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

ama*_*ers 5 c# validation asp.net-mvc automapper

我有这个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; }
}
Run Code Online (Sandbox Code Playgroud)

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

public class Question {

    public int Id { get; set; }
    public string Text { get; set; }
    public string Description { get; set; }
    public bool IsRequired { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

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
    }
}
Run Code Online (Sandbox Code Playgroud)

Hen*_*ema 6

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

Darin还指出MSDN上包含该RequiredIf属性实现的博文.

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

public class ResponseViewModel {

    public QuestionViewModel Question { get; set; }

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

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


Réd*_*tar 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.");
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

@Html.HiddenFor(m => m.Question.IsRequired)
Run Code Online (Sandbox Code Playgroud)

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