MVC自定义ViewModel和自动绑定

时间:2009-04-19 13:25:29

标签: asp.net-mvc binding viewmodel

我将自定义ViewModel定义为:

public class SampleFormViewModel
{
    public SampleFormViewModel(SelectList companies, Widget widget)
    {
        Companies = companies;
        Widget = widget;
    }

    public SelectList Companies { get; private set; }
    public Widget Widget { get; private set; }
}

在我的编辑POST处理程序中,我有以下条目:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(SampleFormViewModel model)
{

编辑表单设置为:

Inherits="System.Web.Mvc.ViewPage<Sample.Web.Models.SampleFormViewModel>"

它只是爆炸,不知道发生了什么,有以下错误: 没有为此对象定义的无参数构造函数。 某些我错过了一些非常明显的东西。一些背景,GET完美运行并按预期显示SelectList的下拉列表。 我猜测自动绑定回自定义视图模型是失败但不知道该怎么做。

2 个答案:

答案 0 :(得分:8)

你需要一个无参数的构造函数,我相信这些属性需要有公共的setter。默认绑定器使用不带参数的构造函数创建对象,然后使用公共属性上的反射来设置表单/查询参数中的值。

public class SampleFormViewModel
{
    public SampleFormViewModel() { }

    public SelectList Companies { get; set; }
    public Widget Widget { get; set; }
}
但是,我怀疑,你真正想做的不是获取视图模型,而是获取底层Widget模型并在表单上选择列表值。我不认为活页夹能够在帖子上重建SelectList,因为它只在参数中有选定的值。

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit( int CompanyID, Widget widget )
{
}

答案 1 :(得分:2)

MVC要求在强类型视图上,视图可以创建在该视图上使用的类。这意味着没有任何参数的构造函数。这是有道理的。 MVC新手会看到类似的“嗯?”当他们忘记/未能使参数公开时发生问题,以及当视图尝试将自身组合在一起时弹出的所有此类相关错误(与编译器错误相反)。

但是这类无参数构造函数问题中的“有趣”是当类的属性也没有无参数构造函数时。我想这是悲观的做法?

在SelectList类上花了一些学习时间 - 一个特定于MVC的类 - 我希望能帮助一些人节省几分钟/小时。

这个用于创建下拉列表的非常重要的工具/类具有以下构造函数:

public SelectList(IEnumerable items); public SelectList(IEnumerable items,object selectedValue); public SelectList(IEnumerable items,string dataValueField,string dataTextField); public SelectList(IEnumerable items,string dataValueField,string dataTextField,object selectedValue);

..因此,如果这些是您的类(用于视图的属性)的属性,MVC将为您提供难以捉摸的“无参数构造函数”错误。

但是,如果您创建类似帮助程序类的东西,请从原始类中剪切确切的代码,然后将该帮助程序类作为原始类的参数(不是get / set);你很高兴。

通过这种方式,您可以使用单个视图获取和发布。哪个更漂亮:)。

个人而言,我要么创建编译器来识别强类型视图的关联和要求,要么让下拉列表(或SelectList的其他“客户”)无法工作,而不是想知道是否有特定的级别对无参数构造函数的递归检查。

值得庆幸的是,目前的版本似乎只是顶级。感觉就像一个黑客,我希望它是设计的。

HTH。