Я создал пользовательское ResourceProvider
вытягивать информацию о локализации от базы данных. Я теперь хочу использовать DataAnnotation
добавить проверку к модели.
DataAnnotation
имеет ErrorMessageResourceType
и ErrorMessageResourceName
свойства, но ErrorMessageResourceType
только принимает System.Type
(т.е. скомпилированный файл ресурсов)
Там какой-либо путь состоит в том, чтобы заставить DataAnnotation использовать пользовательский ResourceProvider?
Для этого я использовал беглую проверку. Это экономит мне много времени. Так выглядит мой глобальный валидатор. Это означает, что вы не используете аннотации данных, но иногда аннотации данных становятся немного большими и беспорядочными.
Вот пример:
(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?
...
}
}
Как я уже сказал, это аннотации к данным с удаленной формы, только потому, что я уже слишком много аннотаций к моим методам!
Я понимаю, что это старый вопрос, но хотел добавить немного. Я оказался в такой же ситуации, и, похоже, нет никакой документации/блогов на эту тему. Тем не менее, я нашел способ использовать пользовательский поставщик ресурсов, с одной оговоркой. Оговорка заключается в том, что я нахожусь в приложении 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);
}
}
Примечания
Код (полуворованного) помощника выглядит следующим образом ....
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;
}
}