对用户未输入的数据进行模型验证

时间:2013-09-10 06:13:36

标签: c# asp.net-mvc automapper validation

我有这个ViewModel(简化):

public class ResponseViewModel {

    public QuestionViewModel Question { get; set; }
    public string Answer { get; set; }
}

public class QuestionViewModel {

    public string Text { get; set; }
    public string Description { get; set; }
    public bool IsRequired { get; set; }
}

QuestionViewModel是从我的DAL实体问题映射的,这是一个简单的映射:

public class Question {

    public int Id { get; set; }
    public string Text { get; set; }
    public string Description { get; set; }
    public bool IsRequired { get; set; }
}

如果Answer为真,我希望能够Question.IsRequired成功。 但是在回发之后只有属性Answer被填充(当然)。

去哪里最好的方法是什么?我希望能够创建验证属性,但不知道如何实现这一点。

更新:

我尝试使用ModelBinding使其工作,但直到现在还没有成功。我做了什么:

public class EntityModelBinder : DefaultModelBinder
  protected override object CreateModel(ControllerContext controllerContext, ModelBindingContext bindingContext, Type modelType)
    {
        // IF I DO IT HERE I AM TOO EARLY
    }
  protected override void OnModelUpdated(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        base.OnModelUpdated(controllerContext, bindingContext);
        // IF I DO IT HERE I AM TOO LATE. VALIDATION ALREADY TOOK PLACE
    }
}

2 个答案:

答案 0 :(得分:6)

也许您需要RequiredÌf属性。 StackOverflow就此有几个问题。其中一个可以在这里找到:RequiredIf Conditional Validation Attribute

Darin还指向包含RequiredIf属性实现的blogpost on MSDN

使用此属性,您的视图模型将变为:

public class ResponseViewModel {

    public QuestionViewModel Question { get; set; }

    [RequiredIf("Question.IsRequired", true, "This question is required.")]
    public string Answer { get; set; }
}

我不确定我提供的实现是否支持复杂类型的属性(例如Question.IsRequired),但是通过一些修改它应该是可能的。

答案 1 :(得分:5)

您可以使用IValidatableObject在班级执行验证(在本例中为ResponseViewModel),以便根据Question.IsRequired检查答案的有效性:

public class ResponseViewModel : IValidatableObject
{
    public QuestionViewModel Question { get; set; }
    public string Answer { get; set; }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if (Question.IsRequired && string.IsNullOrEmpty(Answer))
        {
            yield return new ValidationResult("An answer is required.");
        }
    }
}

但是,Question.IsRequired在验证过程中必须具有有效值。您可以将它作为隐藏输入放在视图中来执行此操作:

@Html.HiddenFor(m => m.Question.IsRequired)

默认模型绑定器将获得正确的值并正确执行验证。