Я работаю над проектом ASP.NET MVC 2 с некоторыми бизнес-объектами, которые применяют к ним атрибуты данных метаданных данных (атрибуты проверки, атрибуты отображения и т. Д.).Как я могу повторно использовать метаданные модели для пользовательских моделей?
Что-то вроде:
//User entity
public class User
{
[DisplayName("Vorname")]
[Required(ErrorMessage = "Vorname fehlt")]
[StringLength(MaxNameLength, ErrorMessage = "Vorname ist zu lang")]
public string FirstName { get; set; }
[DisplayName("Nachname")]
[Required(ErrorMessage = "Nachnamefehlt")]
[StringLength(MaxNameLength, ErrorMessage = "Nachname ist zu lang")]
public string LastName { get; set; }
[Required]
public string Password{ get; set; }
}
Использование метаданных из различных точек зрения не является проблемой, до тех пор, как я использую мои бизнес-объекты, как ViewModels или как часть ViewModel, как это:
//custom viewmodel with a user entity
public class CustomViewModel
{
public User{get;set;}
//some more properties...
}
Однако иногда мне нужно закодировать представление для редактирования некоторых, но не всех полей объекта. Для этих полей я хочу повторно использовать метаданные, уже указанные в моей пользовательской сущности. Остальные поля следует игнорировать. Я говорю о пользовательских моделях вида следующим образом:
[MetadataType(typeof(User))]
public class UserNameViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
//no password on purpose, the user should only
//edit his first and last name in this view
}
Вот где я столкнулся с проблемами. Модель пользовательского представления выше приводит к исключению, когда создается представление, поскольку оно не имеет свойства пароля.
Ассоциированный тип метаданных для типа «Zeiterfassung.Models.ViewModels.Users.UserNameViewModel + UserModel» содержит следующие неизвестные свойства или поля: Пароль. Пожалуйста, убедитесь, что , что имена этих членов соответствуют названиям объектов на основном .
Кроме того, даже если это исключение не произошло, я ожидаю получить еще больше проблем с проверкой модели при отправке формы, поскольку пароль отмечен как требуется в моей бизнес-сущности.
Я могу придумать несколько обходных решений, но никто не кажется действительно идеальным. В любом случае я не могу изменить макет базы данных, чтобы поле пароля было в отдельном объекте в моем примере выше.
Как вы справитесь с этим сценарием?
Это то, что я делал до сих пор, но это много дублирующийся код (в виде атрибутов метаданных). Это также означает наличие отдельных атрибутов проверки тестирования для нескольких моделей, а не только одной модели, хотя по существу у меня есть только одни правила валидации для всех моделей (например, FirstName всегда необходимо). –
Валидация имеет смысл только в заданном контексте для данного вида, поэтому писать единичные тесты для него не должно быть проблемой. Кошмар, с которым вы столкнетесь, если вы используете настоящие модели вместо моделей, будет на порядок хуже, чем устанавливать атрибуты проверки на ваши модели просмотра. Также вы когда-нибудь рассматривали возможность использования какой-либо другой структуры для проверки вместо аннотаций данных? [FluentValidation] (http://fluentvalidation.codeplex.com/) действительно отличная и может быть [unit testing] (http://fluentvalidation.codeplex.com/wikipage?title=Testing&referringTitle=Documentation) очень элегантно. –
Это не огромная проблема, но это большая работа, в основном в виде дополнительных модульных тестов. Это также означает более высокий потенциал ошибок, поскольку, когда правила валидации изменяются в моей бизнес-модели, мне также придется обновить несколько правил модели представления. Легко забыть об одном из них. –