如何控制模型绑定?

时间:2012-05-31 00:15:21

标签: c# asp.net-mvc-3 model-binding

我最近开始使用MVC而且我很失望。而不是帮助我,框架正在阻碍我。

我试图编写像这样的控制器动作(伪代码)

ActionResult Save(long id, string whichForm)
{
    if (whichForm == "A")
    {
        var vm = CreateModel(Request.Form);
        if (!TryValidate(vm))
            return View(vm);
        else
            return RedirectToRoute("Success");
    }
    else ....
}

基本上我希望能够控制构建视图模型的时间以及何时验证它。这可能吗?如何实现CreateModel方法?考虑我可能想在此控制器操作中创建几个不同的视图模型。

* Rant:我真的不明白为什么在DefaultModelBinder中将视图模型绑定和验证混合在一起。好像代码味道。特别是当它很难覆盖这种行为时。

2 个答案:

答案 0 :(得分:21)

您可以自行决定创建并绑定到现有模型:

public ActionResult Save(long id, string whichForm)
{
    if (whichForm == "A")
    {
        var vm = new FormAViewModel();

        if (!TryUpdateModel(vm))
            return View(vm);
        else
            return RedirectToRoute("Success");
    }
    // else ....
}

You also have the option of creating your own IModelBinder,如果您想要完全控制绑定过程。您可以替换默认的模型绑定器,也可以为特定类型注册特定的IModelBinder实现。但是,我建议,除非您的绑定逻辑很简单,否则您可能希望从DefaultModelBinder派生自定义模型绑定器,并覆盖您不喜欢的部分。

我讨厌留下一个巨大的评论,但是有十分之一的人认为一个框架正在阻碍它的原因是因为他们还不知道如何正确使用它。 Here is an article with general tips on model binding

关于你的咆哮:验证和绑定是分开的,但是,默认的模型绑定器会触发验证。这样做的原因是允许您的应用程序优雅地处理绑定到缺失/无效/不完整值的问题,而不是允许绑定以静默方式失败或抛出异常。

答案 1 :(得分:0)

您可以利用IModelBinder界面并编写完整的自定义模型绑定器。这里解释得很好。本质上,此接口公开了一个方法“BindModel”,您可以在其中控制模型绑定行为以及验证。

http://www.dotnetcurry.com/ShowArticle.aspx?ID=584

但是,这可能会使问题复杂化,您可能会收到意大利面条代码。我会建议一个简单的“每个模型的动作”,如果它适合你。所以你可以这样写:

ActionResult SaveA(long id, AViewModel)
{
      //.... Action to be conducted in case it is form A.
}
ActionResult SaveB(...., BViewModel)
{
       //... Action to be conducted in case it is form B.
}


// Your view models can be structured for code reuse as well.
class AViewModel {  ...  }
class BViewModel : AViewModel {  ...  }