模型绑定器究竟做了什么?如何有效地使用它?

时间:2011-03-31 00:37:58

标签: asp.net-mvc-3 annotations model-binding

我正在研究某些内容并遇到this blog post at buildstarted.com关于模型绑定器的问题。它实际上对我的目的来说非常好,但我不确定幕后会发生什么。我所做的是创建一个名为USerModelBinder的自定义ModelBinder:

public class UserModelBinder : IModelBinder
{
    public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
    {
        ValueProviderResult value = bindingContext.ValueProvider.GetValue("id");
        MyEntities db = new MyEntities();
        User user = db.Users.SingleOrDefault(u => u.UserName == value.AttemptedValue);
        return user;
    }
}

然后在Global.asax.cs我有:

ModelBinders.Binders.Add(typeof(User), new UserModelBinder());

我的理解是,使用模型绑定器允许我不必在涉及“用户”的每个控制器操作中使用以下行。因此,模型绑定器不会向操作传递“id”,而是截取id,获取正确的“item”(在我的情况下为User)并将其转发给操作进行处理。

        MyEntities db = new MyEntities();
        User user = db.Users.SingleOrDefault(u => u.UserName == value.AttemptedValue);

我也尝试在我的User类上使用注释,而不是使用Global.asax.cs中的行:

[ModelBinder(typeof(UserModelBinder))]
public partial class User
{
}

我不是在寻找30页的白皮书,但我不知道模型装订器是如何做到的。我只是想了解从发出请求到发送请求的时间会发生什么。所有这些“只是工作”的东西对我来说是不能接受的,哈哈。另外,使用注释与在Global.asax.cs中添加它有什么区别吗?它们在我的测试中看起来一样,但是有没有问题?

2 个答案:

答案 0 :(得分:7)

通常,Model Binder(在MVC中)会查看Action方法并查看它所需的内容(如对象类型)。然后它尝试从HTTP请求中找到值(HTTP表单,QueryString,Json中的值以及可能使用ValueProviders等其他地方,如cookie等)。然后它使用它检索的参数创建一个新对象。

IMO你所做的并不是真正的“模型绑定”。从某种意义上说,你刚刚读取了id并从数据库中获取了对象。

通常的模型绑定示例:

// class
public class SomeClass
{
    public int PropA {get;set;}
    public string PropB {get;set;}
}

// action

public ActionResult AddSomeClass(SomeClass classToBind)
{
  // implementation
}

// pseudo html

      <form action="">
       <input name="PropA" type="text" />
       <input name="PropB" type="text" />
      </form>

如果您发布包含正确值的表单(假设您使用PropA和PropB发布表单),模型绑定器可以识别您已在表单中发送这些值并构建SomeClass对象。

如果你真的想要创建一个真正的工作示例,你应该使用强类型视图并使用HtmlHelper的EditorFor(或EditorForModel)来创建MVC所需的所有正确名称。

-

供参考MVC的默认绑定器是DefaultModelBinder,有些(还有更多,你可以在System.Web.Mvc命名空间中查看)默认使用的ValueProviders是FormValueProviderQueryStringValueProvider

因此,正如我已经说过的,这基本上如何工作是默认模型绑定器读取操作正在接收的模型(例如示例中的SomeClass)读取它可以读取的值(比如PropA和PropB)并向ValueProviders询问属性的正确值。

另外,如果我没记错的话,您还可以使用ValueProviderFactories静态类在运行时看到值提供程序。

答案 1 :(得分:3)

ModelBinder查看所选Controller操作的方法签名的参数,然后将ValueProvider s中的值转换为这些参数。

ControllerActionInvoker调用与ControllerContext相关联的操作时会发生这种情况,因为Controller的{​​{1}}方法告诉了它。

有关ASP.NET MVC执行过程的更多信息,请参阅Understanding the MVC Application Execution Process