Я использую сначала ASP.NET MVC 3 и Entity Framework 4.1.
Скажем, у меня есть объект 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)
Вопросы
Каковы преимущества и недостатки наследования, составления и дублирования в этом случае?
Есть ли простой способ проверки как на стороне клиента, так и на стороне сервера без преобразования модели в модель представления и назад?