Ресурс по умолчанию для аннотаций данных в ASP.NET MVC - PullRequest
18 голосов
/ 16 июля 2010

Есть ли способ установить ресурс по умолчанию для проверки аннотаций данных?

Я не хочу делать что-то вроде этого:

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

Я бы хотел что-то вроде этого:

Global.asax

DataAnnotations.DefaultResources = typeof(CustomDataAnnotationsResources);

тогда

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

кто-то дай мне свет!

заранее спасибо

EDIT

Моя настоящая проблема была с EF Code First CTP4. CTP5 это исправить. Спасибо всем.

Ответы [ 3 ]

13 голосов
/ 03 декабря 2010

Вы можете попробовать сделать это:

Добавьте этот класс где-нибудь в вашем проекте:

 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);
        }
    }
}

и в вашем 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));

Будет выполнено поиск свойства с тем же именем, что и тип валидатора для сообщения об ошибке.Вы можете изменить это с помощью свойства ResourceNameFunc.

EDIT: AFAIK это работает начиная с MVC2, так как DataAnnotationsModelValidatorProvider был представлен в MVC2.

12 голосов
/ 29 ноября 2010

Для этого я создал новый класс, который наследуется от RequiredAttribute, и сообщение об ошибке встроено в этот новый класс:

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

Сообщение об ошибке взято из файла ValidationResource.resx, гдеЯ перечисляю сообщение об ошибке следующим образом:

RequiredErrorMessage -> "{0} требуется."

где {0} = отображаемое имя.

Затем я комментируютаким моделям, поэтому мне никогда не придется повторять объявления сообщений об ошибках:

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

После того, как вы это сделаете, сообщение об ошибке («Требуется имя.») будет появляться при сбое проверки.

Это правильно работает с проверкой на стороне сервера ASP.NET MVC и проверкой на стороне клиента.

3 голосов
/ 03 декабря 2010

Я сделал другой подход.Вам все еще нужно, чтобы вы унаследовали DataAnnotation атрибуты, но вы можете получить более гибкое решение для перевода.

Код из моего блога (читайте его подробнее)

Конечный результат

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 Унаследовать все атрибуты аннотаций данных, подобные этому

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 Унаследовать 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.Создайте языковую службу (в ней можно переключиться на любой источник языка)

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;
    }
}

Наконец, вам нужно зарегистрировать таблицы строк, которые вы используете для перевода сообщений проверки и ваших моделей

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