Asp.net MVC: BindingHelperExtension的UpdateFrom如何使用?

来源:互联网 发布:外贸邮箱抓取软件 编辑:程序博客网 时间:2024/05/15 04:37

预备知识:扩展方法(Extension Method);Asp.net MVC

一般的做法

以修改一篇blog为例,当我们再输入框中输入了修改的内容之后,通过点击提交按钮将新的blog内容提交到服务器端,如图所示,我们可以修改blog的title,body和timestamp三项:

 image

图 1

我们可能写出这样的代码:

[ControllerAction]public void Save(int id){      BlogDataContext dbBlog = new BlogDataContext();    Post post = dbBlog.Posts.Single(p => p.ID == id);
    post.Body = Request.Form["Body"];    post.Title = Request.Form["Title"];    post.Timestamp = DateTime.Parse(Request.Form["Timestamp"]);    dbBlog.SubmitChanges();    RedirectToAction(new { action = "Detail", id = post.ID });   }
 

这段代码显示了controller从view的Request中读取内容,然后更新model。在新的Asp.net模型中,view的内容都放在Request.Form对象中,该对象是一个HttpValueCollection集合。

image

图 2

仔细看它里面存储的值,实际上就是我们在以前看到的Request.QueryString,只是现在我们不用在Url中显示地用?来写出,而是由Asp.net MVC框架帮我们生成,它会自动读取我们在form中定义的有些元素及其中所包含的内容。下面是一个form的例子,红色标注的地方可以先忽略:

image

图 3

BindingHelperExtension.UpdateFrom让更新变得更加容易

回到更新blog内容的问题上来,下面的代码可以完成更新任务:

post.Body = Request.Form["Body"]; 
post.Title = Request.Form["Title"]; 
post.Timestamp = DateTime.Parse(Request.Form["Timestamp"]);

但是这样一个属性一个属性地修改Model的值很繁琐,而且中间涉及到类型转换。比如上面的DateTime类型的属性Timestamp,严格的说我们应该在更新它的值之前坐类型判断,空值判断等等操作。当属性超过10个甚至更多时,更新属性的代码加上类型转换,错误处理等等,代码的数量就比较打了。那么有没有更加简便的做法呢?实际上在MvcToolkit.dll这个程序集中为我们提供了一个简化操作的类,它就是UrlHelper,是一个扩展方法,可以附加到任何的Object类型的对象上

image

图 4

添加对MvcToolkit.dll的引用,并引入名字空间

using System.Web.Mvc.BindingHelpers;

之后我们就可以使用BindingHelpExtension类了。

[ControllerAction]public void Save(int id){      BlogDataContext dbBlog = new BlogDataContext();    Post post = dbBlog.Posts.Single(p => p.ID == id);
post.UpdateFrom(Request.Form); //post.Body = Request.Form["Body"]; //post.Title = Request.Form["Title"]; //post.Timestamp = DateTime.Parse(Request.Form["Timestamp"]); dbBlog.SubmitChanges(); RedirectToAction(new { action = "Detail", id = post.ID }); }

这样修改一个对象的属性是不是很简单呢?毫无疑问,而且这样还带来了另外一个好处,如果这个时候Post的属性变了(属性名或属性个数),我们不需要修改Controller的代码,需要修改的只是View部分

使用UpdateFrom的前提

UpdateFrom固然很好用,可是需要配合Form的Action来完成,而且它对于view中元素的定义有一定的要求。

  • Url.Action

先来看看Action。我们为Form添加Action,注意method属性是post的,因为是提交给服务器。

<form action="<%= Url.Action(new {action="Save",id=ViewData.ID}) %>method="post">

这里action的语法有一点怪异,实际上它生成后的Url是这样的:

<form action="/MVCStudy/Blog/Save/10"  method="post"> 

这里的Url实际上ViewPage的一个属性,而该属性又是UrlHelper的一个实例,所以这里的Url.Action实际上System.Web.Mvc.UrlHelper类的方法Action,该类存在于System.Web.Extension.dll程序集中。

image

图 5

至于Url.Action方法生成Url的原理,可以参考Scott的文章“ASP.NET MVC Framework's Routing Engine”

  • HtmlName——指定HtmlName,updatefrom才能生效。

这里的HtmlName是指在使用HtmlHelper类来生成html元素时所需要指定的相应的html元素的名字:

image

图 6

比如:

image

图 7

这里虽然生成id和name两个属性,但是Asp.net MVC使用的"name"。生成这一元素的代码:

        <p class="body">            <%--<%=Html.TextArea("bodyOfBlog",ViewData.Body) %>--%>            <%=Html.TextArea("Body",ViewData.Body) %>                    </p>

注意这里HtmlName一定要与对应的model的属性名一致,否则无法完成更新。上述代码中注释掉的代码行就是这样一个例子。正确的HtmlName设定,请参考本文图3。

总结

使用UpdateFrom可以为我们带来很多便利,例如类型转换、空值检查之类,同时它也使得代码更加容易维护,因为在controller中不需要理会model的具体的属性,充分发挥了Data Banding的作用。让框架为我们做更多的事,那么我们就可以更省事。

如果你的UpdateFrom不起作用,那么首先应该检查一下Form的action以及HtmlName的设定是否正确.


引用通告
此日志的引用通告 URL 是:
http://raderdotnet.spaces.live.com/blog/cns!3461738A506327E!542.trak
引用此项的网络日志

原创粉丝点击