#c# #asp.net-mvc #validation #ef-code-first #asp.net-mvc-5
#c# #asp.net-mvc #проверка #ef-code-first #asp.net-mvc-5
Вопрос:
Я использую подход Entity Framework Code First, что означает, что моей модели нужны атрибуты аннотации данных для создания базы данных. И я действительно хочу, чтобы проверка была на моей модели.
У меня есть несколько просмотров на моем веб-сайте, которые могут публиковать некоторую информацию. Но эта информация не является полной моделью, и если бы я должен был ее проверить, проверка завершилась бы неудачей.
Например, у меня могла бы быть модель со следующими обязательными свойствами: Title
, Text
, X
… Но тогда у меня могло бы быть представление, в котором было бы опубликовано только значение для Text
. Для этого я создаю ViewModel (в котором также есть другие элементы, не привязанные к модели). Но как я буду проверять Text
в этом случае? Мне нужно, чтобы она имела ту же проверку, что и свойство модели Text
.
Есть ли способ иметь одинаковые проверки для Model и ViewModel без дублирования кода?
Это попытка, которая просто не сработает…
Я подумал о создании пользовательского атрибута, который связывал бы проверки с моделью:
/* This wouldn't work */
public class PropertyValidationAttribute : ValidationAttribute
{
public Type Type { get; set; }
public string PropertyName { get; set; }
public PropertyValidationAttribute(Type type, string propertyName)
{
Type = type;
PropertyName = propertyName;
}
protected override ValidationResult IsValid(object value, ValidationContext validationContext)
{
var attrs = Type.GetProperty(PropertyName).GetCustomAttributes(typeof(ValidationAttribute), true) as IEnumerable<ValidationAttribute>;
if (attrs != null)
{
foreach (var attr in attrs)
{
return attr.GetValidationResult(value, validationContext);
}
}
return base.IsValid(value, validationContext);
}
}
Проблема с вышесказанным заключается в том, что каждый ValidationAttribute
может проверять только одну вещь за раз, поэтому, если у меня есть несколько атрибутов проверки в моей модели, это не будет работать должным образом. И я не уверен, будет ли это работать на стороне клиента, я даже не тестировал это…
Комментарии:
1. Должно быть, я что-то упускаю. Вы говорите: » Но как я буду проверять текст в этом случае? Мне нужно, чтобы она имела ту же проверку, что и текст свойства модели «. Какая проверка есть в модели, которую вам нужно реплицировать в модели представления?
2. Мне это нужно в ViewModel, чтобы иметь возможность использовать проверку на стороне клиента…
3. Можете ли вы просто применить атрибуты как к модели, так и к ViewModel? Или это дублирование, которого вы пытаетесь избежать?
Ответ №1:
Хотя вы, безусловно, можете разработать решение, вы, вероятно, напишете много кода, чтобы избежать написания очень небольшого объема кода.
Есть вещи, которые следует учитывать. Во-первых, некоторые проверки не совпадают между EF и MVC. Например, EF использует MaxLength и minLength, в то время как MVC использует StringLength .
Во-вторых, как вы собираетесь определять, какие атрибуты вы действительно хотите, а какие нет?
Наконец, на самом деле есть только один атрибут, который сопоставляется между .. и это обязательно. Если вы собираетесь использовать атрибут для дублирования… ну, вы только что создали столько же кода, плюс написали весь код для выполнения сопоставления…
Я бы просто взял крошечный удар и продублировал отображение в обоих местах…
Ответ №2:
Вы можете использовать отражение при сопоставлении вашей модели с вашей viewmodel, чтобы проверить наличие любых атрибутов проверки, а затем применить те же атрибуты к вашей viewmodel. Предполагая, что имена ваших свойств одинаковы как в вашей модели, так и в viewmodel, вы сможете создать один метод, который делает это.