【问题标题】:IValidationAttributeAdapterProvider do not work in asp .net core web api 3.1IValidationAttributeAdapterProvider 在 asp .net core web api 3.1 中不起作用
【发布时间】:2020-10-30 21:33:39
【问题描述】:

我正在使用 dotnet core 3.1.403,并正在开发一个 api。

在这里,似乎正在工作: ASP.NET Core custom validation attribute localization

https://blogs.msdn.microsoft.com/mvpawardprogram/2017/01/03/asp-net-core-mvc/

https://github.com/aspnet/Mvc/issues/5282

我的适配器提供者

public class CustomValidatiomAttributeAdapterProvider : IValidationAttributeAdapterProvider
{
    private readonly IValidationAttributeAdapterProvider _baseProvider = 
        new ValidationAttributeAdapterProvider();
    public IAttributeAdapter GetAttributeAdapter(ValidationAttribute attribute, 
        IStringLocalizer stringLocalizer)
    {
        if (attribute is DateTimeAttribute dateTimeAttribute) {
            return new DateTimeAttributeAdapter(dateTimeAttribute, stringLocalizer);
        }
        else
        {
            return _baseProvider.GetAttributeAdapter(attribute, stringLocalizer);
        }
    }
}

我的适配器

public class DateTimeAttributeAdapter : AttributeAdapterBase<DateTimeAttribute>
{
    public DateTimeAttributeAdapter(DateTimeAttribute attribute, IStringLocalizer 
    stringLocalizer) : base(attribute, stringLocalizer)
    {
    }

    public override void AddValidation(ClientModelValidationContext context) 
    {
    }

    public override string GetErrorMessage(ModelValidationContextBase validationContext)
    {
        var metadata = validationContext.ModelMetadata;
        return GetErrorMessage(metadata, metadata.GetDisplayName());
    }
}

我的属性

public class DateTimeAttribute : ValidationAttribute
{
    public DateTimeAttribute() : base(() => "{0} é uma data inválida")
    {
    }

    protected override ValidationResult IsValid(object value, ValidationContext 
    validationContext)
    {
        DateTime dateTime;
        bool success = DateTime.TryParseExact(
                    (value as string).Trim(),
                    new string[] {
                        "yyyy'-'MM'-'dd' 'HH':'mm':'ss",
                        "yyyy'-'MM'-'dd'T'HH':'mm':'ss",
                        "yyyy'-'MM'-'dd",
                    },
                    DateTimeFormatInfo.InvariantInfo,
                    DateTimeStyles.RoundtripKind,
                    out dateTime
                );

        if (!success)
        {
            return new ValidationResult(FormatErrorMessage(validationContext.DisplayName));
        }

        return ValidationResult.Success;
    }
}  

这是我的 Startup.cs

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddLocalization(opt => {
            opt.ResourcesPath = "Resources";
        });

        services.AddControllers()
            .AddDataAnnotationsLocalization(opt => {
                opt.DataAnnotationLocalizerProvider = (type, factory) => factory.Create(typeof(SharedResources));
            });

        
            
        services.AddSingleton<IValidationAttributeAdapterProvider, CustomValidatiomAttributeAdapterProvider>();
    }

但是,永远不会调用 GetAttributeAdapter 方法。 这里有什么问题?

更新

通过不调用 ValidationAttribute 上的基本构造函数来解决问题。见Brando Zhang Answer

代替:

    public DateTimeAttribute() : base(() => "{0} é uma data 
        inválida")
    {
    }

我愿意:

public DateTimeAttribute() : base()
{
    ErrorMessage = "{0} is an invalid";
}

【问题讨论】:

  • 你能分享一下你如何使用`DateTimeAttribute`和SharedResources的代码吗?我在我这边创建了一个测试演示,它运行良好。 CustomValidatiomAttributeAdapterProvider 已触发。 Image.
  • 感谢您的回复。我会将我的完整代码上传到 github 并分享链接。你也可以做你的工作代码吗?
  • 我不建议您分享您的生产项目,您可以创建一个可以重现此问题的简单项目。注意:请不要在您的共享项目中包含任何个人信息。
  • @BrandoZhang 这是我的代码:github.com/ArthDevRepo/validationattributeadapterprovider,正如你所建议的,它不是生产代码

标签: .net asp.net-core .net-core


【解决方案1】:

根据您的描述和代码,我发现您使用base(() =&gt; "{0} é uma data inválida") 来使用父验证提供程序。

这就是不调用您的 CustomValidatiomAttributeAdapterProvider 的原因。

我建议您可以尝试修改 RegisterPersonDto 类的 BirthDate 属性,如下所示:

public class RegisterPersonDto
{
    [Display(Name = "Name")]
    [Required]
    public string Name { get; set; }

    [Display(Name = "Date of Birth")]
    [DateTime([DateTime(ErrorMessage ="tested")])]
    public string BirthDate { get; set; }
} 

【讨论】:

    猜你喜欢
    • 2020-07-25
    • 2021-10-02
    • 2021-10-22
    • 2021-04-24
    • 2020-05-14
    • 1970-01-01
    • 1970-01-01
    • 2020-04-03
    • 2021-03-26
    相关资源
    最近更新 更多