Условная проверка модели в 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; }
}

и перейти к редактированию.