У меня есть несколько контроллеров учетных записей пользователей и моделей просмотра, реализованных для администрирования учетных записей пользователей.Многие из этих моделей представления содержат одни и те же свойства (например, электронная почта, имя пользователя, имя, фамилия, пароль) с одинаковыми аннотациями проверки данных.Я пытаюсь понять, как (или, если возможно, даже) разделить мои аннотации проверки на отдельный интерфейс / класс, чтобы мне нужно было определить эти аннотации только один раз.Конечная цель состоит в том, чтобы мне не нужно было повторять аннотации проверки (оставьте это СУХОЙ), и проверка на стороне сервера и на стороне клиента будет работать.
Я очень близко подошел, но не смог пересечь финишлиния.Рассмотрим эти две модели представления:
[MetadataType(typeof(IRegisterViewModel))]
public class RegisterViewModel : IRegisterViewModel
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string Email { get; set; }
public string UserName { get; set; }
public string Password { get; set; }
public string ConfirmPassword { get; set; }
}
[MetadataType(typeof(IAccountPassword))]
public class ChangePasswordViewModel : IAccountPassword
{
// this version is for already authenticated users that want to change their password
public string Password { get; set; }
public string ConfirmPassword { get; set; }
}
С этими интерфейсами аннотаций:
public interface IRegisterViewModel : IAccountName, IAccountEmail, IAccountUserName, IAccountPassword { }
public interface IAccountEmail
{
[Required(ErrorMessage = "Email is required")]
[EmailAddress(ErrorMessage = "Invalid Email address")]
[Display(Name = "Email")]
string Email { get; set; }
}
public interface IAccountName
{
[Required]
[MinLength(2, ErrorMessage = "First Name must be at least 2 letters")]
[MaxLength(50, ErrorMessage = "First Name is too long")]
[Display(Name = "First Name")]
string FirstName { get; set; }
[Required(ErrorMessage = "Last Name is required")]
[MinLength(2, ErrorMessage = "Last Name must be at least 2 letters")]
[MaxLength(50, ErrorMessage = "Last Name is too long")]
[Display(Name = "Last Name")]
string LastName { get; set; }
}
public interface IAccountPassword
{
[Required(ErrorMessage = "Password is required")]
[StringLength(100, ErrorMessage = "Password must be at least {2} characters long.", MinimumLength = 6)]
[DataType(DataType.Password)]
[Display(Name = "Password")]
string Password { get; set; }
[DataType(DataType.Password)]
[Display(Name = "Confirm Password")]
[Compare("Password", ErrorMessage = "The password and confirmation password do not match.")]
string ConfirmPassword { get; set; }
}
Проверка данных не работает (не кажется, что она даже подключена), когда я используюИнтерфейс состоит из нескольких интерфейсов, как в случае IRegisterViewModel
.Однако проверка данных работает в том случае, если я использую IAccountPassword
(при реализации только одного интерфейса).
Это всего лишь два примера ... У меня есть еще много контроллеров / моделей / представлений учетных записей, которые используютсядля администрирования учетной записи пользователя, и многие из них используют некоторую комбинацию общих свойств.Похоже, что было бы общим желанием определить их один раз, а не повторять самим, определяя их в моделях с несколькими представлениями (и нужно поддерживать обновления этих определений в моделях представления).
Я видел несколькодругие сообщения на SO с людьми, пытающимися сделать в основном то же самое.Обычно вопрос / ответ касается только одного наследования, а не множественного, как я пытаюсь сделать.Другим много лет и / или они помечены более старыми версиями MVC (поэтому я не знаю, действительны ли они больше или нет).Несмотря на это, я не нашел ничего работающего.
Это был интересный вопрос / ответный подход , который составлял требуемую модель представления из одной или нескольких "вспомогательных" моделей представления.Я полагаю, что я мог бы попробовать этот подход, если больше ничего не происходит, но это кажется неуклюжим и склонным к ошибкам при создании модели представления с одним свойством, а затем нужно обратиться к адресу электронной почты из моей родительской модели представления, используя Model.Email.Email
.
Конечно, это распространенная проблема, я не знаю, как искать правильный ответ, или я просто не соединяю все точки.