DataAnnotation с пользовательским ResourceProvider

Я создал пользовательское ResourceProvider вытягивать информацию о локализации от базы данных. Я теперь хочу использовать DataAnnotation добавить проверку к модели.

DataAnnotation имеет ErrorMessageResourceType и ErrorMessageResourceName свойства, но ErrorMessageResourceType только принимает System.Type (т.е. скомпилированный файл ресурсов)

Там какой-либо путь состоит в том, чтобы заставить DataAnnotation использовать пользовательский ResourceProvider?

19
задан analyticalpicasso 22 January 2014 в 15:52
поделиться

2 ответа

Для этого я использовал беглую проверку. Это экономит мне много времени. Так выглядит мой глобальный валидатор. Это означает, что вы не используете аннотации данных, но иногда аннотации данных становятся немного большими и беспорядочными.

Вот пример:

(Errors.Required, Labels.Email и Errors.AlreadyRegistered находятся в моей папке с ресурсами blobal.)

public class CreateEmployerValidator : AbstractValidator<CreateEmployerModel> {
    public RegisterUserValidator() { 
        RuleFor(m => m.Email)
            .NotEmpty()
            .WithMessage(String.Format(Errors.Required, new object[] { Labels.Email }))
            .EmailAddress()
            .WithMessage(String.Format(Errors.Invalid, new object[] { Labels.Email }))
            .Must(this.BeUniqueEmail)
            .WithMessage(String.Format(Errors.AlreadyRegistered,  new object[] { Labels.Email }));
    }

    public bool BeUniqueEmail(this IValidator validator, string email )  {
        //Database request to check if email already there?
        ...
    }    
}

Как я уже сказал, это аннотации к данным с удаленной формы, только потому, что я уже слишком много аннотаций к моим методам!

3
ответ дан 30 November 2019 в 05:15
поделиться

Я понимаю, что это старый вопрос, но хотел добавить немного. Я оказался в такой же ситуации, и, похоже, нет никакой документации/блогов на эту тему. Тем не менее, я нашел способ использовать пользовательский поставщик ресурсов, с одной оговоркой. Оговорка заключается в том, что я нахожусь в приложении MVC, поэтому у меня все еще есть HttpContext.GetLocalResourceObject(). Это метод, который asp.net использует для локализации элементов. Отсутствие объекта ресурса не мешает написать собственное решение, даже если это прямой запрос к таблицам БД. Тем не менее, я подумал, что на это стоит обратить внимание.

Хотя я не очень доволен следующим решением, оно, кажется, работает. Для каждого атрибута проверки, который я хочу использовать, я наследую от этого атрибута и перегружаю IsValid(). Оформление выглядит так:

[RequiredLocalized(ErrorMessageResourceType= typeof(ClassBeginValidated), ErrorMessageResourceName="Errors.GenderRequired")]
public string FirstName { get; set; } 

Новый атрибут выглядит так:

public sealed class RequiredLocalized : RequiredAttribute {

    public override bool IsValid(object value) {

        if ( ! (ErrorMessageResourceType == null || String.IsNullOrWhiteSpace(ErrorMessageResourceName) )   ) {
            this.ErrorMessage = MVC_HtmlHelpers.Localize(this.ErrorMessageResourceType, this.ErrorMessageResourceName);
            this.ErrorMessageResourceType = null;
            this.ErrorMessageResourceName = null;
        }
        return base.IsValid(value);
    }
}

Примечания

  • Вы должны оформлять свой код производным атрибутом, а не стандартным
  • Я использую ErrorMessageResourceType для передачи типа проверяемого класса. То есть, если я нахожусь в классе customer и проверяю свойство FirstName, я передаю typeof(customer). Я делаю это потому, что в бэкенде моей базы данных я использую полное имя класса (пространство имен + имя класса) в качестве ключа (так же, как URL страницы используется в asp.net).
    • MVC_HtmlHelpers.Localize - это просто простая обертка для моего пользовательского поставщика ресурсов

Код (полуворованного) помощника выглядит следующим образом ....

public static string Localize (System.Type theType, string resourceKey) {
    return Localize (theType, resourceKey, null);
}
public static string Localize (System.Type theType, string resourceKey, params object[] args) {
    string resource = (HttpContext.GetLocalResourceObject(theType.FullName, resourceKey) ?? string.Empty).ToString();
    return mergeTokens(resource, args);
}

private static string mergeTokens(string resource, object[] args)        {
    if (resource != null && args != null && args.Length > 0) {
        return string.Format(resource, args);
    }  else {
        return resource;
    }
}
6
ответ дан 30 November 2019 в 05:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: