RadzenDataAnnotationValidator - IServiceProvider support

Hi, I need to create custom validation on property to check if given value is unique and can be saved to database.

I have a model with data annotation validators:

public class InputModel {  
  public long Id { get; set;  }  

  [Display(ResourceType = typeof(Display), Name = nameof(Display.Code))]
  [UniqueCode(ErrorMessageResourceType = typeof(Validations), ErrorMessageResourceName = nameof(Validations.UniqueCode))]
  public string Code { get; set; }
}

Then I use RadzenDataAnnotaionValidator in RadzenTemplateForm

<RadzenTemplateForm @ref="templateForm" Data="Input" Submit="@(async (InputModel model) => await OnFormSubmit(model))">

  <RadzenStack Orientation="Orientation.Vertical" Gap="0">
    <RadzenLabel Component="@nameof(Input.Code)" Text="@LocDisplay["Code"]"/>
    <RadzenTextBox Name="@nameof(Input.Code)" @bind-Value="Input.Code" Disabled="IsBusy"/>
    <RadzenDataAnnotationValidator Component="@nameof(Input.Code)"/>
  </RadzenStack>

</RadzenTemplateForm>

Here is custom validator

public class UniqueCodeAttribute : ValidationAttribute
{
    protected override ValidationResult? IsValid(object? value, ValidationContext validationContext)
    {
        if (value is string code && validationContext.ObjectInstance is InputModel inputModel)
        {
            var factory = validationContext.GetService(typeof(IMyDbConnectionFactory)) ?? throw new InvalidOperationException("IMyDbConnectionFactory was not registered.");

            using var connection = factory.CreateAsync()
                .GetAwaiter()
                .GetResult();

            var codeExists = connection.MyTable
                .Where(x => x.Id != inputModel.Id)
                .Any(x => x.Code == code);

            if (codeExists) return new ValidationResult(GetErrorMessage(validationContext));
        }

        return ValidationResult.Success;
    }

    public override bool RequiresValidationContext => true;

    private string GetErrorMessage(ValidationContext validationContext)
        => !string.IsNullOrWhiteSpace(ErrorMessage)
            ? ErrorMessage
            : !string.IsNullOrWhiteSpace(ErrorMessageResourceName)
                ? ErrorMessageString
                : $"{validationContext.DisplayName} must be unique.";

}

When the validation method is invoked I’m not able to retrieve service from ValidationContext even it is registered as singleton. If I open the instance validationContext in debugger I can see, that there is private field IServiceProvider _serviceProvider that contains null value.

Hi @spud,

Indeed the ValidationContext is currently not initialized with a service provider. You can submit a pull request which uses the ValidatonContext constructor that accepts a valid service provider (which can be injected as a property of RadzenDataAnnotationValidator)

Hi @korchev

thanks for your advice I’ve prepared pull request Inject ServiceProvider to RadzenDataAnnotationValidator to use it wit… by spudcz · Pull Request #2339 · radzenhq/radzen-blazor · GitHub