简体   繁体   English

ASP.NET MVC中数据注释的默认资源

[英]Default resource for data annotations in ASP.NET MVC

There's a way to set the default resource to the data annotations validations? 有一种方法可以将默认资源设置为数据注释验证吗?

I don't wanna make something like this: 我不想做这样的事情:

[Required(ErrorMessage="Name required.", ErrorMessageResourceType=typeof(CustomDataAnnotationsResources)]
public string Name { get; set; }

I would like something like this: 我想要这样的东西:

Global.asax Global.asax中

DataAnnotations.DefaultResources = typeof(CustomDataAnnotationsResources);

then 然后

[Required]
public string Name { get; set; }

someone gimme a light! 有人给我一个光!

thanks in advance 提前致谢

EDIT 编辑

My real problem was with EF Code First CTP4. 我真正的问题是使用EF Code First CTP4。 CTP5 fix it. CTP5修复它。 Thanks for everyone. 谢谢大家。

You could try doing this: 你可以尝试这样做:

Add this class somewhere in your project: 在项目的某处添加此类:

 public class ExternalResourceDataAnnotationsValidator : DataAnnotationsModelValidator<ValidationAttribute>
{
    /// <summary>
    /// The type of the resource which holds the error messqages
    /// </summary>
    public static Type ResourceType { get; set; }

    /// <summary>
    /// Function to get the ErrorMessageResourceName from the Attribute
    /// </summary>
    public static Func<ValidationAttribute, string> ResourceNameFunc 
    {
        get { return _resourceNameFunc; }
        set { _resourceNameFunc = value; }
    }
    private static Func<ValidationAttribute, string> _resourceNameFunc = attr => attr.GetType().Name;

    public ExternalResourceDataAnnotationsValidator(ModelMetadata metadata, ControllerContext context, ValidationAttribute attribute)
        : base(metadata, context, attribute)
    {
        if (Attribute.ErrorMessageResourceType == null)
        {
            this.Attribute.ErrorMessageResourceType = ResourceType;
        }

        if (Attribute.ErrorMessageResourceName == null)
        {
            this.Attribute.ErrorMessageResourceName = ResourceNameFunc(this.Attribute);
        }
    }
}

and in your global.asax, add the following: 并在您的global.asax中,添加以下内容:

// Add once
ExternalResourceDataAnnotationsValidator.ResourceType = typeof(CustomDataAnnotationsResources);

// Add one line for every attribute you want their ErrorMessageResourceType replaced.
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof(RangeAttribute), typeof(ExternalResourceDataAnnotationsValidator));

It will look for a property with the same name as the validator type for the error message. 它将查找与错误消息的验证程序类型同名的属性。 You can change that via the ResourceNameFunc property. 您可以通过ResourceNameFunc属性更改它。

EDIT: AFAIK this works from MVC2 onwards, as DataAnnotationsModelValidatorProvider was introduced in MVC2. 编辑:AFAIK从MVC2开始,因为DataAnnotationsModelValidatorProvider是在MVC2中引入的。

To achieve this, I created a new class that inherits from RequiredAttribute, and the error message is embedded inside this new class: 为此,我创建了一个继承自RequiredAttribute的新类,并将错误消息嵌入到这个新类中:

public class RequiredWithMessageAttribute : RequiredAttribute
{
    public RequiredWithMessageAttribute()
    {
        ErrorMessageResourceType = typeof(ValidationResource);
        ErrorMessageResourceName = "RequiredErrorMessage";
    }
}

The error message is taken from the ValidationResource.resx file, where I list the error message as follows: 错误消息来自ValidationResource.resx文件,我在其中列出错误消息,如下所示:

RequiredErrorMessage --> "{0} is required." RequiredErrorMessage - >“{0}是必需的。”

where {0} = display name. 其中{0} =显示名称。

I then annotate my models like this, so I never have to repeat my error message declarations: 然后我像这样注释我的模型,所以我永远不必重复我的错误消息声明:

[RequiredWithMessage]
public string Name { get; set; }

Once you do this, an error message ("Name is required.") will appear whenever validation fails. 执行此操作后,只要验证失败,就会出现错误消息(“名称是必需的。”)。

This works properly with ASP.NET MVC's server-side validation and client-side validation. 这适用于ASP.NET MVC的服务器端验证和客户端验证。

I did another approach. 我做了另一种方法。 It still needs you to inherit DataAnnotation attributes, but you can get a more flexible translation solution. 它仍然需要您继承DataAnnotation属性,但您可以获得更灵活的翻译解决方案。

Code from my blog post (read it fore more details) 我的博客文章中的代码(请阅读更多详情)

End result 最终结果

public class User
{
    [Required]
    [LocalizedDisplayNameAttribute("User_Id")]
    public int Id { get; set; }

    [Required]
    [StringLength(40)]
    [LocalizedDisplayNameAttribute("User_FirstName")]
    public string FirstName { get; set; }

    [Required]
    [StringLength(40)]
    [LocalizedDisplayNameAttribute("User_LastName")]
    public string LastName { get; set; }
}

1 Inherit all data annotation attributes like this 1像这样继承所有数据注释属性

public class RequiredAttribute : System.ComponentModel.DataAnnotations.RequiredAttribute
{
    private string _displayName;

    public RequiredAttribute()
    {
        ErrorMessageResourceName = "Validation_Required";
    }

    protected override ValidationResult IsValid(object value, ValidationContext validationContext)
    {
        _displayName = validationContext.DisplayName;
        return base.IsValid(value, validationContext);
    }

    public override string FormatErrorMessage(string name)
    {
        var msg = LanguageService.Instance.Translate(ErrorMessageResourceName);
        return string.Format(msg, _displayName);
    }
}

2 Inherit DisplayNameAttribute 2继承DisplayNameAttribute

public class LocalizedDisplayNameAttribute : DisplayNameAttribute
{
    private PropertyInfo _nameProperty;
    private Type _resourceType;

    public LocalizedDisplayNameAttribute(string className, string propertyName)
        : base(className + (propertyName == null ? "_Class" : ("_" + propertyName)))
    {

    }

    public override string DisplayName
    {
        get
        {
            return LanguageService.Instance.Translate(base.DisplayName) ?? "**" + base.DisplayName + "**";
        }
    }
}

3. Create the language service (you can switch to any language source in it) 3.创建语言服务(您可以切换到其中的任何语言源)

public class LanguageService
{
    private static LanguageService _instance = new LanguageService();
    private List<ResourceManager> _resourceManagers = new List<ResourceManager>();

    private LanguageService()
    {
    }

    public static LanguageService Instance { get { return _instance; } }

    public void Add(ResourceManager mgr)
    {
        _resourceManagers.Add(mgr);
    }

    public string Translate(string key)
    {
        foreach (var item in _resourceManagers)
        {
            var value = item.GetString(key);
            if (value != null)
                return value;
        }

        return null;
    }
}

Finally you need to register the string tables you use to translate the validation messages and your models 最后,您需要注册用于转换验证消息和模型的字符串表

LanguageService.Instance.Add(MyNameSpace.ModelResource.ResourceManager);
LanguageService.Instance.Add(MyNameSpace.ValidationResources.ResourceManager);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM