在 MVC4 窗体中生成所需的复杂类型化属性

本文关键字:复杂 类型化 属性 MVC4 窗体 | 更新日期: 2023-09-27 18:35:11

当我将 [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界面的用法?

在 MVC4 窗体中生成所需的复杂类型化属性

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

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

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

你期望你的代码,ASP.NET MVC,知道你正在使用这个MyModel类?您绝对从未在 POST 操作中使用它,因此您不能期望对其进行任何验证。

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