연습 - 주소 양식에 서버 측 및 클라이언트 측 데이터 유효성 검사 추가

완료됨

Blazor는 애플리케이션에서 모델에 양식을 바인딩할 수 있습니다. 이러한 모델을 데이터 주석으로 데코레이트하는 경우 코드를 더 작성하지 않고도 클라이언트 및 서버 측 유효성 검사를 가져올 수 있습니다.

클라이언트가 이름 및 일부 주소 필드를 입력하지 않으면 앱이 올바르게 주문을 제출하지 않습니다. 팀에서는 유효성 검사를 개선하여 더 많은 필드를 포함하려고 합니다. 또한 최소 길이 및 문자 유효성 검사를 사용하려고 합니다.

이 연습에서는 데이터 주석을 사용하도록 현재 서버 쪽 유효성 검사를 대체합니다. 유효성 검사 메시지를 관리하고 기본 제공 유효성 검사 지원을 개선하는 방법을 알아봅니다. 마지막 단계에서는 모든 필드가 유효한 경우에만 양식을 제출하도록 양식이 제출되는 방식을 제어합니다.

Blazor 모델에 데이터 주석 추가

  1. Visual Studio Code의 파일 탐색기에서 모델을 확장한 다음 Address.cs를 선택합니다.

  2. 클래스 맨 위에서 System.ComponentModel.DataAnnotations에 대한 참조를 추가합니다.

    using System.ComponentModel.DataAnnotations;
    
  3. 필요한 각 필드에 데이터 주석을 추가합니다.

    public class Address
    {
        public int Id { get; set; }
    
        [Required, MinLength(3), MaxLength(100)]
        public string Name { get; set; }
    
        [Required, MinLength(5), MaxLength(100)]
        public string Line1 { get; set; }
    
        [MaxLength(100)]
        public string Line2 { get; set; }
    
        [Required, MinLength(3), MaxLength(50)]
        public string City { get; set; }
    
        [Required, MinLength(3), MaxLength(20)]
        public string Region { get; set; }
    
        [Required, RegularExpression(@"^([0-9]{5})$")]
        public string PostalCode { get; set; }
    }
    
  4. 파일 탐색기에서 페이지를 확장한 다음 Checkout.razor를 선택합니다.

  5. 닫는 </EditForm> 태그 위에 유효성 검사 요약과 데이터 주석 유효성 검사기를 추가합니다.

        <ValidationSummary />
        <DataAnnotationsValidator />
      </EditForm>
    </div>
    
  6. EditForm 태그에서 OnSubmit 매개 변수를 바꾸어 유효한 제출을 사용합니다.

      <EditForm Model=Order.DeliveryAddress OnValidSubmit=PlaceOrder>
    
  7. 이제 사용자 지정 서버 쪽 논리를 삭제하여 주소가 유효한지 테스트할 수 있습니다. @code 블록에서 CheckSubmission 메서드를 삭제합니다.

새 데이터 주석 유효성 검사 테스트

  1. Visual Studio Code에서 F5 키를 누르거나 실행>디버깅 시작을 선택합니다.

    아무 정보도 입력하지 않고 피자를 주문해본 다음, 정보를 일부만 입력하고 주문해봅니다. 각 필드에 대한 세부 오류 메시지를 관찰합니다.

    각 필드에 대한 오류 메시지의 스크린샷.

    이 상호 작용은 각 필드에 대한 오류 검사를 개선하지만 각 필드에 대한 오류는 관련된 필드 옆에 있는 편이 훨씬 적합합니다.

  2. Shift + F5 키를 눌러 앱 실행을 중지합니다.

EditFrom 오류 메시지 개선

  1. 파일 탐색기에서 페이지를 확장한 다음 Checkout.razor를 선택합니다.

  2. Blazor <ValidationSummary /> 구성 요소를 삭제합니다.

            <DataAnnotationsValidator />
      </EditForm>
    </div>
    
  3. 파일 탐색기에서 공유를 확장한 다음 AddressEditor.razor를 선택합니다.

  4. 각 필드 아래에 사용자 지정 유효성 검사 메시지를 추가합니다.

    <div class="form-field">
        <label>Name:</label>
        <div>
            <InputText @bind-Value="Address.Name" />
            <ValidationMessage For="@(() => Address.Name)" />
        </div>
    </div>
    
    <div class="form-field">
        <label>Line 1:</label>
        <div>
            <InputText @bind-Value="Address.Line1" />
            <ValidationMessage For="@(() => Address.Line1)" />
        </div>
    </div>
    
    <div class="form-field">
        <label>Line 2:</label>
        <div>
            <InputText @bind-Value="Address.Line2" />
            <ValidationMessage For="@(() => Address.Line2)" />
        </div>
    </div>
    
    <div class="form-field">
        <label>City:</label>
        <div>
            <InputText @bind-Value="Address.City" />
            <ValidationMessage For="@(() => Address.City)" />
        </div>
    </div>
    
    <div class="form-field">
        <label>Region:</label>
        <div>
            <InputText @bind-Value="Address.Region" />
            <ValidationMessage For="@(() => Address.Region)" />
        </div>
    </div>
    
    <div class="form-field">
        <label>Postal code:</label>
        <div>
            <InputText @bind-Value="Address.PostalCode" />
            <ValidationMessage For="@(() => Address.PostalCode)" />
        </div>
    </div>
    
  5. 파일 탐색기에서 모델을 확장한 다음 Address.cs를 선택합니다.

  6. 각 필드의 데이터 주석에 대한 사용자 지정 오류 메시지를 추가합니다.

    public class Address
    {
        public int Id { get; set; }
    
        [Required, MinLength(3, ErrorMessage = "Please use a Name bigger than 3 letters."), MaxLength(100, ErrorMessage = "Please use a Name less than 100 letters.")]
        public string Name { get; set; }
    
        [Required, MinLength(5, ErrorMessage = "Please use an Address bigger than 5 letters."), MaxLength(100, ErrorMessage = "Please use an Address less than 100 letters.")]
        public string Line1 { get; set; }
    
        [MaxLength(100)]
        public string Line2 { get; set; }
    
        [Required, MinLength(3, ErrorMessage = "Please use a City bigger than 3 letters."), MaxLength(50, ErrorMessage = "Please use a City less than 50 letters.")]
        public string City { get; set; }
    
        [Required, MinLength(3, ErrorMessage = "Please use a Region bigger than 3 letters."), MaxLength(20, ErrorMessage = "Please use a Region less than 20 letters.")]
        public string Region { get; set; }
    
        [Required, RegularExpression(@"^([0-9]{5})$", ErrorMessage = "Please use a valid Postal Code with five numbers.")]
        public string PostalCode { get; set; }
    }
    

새 데이터 주석 유효성 검사 테스트

  1. Visual Studio Code에서 F5 키를 누르거나 실행>디버깅 시작을 선택합니다.

    데이터가 잘못된 경우 표시되는 각 필드에 대한 오류 메시지를 보여주는 애니메이션 gif.

    주소 양식은 잘못된 데이터가 입력된 필드 아래에 오류 메시지를 동적으로 표시합니다. 이 상호 작용은 클라이언트 쪽에서 발생하며 고객이 잘못된 주소를 입력하는 것을 방지합니다.

  2. Shift + F5 키를 눌러 앱 실행을 중지합니다.

전체 오류 메시지를 복원하고 제출 단추를 비활성화

  1. 파일 탐색기에서 페이지를 확장한 다음 Checkout.razor를 선택합니다.

  2. EditForm 구성 요소에 ShowError 메서드를 호출할 OnInvalidSubmit 매개 변수를 추가합니다.

    <EditForm Model=Order.DeliveryAddress OnValidSubmit=PlaceOrder OnInvalidSubmit=ShowError> 
    
  3. isError 속성을 업데이트하는 ShowError 메서드를 추가합니다.

    protected void ShowError()
    {
        isError = true;
    }     
    
  4. PlaceOrder 메서드를 변경하여 isErrorisSubmitting 속성을 업데이트합니다.

    async Task PlaceOrder()
    {
        isError = false;
        isSubmitting = true;
        var response = await HttpClient.PostAsJsonAsync(
            $"{NavigationManager.BaseUri}orders", OrderState.Order);
        var newOrderId= await response.Content.ReadFromJsonAsync<int>();
        OrderState.ResetOrder();
        NavigationManager.NavigateTo($"myorders/{newOrderId}");
    } 
    
  5. Visual Studio Code에서 F5 키를 누르거나 실행>디버깅 시작을 선택합니다.

    전체 오류 메시지가 표시된 스크린샷.

    고객이 잘못된 양식을 제출하려고 하면 오류 메시지가 표시됩니다.

  6. Shift + F5 키를 눌러 앱 실행을 중지합니다.

모든 필드가 올바르면 제출 단추를 활성화

고객이 모든 필드를 완성할 때까지 주문을 제출할 수 없는 사용자 환경이 더 나을까요? 이 요구 사항을 지원하도록 체크 아웃 페이지를 변경해 보겠습니다. 모델 대신 EditContext를 사용하도록 EditForm을 변경합니다.

  1. 파일 탐색기에서 페이지를 확장한 다음 Checkout.razor를 선택합니다.

  2. EditFrom 요소를 업데이트합니다.

    <EditForm EditContext=editContext OnValidSubmit=PlaceOrder> 
    
  3. isError 매개 변수를 사용하도록 단추 요소를 변경합니다.

    <button class="checkout-button btn btn-warning" type="Submit" disabled=@isError>
    
  4. @code 블록에서 새 EditContext에 대한 선언을 추가합니다.

    private EditContext editContext;
    
  5. 주문 배달 주소를 사용하여 컨텍스트를 초기화합니다.

    protected override void OnInitialized()
    {
        editContext = new(Order.DeliveryAddress);
        editContext.OnFieldChanged += HandleFieldChanged;
    }    
    

    또한 이 코드를 사용하면 이벤트 처리기를 필드가 변경되는 시점에 연결할 수 있습니다. 새 처리기에서 모델이 유효한지 확인하고 isError를 적절하게 설정할 수 있습니다.

        private void HandleFieldChanged(object sender, FieldChangedEventArgs e)
        {
            isError = !editContext.Validate();
            StateHasChanged();
        }
    
  6. 이제 이벤트 처리기를 만들었으므로 체크 아웃 구성 요소에 더 이상 필요하지 않으면 이를 삭제해야 합니다.

    public void Dispose()
    {
        editContext.OnFieldChanged -= HandleFieldChanged;
    }
    
  7. Dispose 기능을 구현하려면 Blazor에도 알려야 합니다. 다음 코드를 페이지 맨 위의 @inject 문 아래에 추가합니다.

    @implements IDisposable
    
  8. isSubmitting에 대한 참조를 모두 삭제하고 PlaceOrder 메서드를 업데이트합니다.

    async Task PlaceOrder()
    {
      var response = await HttpClient.PostAsJsonAsync(NavigationManager.BaseUri + "orders", OrderState.Order);
      var newOrderId= await response.Content.ReadFromJsonAsync<int>();
      OrderState.ResetOrder();
      NavigationManager.NavigateTo($"myorders/{newOrderId}");
    }    
    
  9. Visual Studio Code에서 F5 키를 누르거나 실행>디버깅 시작을 선택합니다.

    모든 필드에 올바른 값이 입력될 때까지 주문하기 단추가 비활성화됨을 보여주는 애니메이션 gif.

    이제 고객에게 정보를 입력하라는 메시지가 표시되고, 먼저 주문하기 단추가 비활성화됩니다. 모든 필수 필드에 데이터가 입력된 후에만 단추를 클릭할 수 있습니다.

  10. Shift + F5 키를 눌러 앱 실행을 중지합니다.