Условная проверка модели в MVC
У меня есть представление и модель, которые я использую как для редактирования, так и для страницы вставки для записи. Одним из бизнес-требований является то, что определенное поле требуется для редактирования, но не для нового. Первоначально, прежде чем эта особенность была добавлена в docket, у меня была такая модель:
[Required(ErrorMessage = "*")]
[Range(0.0, (double)decimal.MaxValue)]
[DisplayName("Cost")]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public decimal ProposedCost { get; set; }
Я хотел бы либо удалить требуемое свойство, если оно является формой вставки, либо добавить его в форму редактирования. Какой лучший подход? Вся моя другая проверка выполняется, как указано выше. Или я могу изменить состояние модели? Мысли?
ИЗМЕНИТЬ
Что-то я должен уточнить, так это то, что им по-прежнему разрешено вставлять затраты на новые, просто не требуемые.
Ответы
Ответ 1
Если вы находитесь на MVC3/.NET4, вы можете использовать IValidatableObject
, который существует специально для таких целей.
Цитата ScottGu,
... Интерфейс IValidatableObject позволяет выполнять модельный уровень валидация и позволяет вам предоставлять сообщения об ошибках проверки специфичный для состояния общей модели....
Модель будет выглядеть как
public class MyViewModel : IValidatableObject
{
public long? Id { get; set; }
public decimal? ProposedCost { get; set; }
public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
{
if (Id != null && ProposedCost == 0) {
yield return new ValidationResult("ProposedCost must be provided.");
}
}
}
а затем в контроллере
[HttpPost]
public ActionResult Submit(MyViewModel model)
{
if (!ModelState.IsValid) {
//failed - report an error, redirect to action etc
}
//succeeded - save to database etc
}
В противном случае самым чистым решением будет использование моделей просмотра - UpdateViewModel
, где требуется свойство, и CreateViewModel
, где это не требуется.
Ответ 2
Существует библиотека MVC Foolproof: http://foolproof.codeplex.com/
Например, в вашей модели должно быть что-то вроде этого:
[RequiredIfTrue("Required", ErrorMessage = "*")]
[Range(0.0, (double)decimal.MaxValue)]
[DisplayName("Cost")]
[DisplayFormat(DataFormatString = "{0:d}", ApplyFormatInEditMode = true)]
public decimal ProposedCost { get; set; }
public bool Required { get; set; }
Затем вам нужно будет установить свойство Required
, на основе которого будет выглядеть модель.
Вам также понадобится скрытое поле ввода в форме для представления свойства Required
, если вы хотите выполнить проверку на стороне клиента.
Надеюсь, что это поможет...
Ответ 3
Вы можете использовать атрибут проверки RequiredIf
из проекта MVC Foolproof Validation.
Я использовал его для проектов, чтобы обеспечить только необходимую функциональность.
Альтернативой было бы использовать RemoteAttribute
и реализовать логику самостоятельно в методе.
Ответ 4
Вы можете проверить правильность с помощью:
ModelState.Remove("ProposedCost");
Или расширьте свою модель следующим образом:
public class NewModeViewModel : EditModeViewModel
{
public new decimal ProposedCost { get; set; }
}
и перейти к редактированию.