Blazor get validation message for two properties

Viewed 1838

I have a simple EditForm within a Blazor Server Side application. It has an bound property which changes another property which should also be validated by the form.

The form contains the following section

<div class="form-group col-md-6">
    <label for="inputRechnungsnummer">Rechnungsnummer</label>
    <InputNumber @bind-Value="Input.Rechnungsnummer" id="inputRechnungsnummer" class="form-control" />
    <ValidationMessage For="() => Input.CustomerExists" />
    <ValidationMessage For="() => Input.Rechnungsnummer" />
</div>

As you can see, I want to display two messages under this InputField.

The bond field calls a method to find customer details.

public int Rechnungsnummer 
{ 
    get => _rechnungsnummer; 
    set
    {
        _rechnungsnummer = value;
        SearchKunde();
    }
}

This method changed the value of my attribute

private void SearchKunde()
{

    /* LOGIC */
    
    if(name != null)
    {
        Kundenname = name;
        CustomerExists = true;
    }
    else
    {
        Kundenname = "";
        CustomerExists = false;
    }
}

The second attribute is defined as:

[Required]
[Range(typeof(bool), "true", "true", ErrorMessage = "Bitte geben Sie eine gültige Rechnungsnummer ein")]
public bool CustomerExists { get; set; }

However the validation message for CustomerExists won't be displayed. It is only shown once I try to submit my form.

Does anybody know how I can achive to display the message after it's value has been changed?

1 Answers

I think there are a few problems here.

1: Blazor will not report an error for the property unless you either (A) Edit it in a Blazor input control (make the property "modified"), or (B) call EditContext.Validate which will validate all properties.

2: If your code runs asynchronously then you'd also need to call InvokeAsync(StateHasChanged) at the end.

Alternatively, if you bind your form to an EditContext instead of Model you could do something like this

<EditForm EditContext=@MyEditContext>
  ... your form stuff here...
</EditForm>

@code
{
  EditContext MyEditContext = new EditContext(new Person());

  protected override void OnInitialized()
  {
    base.OnInitialized();
    MyEditContext.OnFieldChanged += FieldChanged;
  }

  private void FieldChanged(object sender, FieldChangedEventArgs args)
  {
    if (args.FieldIdentifier.FieldName == nameof(Person.FirstProperty))
    {
      FieldIdentifider fd = MyEditContext.Field(nameof(Person.OtherProperty));
      MyEditContext.NotifyFieldChanged(fd);
    }
  }
}

If you want to get a property that isn't directly on the object your EditForm is bound to (e.g. Model.Address.PostalCode) you can do this

var fd = new FieldIdentifier(Model.Address, nameof(Address.PostalCode));
MyEditContext.NotifyFieldChanged(fd);
Related