Сначала я использую ASP.NET MVC 3 и Entity Framework 4.1 Code.
Допустим, у меня есть объект User
:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; }
}
При редактировании в моем UserController
Я хочу добавить поле PasswordConfirmation
и убедиться, что PasswordConfirmation == Password
1.По составу
Моя первая попытка была:
public class EditUserModel
{
[Required]
public User User { get; set; }
[Compare("User.Password", ErrorMessage = "Passwords don't match.")]
public string PasswordConfirmation { get; set; }
}
В этом случае проверка на стороне клиента работает, но ( Редактировать: проверка на стороне клиента работаетбыло совпадением.) не работает , а проверка на стороне сервера завершается ошибкой со следующим сообщением: Не удалось найти свойство с именем User.Password
Редактировать: Я думаю, что лучшим решением в этом случае было бы создание пользовательского CompareAttribute
Реализация IValidatableObject
public class EditUserModel : IValidatableObject
{
[Required]
public User User { get; set; }
public string PasswordConfirmation { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if(this.PasswordConfirmation != this.User.Password)
return new[] { new ValidationResult("Passwords don't match", new[] { "PasswordConfirmation " }) };
return new ValidationResult[0];
}
}
В этом случае проверка на стороне сервера работает , но проверка на стороне клиента больше не работает .Реализация IClientValidatable
кажется слишком сложной, и в этом случае я предпочитаю не проводить проверку на стороне клиента.
2.По наследству
public class EditUserModel : User
{
[Compare("Password", ErrorMessage = "Passwords don't match.")]
public string PasswordConfirmation { get; set; }
}
При попытке напрямую сохранить EditUserModel
с помощью EF это не работает, я получаю сообщение об ошибке с метаданными EditUserModel
, поэтому я использую AutoMapper конвертировать из User
в EditUserModel
и обратно.Это решение работает , но оно более сложное, потому что мне нужно преобразовать модель в модель представления и обратно.
3.Путем дублирования
(предложено Malte Clasen)
Модель представления будет иметь все свойства модели плюс дополнительные. AutoMapper может использоваться для преобразования из одного в другое.
public class EditUserModel {
public string Name { get; set; }
public string Email { get; set; }
public string Password { get; set; }
[Compare("Password", ErrorMessage = "Passwords don't match.")]
public string ConfirmPassword { get; set; }
}
Это решение мне нравится меньше всего из-за дублирования кода (DRY)
Вопросы
Каковы плюсы и минусы наследования, композиции и дублирования в этом случае?
Существует ли простой способ проверки на стороне клиента и на стороне сервера без необходимости преобразованиямодель к виду модель и обратно?