Blazor Server 아이디어 관리자 앱 만들기

  • 7 minutes to read

소개

Blazor Server로 입출력 기능이 있는 아이디어 관리자 앱 만들기

이 강좌에서는 Blazor Server를 사용하여 사용자 인증 기능과 간단한 CRUD(생성, 조회) 기능을 포함한 아이디어 관리자 앱을 만드는 방법을 단계별로 안내합니다. Blazor Server의 핵심 기능을 활용하며, .NET 9.0 이상의 최신 기능을 반영한 구현을 제공합니다.


1. 프로젝트 생성 및 초기 설정

1.1 프로젝트 생성

Visual Studio에서 Blazor Server 앱 생성하기

  1. Visual Studio를 실행하고, 파일새로 만들기프로젝트를 선택합니다.
  2. 프로젝트 만들기 창에서 검색창에 Blazor Web App을 입력하고, Blazor Web App 템플릿을 선택합니다.
  3. 다음을 클릭하고, 프로젝트 이름을 IdeaAppCore로 설정합니다.
    • 위치: 원하는 디렉터리 지정 (예: D:\IdeaAppCore).
    • 솔루션 이름: 기본값 유지.
  4. 다음을 클릭하여 프로젝트 설정 화면으로 이동합니다.
  5. 프로젝트 설정:
    • .NET 프레임워크: .NET 9.0 선택.
    • Blazor Hosting Type: Blazor Server App 선택.
    • Authentication Type: Individual Accounts 선택하여 인증 기능 포함.
  6. 만들기를 클릭하여 프로젝트를 생성합니다.

생성된 프로젝트 구조

  • Solution 파일: D:\IdeaAppCore\IdeaAppCore.sln
  • 프로젝트 파일: D:\IdeaAppCore\IdeaAppCore\IdeaAppCore.csproj

CLI에서 Blazor Server 앱 생성하기

Blazor Server 템플릿을 사용해 명령줄에서 프로젝트를 생성하려면 아래 명령어를 사용합니다.

dotnet new blazorserver -n IdeaAppCore --auth Individual
  • 옵션 설명:
    • --auth Individual: 사용자 인증을 활성화합니다.
    • -n IdeaAppCore: 프로젝트 이름 설정.

Visual Studio를 사용하면 GUI를 통해 직관적으로 생성 가능하며, CLI는 간단하고 빠른 설정에 적합합니다. 두 방법 중 편리한 방법을 선택하세요.

1.2 .NET 9.0 타겟 설정

IdeaAppCore.csproj 파일을 열어 .NET 9.0으로 타겟 프레임워크를 설정합니다.

<Project Sdk="Microsoft.NET.Sdk.Web">
  <PropertyGroup>
    <TargetFramework>net9.0</TargetFramework>
    <UserSecretsId>aspnet-IdeaAppCore-077B4CCF-5349-4A52-8B04-0E59EB960ECB</UserSecretsId>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore" Version="9.0.1" />
    <PackageReference Include="Microsoft.AspNetCore.Identity.EntityFrameworkCore" Version="9.0.1" />
    <PackageReference Include="Microsoft.AspNetCore.Identity.UI" Version="9.0.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="9.0.1" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="9.0.1" PrivateAssets="all" />
  </ItemGroup>
</Project>

2. 데이터베이스 및 모델 설정

2.1 데이터베이스 연결 설정

appsettings.json 파일에 데이터베이스 연결 문자열을 추가합니다.

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\mssqllocaldb;Database=IdeaAppCore;Trusted_Connection=True;"
  },
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  },
  "AllowedHosts": "*"
}

2.2 데이터베이스 컨텍스트 생성

Data 폴더에 ApplicationDbContext.cs 파일을 생성합니다.

using IdeaAppCore.Models;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;

namespace IdeaAppCore.Data
{
    public class ApplicationDbContext : IdentityDbContext
    {
        public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options)
            : base(options) { }

        public DbSet<Idea> Ideas { get; set; }
    }
}

2.3 모델 클래스 생성

Models 폴더에 Idea.cs 파일을 생성합니다.

using System.ComponentModel.DataAnnotations;

namespace IdeaAppCore.Models
{
    public class Idea
    {
        public int Id { get; set; }

        [Required]
        public string Note { get; set; }
    }
}

3. 데이터 저장소 구현

3.1 저장소 인터페이스 생성

Models 폴더에 IIdeaRepository.cs 파일을 생성합니다.

using System.Collections.Generic;
using System.Threading.Tasks;

namespace IdeaAppCore.Models
{
    public interface IIdeaRepository
    {
        Task<Idea> AddIdea(Idea idea);
        Task<List<Idea>> GetIdeas();
    }
}

3.2 저장소 클래스 생성

Models 폴더에 IdeaRepository.cs 파일을 생성합니다.

using IdeaAppCore.Data;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace IdeaAppCore.Models
{
    public class IdeaRepository : IIdeaRepository
    {
        private readonly ApplicationDbContext _context;

        public IdeaRepository(ApplicationDbContext context)
        {
            _context = context;
        }

        public async Task<Idea> AddIdea(Idea idea)
        {
            _context.Ideas.Add(idea);
            await _context.SaveChangesAsync();
            return idea;
        }

        public async Task<List<Idea>> GetIdeas()
        {
            return await _context.Ideas.ToListAsync();
        }
    }
}

4. 데이터베이스 마이그레이션

4.1 마이그레이션 및 데이터베이스 업데이트

패키지 관리자 콘솔(PMC)에서 다음 명령어를 실행합니다.

Add-Migration "Ideas Table Add"
Update-Database

5. Blazor Server 구성

5.1 서비스 등록

Program.cs 파일에서 IIdeaRepository를 DI 컨테이너에 등록합니다.

builder.Services.AddTransient<IIdeaRepository, IdeaRepository>();

6. 사용자 인터페이스 구현

6.1 아이디어 목록 페이지

Pages 폴더에 Ideas.razor 파일을 생성하고 CRUD UI를 추가합니다.

@page "/Ideas"
@inject IIdeaRepository repository

<h3>Ideas</h3>

@if (ideas == null)
{
    <p><em>Loading...</em></p>
}
else if (ideas.Count == 0)
{
    <p><em>No Data...</em></p>
}
else
{
    <table class="table">
        <thead>
            <tr>
                <th>ID</th>
                <th>Note</th>
            </tr>
        </thead>
        <tbody>
            @foreach (var idea in ideas)
            {
                <tr>
                    <td>@idea.Id</td>
                    <td>@idea.Note</td>
                </tr>
            }
        </tbody>
    </table>
}

<input type="button" value="글쓰기" @onclick="btnCreate_Click" class="btn btn-primary" />

@if (isShow)
{
    <div class="modal fade show" tabindex="-1" role="dialog" style="display:block;" id="myModal">
        <div class="modal-dialog" role="document">
            <div class="modal-content">
                <div class="modal-header">
                    <h5 class="modal-title">어떤 아이디어가 있나요?</h5>
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"
                            @onclick="btnClose_Click">
                        <span aria-hidden="true">&times;</span>
                    </button>
                </div>
                <div class="modal-body">
                    <div class="form-group">
                        <label for="note">아이디어</label>
                        <input type="text" class="form-control" @bind="@idea.Note" />
                    </div>
                    <button type="button" class="btn btn-primary" @onclick="btnSave_Click">Submit</button>
                    <button type="button" class="btn btn-secondary" data-dismiss="modal"
                            @onclick="btnClose_Click">
                        Close
                    </button>
                </div>
            </div>
        </div>
    </div>
}

@code {
    Idea idea = new Idea();
    private bool isShow = false;
    private List<Idea> ideas;

    protected override async Task OnInitializedAsync()
    {
        ideas = await repository.GetIdeas();
    }

    private void btnCreate_Click()
    {
        isShow = true;
    }

    private void btnClose_Click()
    {
        isShow = false;
        idea = new Idea();
    }

    private async Task btnSave_Click()
    {
        await repository.AddIdea(idea);
        isShow = false;
        ideas = await repository.GetIdeas();
        idea = new Idea();
        StateHasChanged();
    }
}

6.2 네비게이션 메뉴 업데이트

Shared 폴더의 NavMenu.razor를 수정합니다.

<NavLink class="nav-link" href="Ideas">
    <span class="oi oi-pencil" aria-hidden="true"></span> Ideas
</NavLink>

7. 실행 및 테스트

  1. 앱을 실행합니다.
dotnet run
  1. 브라우저에서 다음 URL을 확인합니다:
    • 아이디어 목록: http://localhost:5000/Ideas

8. 기능 확장: Bootstrap 4와 5 모달 구분 지원

8.1 설정 추가

appsettings.json 파일에 Bootstrap 버전을 명시합니다.

{
  "Bootstrap": {
    "Version": "4" // 또는 "5"
  }
}

8.2 Program.cs에서 설정 주입

builder.Services.Configure<BootstrapSettings>(builder.Configuration.GetSection("Bootstrap"));

public class BootstrapSettings
{
    public string Version { get; set; }
}

8.3 Bootstrap 모달 처리

Ideas.razor 코드에서 설정 값을 참조하여 Bootstrap 4와 5에 맞는 HTML 구조를 렌더링합니다.

@if (isShow)
{
    @if (BootstrapOptions.Value.Version == "4")
    {
        <div class="modal fade show" tabindex="-1" style="display:block;" id="myModal">
            ...
        </div>
    }
    else if (BootstrapOptions.Value.Version == "5")
    {
        <div class="modal fade show" tabindex="-1" style="display:block;" id="myModal">
            ...
        </div>
    }
}

마무리

이 강좌를 통해 Blazor Server.NET 9.0 기반 CRUD 애플리케이션을 구축하고, Bootstrap 4와 5의 호환성도 지원하는 기능을 학습했습니다.

VisualAcademy Docs의 모든 콘텐츠, 이미지, 동영상의 저작권은 박용준에게 있습니다. 저작권법에 의해 보호를 받는 저작물이므로 무단 전재와 복제를 금합니다. 사이트의 콘텐츠를 복제하여 블로그, 웹사이트 등에 게시할 수 없습니다. 단, 링크와 SNS 공유, Youtube 동영상 공유는 허용합니다. www.VisualAcademy.com
박용준 강사의 모든 동영상 강의는 데브렉에서 독점으로 제공됩니다. www.devlec.com