演習 - サーバー側とクライアント側のデータ検証を住所フォームに追加する

完了

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. これで、住所が有効かどうかをテストするカスタム サーバー側のロジックを削除できるようになりました。 CheckSubmission ブロック内の @code メソッドを削除します。

新しいデータ注釈の検証をテストする

  1. Visual Studio Code で F5 キーを押 すか、実行>デバッグの開始を選択します。

    情報を入力しないで、次に不完全な情報で、ピザを注文してみます。 各フィールドの詳細なエラー メッセージを確認します。

    各フィールドのエラー メッセージのスクリーンショット。

    この操作により、各フィールドのエラー チェックが向上しますが、各フィールドのエラーは、関連するフィールドの横の方が適切です。

  2. Shift + F5 キーを押して、アプリの実行を停止します。

EditFrom エラー メッセージを改善する

  1. エクスプローラーで [ ページ] を展開し、[ Checkout.razor] を選択します。

  2. <ValidationSummary /> Blazor コンポーネントを削除します。

            <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. OnInvalidSubmit コンポーネントに対して ShowError メソッドを呼び出す EditForm パラメーターを追加します。

    <EditForm Model=Order.DeliveryAddress OnValidSubmit=PlaceOrder OnInvalidSubmit=ShowError> 
    
  3. isError プロパティを更新する ShowError メソッドを追加します。

    protected void ShowError()
    {
        isError = true;
    }     
    
  4. PlaceOrder メソッドを変更して isError プロパティと isSubmitting プロパティを更新します。

    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. EditForm 要素を更新します。

    <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 キーを押して、アプリの実行を停止します。