模型绑定器到底是做什么的?如何有效地使用它?
我正在研究一些东西,发现这个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,获取正确的“项目”(在我的例子中为用户)并将其转发给操作进行处理。
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 中添加注释之间有什么区别吗?它们在我的测试中似乎工作相同,但是有什么问题吗?
I was researching something and came across this blog post at buildstarted.com about model binders. It actually works pretty darn well for my purposes but I am not sure exactly whats going on behind the scenes. What I did was create a custom ModelBinder called USerModelBinder
:
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;
}
}
Then in my Global.asax.cs
I have:
ModelBinders.Binders.Add(typeof(User), new UserModelBinder());
My understanding is that using the model binder allows me to NOT have to use the following lines in every controller action that involves a "User". So instead of passing in an "id" to the action, the modelbinder intercepts the id, fetches the correct "item"(User in my case) and forwards it to the action for processing.
MyEntities db = new MyEntities();
User user = db.Users.SingleOrDefault(u => u.UserName == value.AttemptedValue);
I also tried using an annotation on my User class instead of using the line in Global.asax.cs:
[ModelBinder(typeof(UserModelBinder))]
public partial class User
{
}
I'm not looking for a 30 page white paper but I have no idea how the model binder does what it does. I just want to understand what happens from when a request is made to the time it is served. All this stuff "just working" is not acceptable to me, lol. Also, is there any difference between using the annotation versus adding it in Global.asax.cs? They seem to work the same in my testing but are there any gotchas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
通常,模型绑定器(在 MVC 中)会查看您的 Action 方法并查看它需要什么(如对象类型)。然后,它尝试从 HTTP 请求中查找值(HTTP 表单、QueryString、Json 中的值,可能还有其他位置,例如使用 ValueProviders 的 cookie 等)。然后,它使用检索到的参数创建一个新对象。
IMO 你所做的并不是真正的“模型绑定”。从某种意义上说,您刚刚读取了 id 并从数据库中获取了对象。
常见模型绑定的示例:
如果您发布包含正确值的表单(假设您发布带有 PropA 和 PropB 的表单),模型绑定程序可以识别您已在表单中发送了这些值并构建 SomeClass 对象。
如果您确实想创建一个真正的工作示例,您应该使用强类型视图并使用 HtmlHelper 的 EditorFor(或 EditorForModel)来创建 MVC 需要的所有正确名称。
--
作为参考,MVC 的默认绑定器是 DefaultModelBinder,还有一些(还有更多,您可以在 System.Web.Mvc 命名空间中查看)默认使用的 ValueProvider 是 FormValueProvider 和 QueryStringValueProvider
因此,正如我已经说过的,这基本上是如何工作的,默认模型绑定器读取操作正在接收的模型(例如示例中的 SomeClass)读取什么是它可以读取的值(例如 PropA 和 PropB),并向 ValueProvider 询问属性的正确值。
另外,如果我没记错的话,您还可以使用 ValueProviderFactories 静态类在运行时查看值提供程序。
Usually the Model Binder (in MVC) looks at you Action method and sees what it requires (as in, the objects types). It then tries to find the values from the HTTP Request (values in the HTTP Form, QueryString, Json and maybe other places such as cookies etc. using ValueProviders). It then creates a new object with the parameters that it retrieves.
IMO What you've done is not really "model binding". In the sense that you've just read the id and fetched the object from the DB.
example of usual model binding:
if you post a form that contains the correct values (lets say you post a form with PropA and PropB ) the model binder can identify that you've sent those values in the form and build a SomeClass object.
If you really want to create a real working example you should use a strongly typed View and use HtmlHelper's EditorFor (or EditorForModel) to create all the correct names that MVC needs.
--
for reference MVC's default binder is the DefaultModelBinder, and some (there are more, you can look around in the System.Web.Mvc namespace) ValueProviders that it uses by default are the FormValueProvider and the QueryStringValueProvider
So, as I already said, how this basically works is that the default model binder reads the model that the action is recieving (say SomeClass in the example) reads what are the values that it can read (say PropA and PropB) and asks the ValueProviders for the correct values for the properties.
Also, if I recall correctly, you can also see the value providers in runtime using the ValueProviderFactories static class.
ModelBinder
查看所选Controller
操作方法签名的参数,然后将ValueProvider
中的值转换为这些参数。当
ControllerActionInvoker
调用与ControllerContext
关联的操作时会发生这种情况,因为Controller
的Execute()
方法告诉它。有关 ASP.NET MVC 执行过程的更多信息,请参阅了解 MVC 应用程序执行过程< /a>
A
ModelBinder
looks at the arguments of the selectedController
action's method signature, then converts the values from theValueProvider
s into those arguments.This happens when the
ControllerActionInvoker
invokes the action associated with theControllerContext
, because theController
'sExecute()
method told it to.For more about the ASP.NET MVC execution process, see Understanding the MVC Application Execution Process