创建MVC4表单中所需的复杂类型属性

时间:2013-10-14 09:57:05

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

当我将其固定到自定义类型属性时,我无法弄清楚如何“自定义”[Required]属性的规则。代码如下所示:

public class MyProp
{
    public Guid Id {get;set;}
    public string Target {get;set;}
}
public class MyType : IValidatableObject
{
    public string Name {get;set;}
    public MyProp Value {get;set;}

    private MyType()
    {
        this.Name = string.Empty;
        this.Value = new MyProp { Id = Guid.Empty, Target = string.Empty };
    }
    public MyType(Guid id) : this()
    {
        this.Value.Id = id;
        // Fill rest of data through magic
    }

    public IEnumerable<ValidationResult> Validate(ValidationContext validationContext)
    {
        if(this.Value.Id == Guid.Empty)
            yield return new ValidationResult("You must fill the property");
    }
}

此模型以表格形式(通过其自己的EditorTemplate)显示为带有按钮的文本框,该按钮允许从列表中进行选择(支持数据是Dynamics CRM 2011环境,此模型实际上旨在表示查找属性。)

public class MyModel
{
    // Many props

    [Required] // This one is enforced correctly
    public string MyString {get;set;}

    [Required] // This one isn't
    public MyType MyData {get;set;}

    public MyModel() { this.MyData = new MyType(); }
}

结果视图显示该字段(当然是空的)。用户只能通过单击字段并从列表中选择来输入数据(jquery对话框可以处理此问题,并且它已经可以工作)。

IValidatableObject界面听起来很有希望,但似乎没有调用代码。

在控制器中,我只是在做

[HttpPost]
public ActionResult MyAction(FormCollection data)
{
    if (!ModelState.IsValid) return View();
    // magic: handle data
}

我错过了什么?我可能误解了IValidatableObject界面用法?

1 个答案:

答案 0 :(得分:1)

您的控制器操作应该将视图模型作为参数而不是弱类型FormCollection,它与您的模型(及其验证规则)完全无关:

[HttpPost]
public ActionResult MyAction(MyModel model)
{
    if (!ModelState.IsValid) 
    {
        return View();
    }

    // magic: handle model
}

现在将调用默认模型绑定器,以便从请求绑定视图模型,并评估此模型中可能具有的任何验证逻辑。

您对代码ASP.NET MVC的期望是如何知道您正在使用此MyModel类?你绝对没有在你的POST动作中使用它,所以你不能期望对它进行任何验证。

一旦开始使用视图模型,您应该忘记弱类型集合,例如FormCollection,并开始使用这些视图模型。