【问题标题】:MVC Custom ViewModel and auto bindingMVC 自定义 ViewModel 和自动绑定
【发布时间】:2010-10-20 09:46:18
【问题描述】:

我有一个自定义 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 中的下拉列表。 我猜想自动绑定回自定义视图模型是失败的原因,但不知道该怎么办。

【问题讨论】:

  • 您发布的表单是什么样的?

标签: asp.net-mvc binding viewmodel


【解决方案1】:

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

public class SampleFormViewModel
{
    public SampleFormViewModel() { }

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

不过,我怀疑您真正想要做的不是获取视图模型,而是获取底层 Widget 模型和表单发布上的选择列表值。我不认为活页夹将能够在 post 上重建 SelectList,因为它只有参数中的选定值。

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

【讨论】:

  • 是的,我现在明白了。问题是 SelectList 没有无参数的构造函数。如果我从构造函数中删除 SelectList (Companies)。并在我创建 ViewModel 时动态构建它(根据小部件对象中的信息),它一切都按预期工作。唯一的区别是我在 POST 中如何处理它,签名现在是:public ActionResult Edit(int id, FormCollection formValues)
【解决方案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 会给您一个难以捉摸的“无无参数构造函数”错误。

但是,如果您创建了类似帮助类的东西,请从原始类中剪切并粘贴确切的代码,然后将该帮助类作为原始类的参数(不是获取/设置);你可以走了。

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

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

谢天谢地,当前版本似乎只是顶级版本。感觉就像一个 hack,我希望这是设计使然。

HTH。

【讨论】:

  • 你能详细说明一下关于选择列表的帮助类的陈述吗?也许有一个代码示例?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多