ASP.NET Core Blazor 기초 입문 가이드

Blazor 소개

Blazor는 HTML, CSS, C#을 기반으로 웹 애플리케이션을 구축할 수 있는 프론트엔드 프레임워크입니다. 클라이언트와 서버 양쪽에서 동작하는 재사용 가능한 컴포넌트를 사용해 반응형 웹 경험을 제공할 수 있습니다.

프로젝트 구성 요소

  • wwwroot: 정적 자산(이미지, CSS, JS 등)을 저장하는 디렉터리입니다.
  • Components: 공통 Razor 컴포넌트를 포함하며, 레이아웃과 페이지 외부의 재사용 가능한 UI 요소를 위치시킵니다.
  • Layout: 레이아웃 파일 및 스타일 시트를 관리합니다.
  • Pages: 라우팅 가능한 페이지 컴포넌트가 위치합니다. 각 페이지는 @page 지시어로 경로를 설정합니다.
  • _Imports.razor: 자주 사용하는 네임스페이스를 전역으로 포함합니다. 예: @using System.Net.Http.
  • App.razor: 앱의 최상위 컴포넌트로, 라우팅 및 스크립트 로딩을 담당합니다.
  • Routes.razor: Router 컴포넌트를 통해 요청된 URL에 맞는 페이지를 매핑합니다.
  • Program.cs: 앱 시작점으로, 서비스 등록, 미들웨어 구성, 호스팅 설정 등을 수행합니다.
주의: 모든 Razor 컴포넌트 파일은 반드시 대문자로 시작해야 하며, 그렇지 않으면 인식되지 않습니다.

렌더링 모드 종류

각 컴포넌트는 렌더링 방식을 결정하는 렌더링 모드(Render Mode)를 가집니다. 이는 해당 컴포넌트가 어디서 실행되며 상호작용이 가능한지를 정의합니다.

모드 설명 렌더링 위치 인터랙티브 여부
정적 서버 (Static Server) 서버에서 HTML 생성 후 전송. 이후 상호작용 불가 서버 아니요
인터랙티브 서버 (Interactive Server) Blazor Server 기반 실시간 상호작용 지원 서버
인터랙티브 WebAssembly 클라이언트에서 .NET 런타임 실행 (CSR) 클라이언트
자동 인터랙티브 (Interactive Auto) 초기 요청은 서버, 이후 자동으로 WebAssembly 전환 서버 → 클라이언트

인터랙티브 모드 활성화

인터랙티브 기능을 사용하려면 Program.cs에서 적절한 서비스를 등록해야 합니다.

// Program.cs
var builder = WebApplication.CreateBuilder(args);

// 인터랙티브 서버 및 WebAssembly 지원 추가
builder.Services.AddRazorComponents()
    .AddInteractiveServerComponents()
    .AddInteractiveWebAssemblyComponents();

var app = builder.Build();

app.MapRazorComponents<App>()
    .AddInteractiveServerRenderMode()
    .AddInteractiveWebAssemblyRenderMode();

컴포넌트 내에서 렌더링 모드 지정

특정 페이지나 컴포넌트에 대해 렌더링 모드를 명시적으로 설정할 수 있습니다.

@page "/dashboard"
@rendermode InteractiveServer

또는 앱 전체에 적용하고 싶다면 App.razor에서 루트 컴포넌트에 모드를 부여합니다.

<Routes @rendermode="InteractiveServer" />
<HeadOutlet @rendermode="InteractiveServer" />

기본 컴포넌트 작성법

Blazor 컴포넌트는 .razor 확장자를 가지며 HTML 마크업과 C# 코드를 결합합니다.

<!-- Counter.razor -->
<h1>카운터</h1>
<p>현재 값: @count</p>
<button class="btn btn-primary" @onclick="Increment">증가</button>

@code {
    private int count = 0;

    private void Increment() => count++;
}

1. 데이터 바인딩

@bind를 사용하면 양방향 데이터 바인딩이 가능합니다. 입력 필드 변경 시 변수도 자동 갱신됩니다.

<input @bind="name" placeholder="이름 입력" />
<p>입력된 이름: @name</p>

@code {
    private string name = string.Empty;
}

@bind:event를 사용하면 특정 이벤트에 따라 동기화 시점을 조정할 수 있습니다.

<input @bind="inputText" @bind:event="oninput" />
<p>실시간 입력: @inputText</p>

2. 날짜 형식 지정

@bind:format을 이용해 DateTime 값을 원하는 형식으로 표시할 수 있습니다.

<input type="date" @bind="selectedDate" @bind:format="yyyy-MM-dd" />

@code {
    private DateTime selectedDate = DateTime.Today;
}

3. 속성 확장(Splatting)

딕셔너리를 사용해 여러 속성을 한 번에 바인딩할 수 있습니다.

<input @attributes="InputAttrs" />

@code {
    private Dictionary<string, object> InputAttrs = new()
    {
        { "maxlength", 20 },
        { "placeholder", "입력하세요" },
        { "required", true },
        { "size", 40 }
    };
}

4. 객체 바인딩

복잡한 객체의 프로퍼티에도 바인딩이 가능합니다.

@page "/student"
@rendermode InteractiveServer

<label>
    이름:
    <input @bind="Student.Name" />
</label>
<p>학생 이름: @Student.Name</p>

@code {
    public StudentModel Student { get; set; } = new() { Name = "김철수" };

    public class StudentModel
    {
        public string? Name { get; set; }
    }
}

이벤트 처리 및 컴포넌트 통신

부모-자식 컴포넌트 간 데이터 전달은 [Parameter] 속성과 EventCallback을 활용합니다.

<!-- ChildComponent.razor -->
<div class="card">
    <h4>자식 컴포넌트</h4>
    <p>년도: @Year</p>
    <button @onclick="ChangeYear">년도 변경</button>
</div>

@code {
    [Parameter]
    public int Year { get; set; }

    [Parameter]
    public EventCallback<int> YearChanged { get; set; }

    private async Task ChangeYear()
    {
        var newYear = Random.Shared.Next(1980, 2025);
        await YearChanged.InvokeAsync(newYear);
    }
}
<!-- ParentComponent.razor -->
@page "/parent"
@rendermode InteractiveServer

<h3>부모 컴포넌트</h3>
<p>현재 년도: @currentYear</p>
<button @onclick="UpdateYear">직접 업데이트</button>

<ChildComponent @bind-Year="currentYear" />

@code {
    private int currentYear = 2020;

    private void UpdateYear() => currentYear = Random.Shared.Next(1980, 2025);
}

라우팅 및 네비게이션

1. 기본 라우팅

@page 지시어로 경로를 정의합니다. 라우터는 어셈블리 스캔을 통해 경로 정보를 수집합니다.

@page "/profile/{userId:int}"

2. 라우트 파라미터

URL 세그먼트 값을 컴포넌트에 전달할 수 있습니다. 대소문자 구분 없음.

@page "/greeting/{message}"

<p>메시지: @Message</p>

@code {
    [Parameter]
    public string? Message { get; set; }
}

3. 라우트 제약 조건

타입 안전성을 보장하기 위해 제약 조건을 설정할 수 있습니다.

@page "/user/{id:int}/{active:bool?}"

<p>사용자 ID: @Id</p>
<p>활성 상태: @Active</p>

@code {
    [Parameter]
    public int Id { get; set; }

    [Parameter]
    public bool Active { get; set; } = true;
}

4. NavigationManager 사용

C# 코드 내에서 프로그래밍 방식으로 페이지 이동이 가능합니다.

@inject NavigationManager NavManager

<button @onclick="GoToCounter">카운터로 이동</button>

@code {
    private void GoToCounter() => NavManager.NavigateTo("/counter");
}

5. NavLink 컴포넌트

내비게이션 링크는 일반 <a> 태그보다 NavLink를 사용하는 것이 좋습니다. 현재 경로와 일치할 경우 자동으로 활성 클래스를 추가합니다.

<NavLink href="/home" Match="NavLinkMatch.All">홈</NavLink>
<NavLink href="/products" Match="NavLinkMatch.Prefix">제품</NavLink>
  • NavLinkMatch.All: 정확한 전체 URL 일치 시 활성화
  • NavLinkMatch.Prefix: URL 접두사 일치 시 활성화 (기본값)

폼 검증 (Validation)

Blazor는 Data Annotations 기반 검증을 지원합니다. EditForm, DataAnnotationsValidator, ValidationSummary 등을 조합해 사용합니다.

@page "/register"
@using System.ComponentModel.DataAnnotations
@inject ILogger<RegistrationForm> Logger

<EditForm Model="User" OnValidSubmit="HandleValidSubmit">
    <DataAnnotationsValidator />
    <ValidationSummary />

    <label>
        사용자명:
        <InputText @bind-Value="User.Username" />
        <ValidationMessage For="() => User.Username" />
    </label>

    <button type="submit">제출</button>
</EditForm>

@code {
    public UserModel User { get; set; } = new();

    private void HandleValidSubmit()
    {
        Logger.LogInformation("유효한 폼 제출: {Username}", User.Username);
    }

    public class UserModel
    {
        [Required(ErrorMessage = "사용자명은 필수입니다.")]
        [StringLength(10, MinimumLength = 3, ErrorMessage = "3~10자 사이로 입력하세요.")]
        public string? Username { get; set; }
    }
}
  • EditForm: 폼 컨텍스트를 제공하고 제출 이벤트를 처리합니다.
  • DataAnnotationsValidator: 모델의 특성 기반 유효성 검사를 연결합니다.
  • ValidationSummary: 전체 오류 메시지를 목록으로 표시합니다.
  • ValidationMessage: 특정 필드의 오류만 표시합니다.

폼 제출 콜백은 다음과 같이 세 가지로 나뉩니다:

  • OnValidSubmit: 유효할 때 실행
  • OnInvalidSubmit: 무효일 때 실행
  • OnSubmit: 항상 실행 (내부에서 수동 검증 필요)

태그: Blazor ASP.NET Core Razor Components WebAssembly Server-Side Rendering

7월 11일 03:55에 게시됨