首页 > 解决方案 > 将 ValidationMetadataProviderContext 与 Validator 对象一起使用

问题描述

我的 ASP.NET Core 3.1 应用程序中有两种验证机制:

  1. services.AddControllersWithViews我添加一个自定义IValidationMetadataProvideroptions.ModelMetadataDetailsProviders. 它将我的模型类中定义ErrorMessage的默认ValidationAttributes 更改为可以本地化的东西。对于通过 MVC 模型绑定验证的所有模型都会发生这种情况。结果在通常的位置ModelState

    这是一些代码:

    // In Startup.ConfigureServices:
    services.AddControllersWithViews(options =>
    {
        options.ModelMetadataDetailsProviders.Add(new LocalizedValidationMetadataProvider());
    });
    
    internal class LocalizedValidationMetadataProvider : IValidationMetadataProvider
    {
        public void CreateValidationMetadata(ValidationMetadataProviderContext context)
        {
            foreach (object attribute in context.ValidationMetadata.ValidatorMetadata)
            {
                if (attribute is ValidationAttribute valAttr)
                {
                    if (valAttr is RequiredAttribute reqAttr)
                        reqAttr.ErrorMessage = "@input_required";
                    if (valAttr is MaxLengthAttribute maxLenAttr)
                        maxLenAttr.ErrorMessage = $"@max_length {maxLenAttr.Length}";
                }
            }
        }
    }
    
  2. 当从其他来源读取和验证数据(例如从 JSON 文件导入)时,我使用Validator对象ValidationAttribute通过其标准和其他机制 ( )来验证模型IValidatableObject。结果在ValidationResults 的本地列表中。

    这是我到目前为止所做的:

    var vc = new ValidationContext(importedModel);
    var results = new List<ValidationResult>();
    bool isValid = Validator.TryValidateObject(importedModel, vc, results, true);
    if (!isValid)
    {
        // Here I need results with the localisable messages like "@input_required"
        // Instead, I get the default "The (Name) field is required."
    }
    

现在的问题是,在第二种情况下,ValidationAttribute生成了 s 的默认消息,而在ValidationResults 中我没有参考这些消息的来源。我需要以某种方式将第一种情况整合到第二种情况中。

IValidationMetadataProvider实现适用于在ValidationMetadataProviderContext实例中找到的验证元数据。我试图追踪它的来源以及 MVC 模型绑定如何使用它,但我有点迷失在带有所有接口的aspnetcore 源代码中。

我如何将ValidationContextof与MVCValidator结合在一起?ValidationMetadataProviderContext

编辑:进一步阅读了相关的源代码后,我的印象是不可能Validator像这样使用。ModelState或者,对于不是来自 Web 表单请求而是来自另一个任意来源的对象,我如何使用 MVC 的相关机制?我可以告诉 MVC 的一个类来处理一个对象,就好像它来自请求并通过模型绑定一样?

标签: c#validationasp.net-core-mvc

解决方案


也许你有反序列化的问题?

尝试添加 AddNewtonsoftJson:

services.AddControllers().AddNewtonsoftJson();
services.AddControllersWithViews().AddNewtonsoftJson();
services.AddRazorPages().AddNewtonsoftJson();

推荐阅读