I am trying to validate two fields in a class that must total less than a third value. If Property1 + Property2 is greater than X then show an error.
I've created a custom attribute that will throw the error on the changed field if the total is greater than X. If you then reduce the value on this same field the validation error will be removed. However if you reduce the total by reducing the value in the other field than the validation error will still be shown.
Ideally, I'd be able to force Validation on Property1 to be refreshed if I update Property2 and vice-versa. However as far as I can tell, it will only do this is the value is changed from the original value at the close of the set block.
I'm using C# with a Blazor Server App and I've been doing the validation within the classes as opposed to resorting to JavaScript or TypeScript.
I've created a simple example below to replicate the issue. When the two boxes combined total more than ten a validation error is shown against the box which pushes it over 10.
At page load:
Changed the first value to 8, raising the total to 12:
Now reduced the second value to 1, reducing the total to 9:
If rather than reduce the second box to 1, I were to change it to 3, the total would still be over 10 and that box would also show its validation summary. Then if I changed either box to a 1, the validation error would disappear only for that one box.
Could anyone please give guidance on how to resolve this? Ideally I'd like a way of forcing the validation to fire on the both boxes if either were changed. It may be a case that being new to Blazor, I'm approaching this at an entirely wrong angle.
using Sample.ValidationAttributes;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
namespace Sample.ViewModels
{
public class SampleClass
{
[Required]
[DisplayName("Sample A")]
[LessThan10(ErrorMessage = "Sample A + Sample B Must be less than 10")]
public int SampleIntA { get; set; }
[Required]
[DisplayName("Sample B")]
[LessThan10(ErrorMessage = "Sample A + Sample B Must be less than 10")]
public int SampleIntB { get; set; }
}
}
namespace Sample.ValidationAttributes
{
using Sample.ViewModels;
using System.ComponentModel.DataAnnotations;
public class LessThan10Attribute : ValidationAttribute
{
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
if (((SampleClass)validationContext.ObjectInstance).SampleIntA + ((SampleClass)validationContext.ObjectInstance).SampleIntB > 10)
{
return new ValidationResult(ErrorMessage);
}
return ValidationResult.Success;
}
}
}
using Sample.ViewModels;
namespace Sample.Data
{
public class SampleService
{
public SampleClass GetSampleClass()
{
return new SampleClass()
{
SampleIntA = 3,
SampleIntB = 4
};
}
}
}
@page "/SamplePage"
@using Sample.Data;
@using Sample.ViewModels;
@inject SampleService sampleService
<h3>SamplePage</h3>
<EditForm Model="@sampleClass" >
<DataAnnotationsValidator />
<ValidationSummary />
<InputNumber id="SampleIntA" @bind-Value="sampleClass.SampleIntA" class="form-control" autocomplete="off" />
<ValidationMessage For="() => sampleClass.SampleIntA" class="help-block text-danger" />
<InputNumber id="SampleIntB" @bind-Value="sampleClass.SampleIntB" class="form-control" autocomplete="off" />
<ValidationMessage For="() => sampleClass.SampleIntB" class="help-block text-danger" />
</EditForm>
@code {
private SampleClass sampleClass;
protected override async Task OnInitializedAsync()
{
sampleClass = sampleService.GetSampleClass();
}
}