首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何为验证属性提供本地化验证消息

如何为验证属性提供本地化验证消息
EN

Stack Overflow用户
提问于 2016-11-24 21:48:00
回答 3查看 11.4K关注 0票数 9

我正在开发一个ASP.NET Core应用程序,我想覆盖数据注释的默认验证错误消息,如RequiredMinLengthMaxLength等。我在上阅读了文档,但似乎没有涵盖我正在寻找的内容……

例如,Required属性的验证错误消息对于任何模型属性都可以是相同的。默认文本只说明:{0}字段是必需的,因此{0}占位符将用属性的显示名称填充。

在我的视图模型中,我使用不带任何命名参数的Required属性,如下所示...

代码语言:javascript
复制
class ViewModel
{
    [Required, MinLength(10)]
    public string RequiredProperty { get; set; }
}

在我看来,设置ErrorMessageErrorMessageResourceName (和ErrorMessageResourceType)是不必要的开销。我想我可以实现类似于IDisplayMetadataProvider的东西,允许我返回所应用属性的错误消息,以防验证失败。这个是可能的吗?

EN

回答 3

Stack Overflow用户

发布于 2016-11-25 20:30:00

如果要更改完整文本,应使用资源文件对其进行本地化。

每个ValidationAttribute都有ErrorMessageResourceTypeErrorMessageResourceName的属性(请参阅源here)。

代码语言:javascript
复制
[Required(ErrorMessageResourceName = "BoxLengthRequired", ErrorMessageResourceType = typeof(SharedResource))]

更新

好吧,似乎有一种方法可以使用本地化提供程序来本地化它,但它仍然有点老套,并且至少需要在属性上有一个属性(来自this blog post - Word of warning,它最初是针对旧的RC1或RC2版本的。它应该可以工作,但文章中一些API可能无法工作):

在启动时:

代码语言:javascript
复制
services.AddMvc()
   .AddViewLocalization()
   .AddDataAnnotationsLocalization();

在您的模型上:

代码语言:javascript
复制
[Required(ErrorMessage = "ViewModelPropertyRequired"), MinLength(10, ErrorMessage = "ViewModelMinLength")]
public string RequiredProperty { get; set; }

并实现/使用使用DB的本地化提供程序(即https://github.com/damienbod/AspNet5Localization)。

票数 3
EN

Stack Overflow用户

发布于 2017-10-27 04:41:52

我遇到了同样的问题,我使用的解决方案是创建验证属性的子类来提供本地化的错误消息。

为了防止程序员意外地使用非本地化版本,我只是省略了非本地化库的using语句。

票数 0
EN

Stack Overflow用户

发布于 2020-10-10 07:08:47

所以,我来到这里是因为创建了我自己的自定义IStringLocalizer,并想分享我的解决方案,因为@jlchavez帮助了我。

我创建了一个MongoDB IStringLocalizer,并希望通过DataAnnotations使用资源。问题是DataAnnotations属性期望通过暴露资源的静态类进行本地化。

jlchavez's answer相比的一个增强是,这将修复所有ValidationAttribute的资源消息

代码语言:javascript
复制
services.AddTransient<IValidationMetadataProvider, Models.LocalizedValidationMetadataProvider>();
services.AddOptions<MvcOptions>()
    .Configure<IValidationMetadataProvider>((options, provider) =>
    {
        options.ModelMetadataDetailsProviders.Add(provider);
    });


public class Resource
{
    public string Id => Culture + "." + Name;
    public string Culture { get; set; }
    public string Name { get; set; }
    public string Text { get; set; }
}

public class MongoLocalizerFactory : IStringLocalizerFactory
{
    private readonly IMongoCollection<Resource> _resources;

    public MongoLocalizerFactory(IMongoCollection<Resource> resources)
    {
        _resources = resources;
    }

    public IStringLocalizer Create(Type resourceSource)
    {
        return new MongoLocalizer(_resources);
    }

    public IStringLocalizer Create(string baseName, string location)
    {
        return new MongoLocalizer(_resources);
    }
}

public class MongoLocalizer : IStringLocalizer
{
    private readonly IMongoCollection<Resource> _resources;

    public MongoLocalizer(IMongoCollection<Resource> resources)
    {
        _resources = resources;
    }

    public LocalizedString this[string name]
    {
        get
        {
            var value = GetString(name);
            return new LocalizedString(name, value ?? name, resourceNotFound: value == null);
        }
    }

    public LocalizedString this[string name, params object[] arguments]
    {
        get
        {
            var format = GetString(name);
            var value = string.Format(format ?? name, arguments);
            return new LocalizedString(name, value, resourceNotFound: format == null);
        }
    }

    public IStringLocalizer WithCulture(CultureInfo culture)
    {
        CultureInfo.DefaultThreadCurrentCulture = culture;

        return new MongoLocalizer(_resources);
    }

    public IEnumerable<LocalizedString> GetAllStrings(bool includeAncestorCultures)
    {
        var resources = _resources.Find(r => r.Culture == CultureInfo.CurrentCulture.Parent.Name).ToList();
        return resources.Select(r => new LocalizedString(r.Name, r.Text, false));
    }

    private string GetString(string name)
    {
        var resource = _resources.Find(r => r.Culture == CultureInfo.CurrentCulture.Parent.Name && r.Name == name).SingleOrDefault();
        if (resource != null)
        {
            return new LocalizedString(resource.Name, resource.Text, false);
        }
        return new LocalizedString(name, name, true);
    }
}

public class LocalizedValidationMetadataProvider : IValidationMetadataProvider
{
    private IStringLocalizer _localizer;

    public LocalizedValidationMetadataProvider(IStringLocalizer localizer)
    {
        _localizer = localizer;
    }

    public void CreateValidationMetadata(ValidationMetadataProviderContext context)
    {
        foreach(var metadata in context.ValidationMetadata.ValidatorMetadata)
        {
            if (metadata is ValidationAttribute attribute)
            {
                attribute.ErrorMessage = _localizer[attribute.ErrorMessage].Value;
            }
        }
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40788092

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档