asp.net mvc案例教程(基于asp.net mvc beta)——第五篇:mvc整合ajax
2008-11-03 22:48
by
t2噬菌体,
29499
visits,
收藏,
编辑
摘要
本文将从完成“输入数据验证”这个功能出发,逐渐展开asp.net mvc与ajax结合的方法。首先,本文将使用asp.net mvc提供的同步方式完成数据验证。而后,将分别结合asp.net ajax和jquery将这个功能重构成异步形式。
数据验证
在上一篇文章中,我们完成了发布公告的功能。但是从健壮性角度看,这个功能并不完善,因为一般情况下,我们输入的数据要符合一定的约束条件,例如,在我们的例子中,我们至少不能将空字符串作为标题或内容吧。下面,我们来为程序加入数据验证功能,
asp.net mvc中提供了良好的数据验证实现支持,下面我们来看实现过程。首先,我们要修改一下release.aspx视图,修改后的视图如下。
release.aspx:
1@ page language="c#" autoeventwireup="true" codebehind="release.aspx.cs" inherits="mvcdemo.views.announce.release" %>
2@ import namespace="mvcdemo.models.entities" %>
3
4doctype html public "-//w3c//dtd xhtml 1.0 transitional//en"
"http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd"]]>
>
5
6html xmlns="http://www.w3.org/1999/xhtml" >
7head runat="server">
8title>title>
9head>
10body>
11 selectlist categories = viewdata["categories"] as selectlist; %>
12div>
13h1>mvc公告发布系统——发布公告h1>
14 html.beginform("dorelease","announce",formmethod.post); %>
15dl>
16dt>标题:dt>
17dd>= html.textbox("title") %>dd>
18dd>= html.validationmessage("titlevalidator") %>dd>
19dt>分类:dt>
20dd>= html.dropdownlist("category",categories) %>dd>
21dd>dd>
22dt>内容:dt>
23dd>= html.textarea("content") %>dd>
24dd>= html.validationmessage("contentvalidator") %>dd>
25dl>
26input type="submit" value="发布" />
27 html.endform(); %>
28div>
29body>
30html>
可以看到,并没有什么大的变动,只是多了两个html.validationmessage方法。可以这样理解,这个方法相当于产生一个span标签,而这个span就是要显示错误信息的地方。这个方法接收一个参数,用来指明其在controller中的名字。如果你对这个迷惑,不要紧,接下来看完controller的代码,你就什么都清楚了。
announcecontroller.cs:
1using system;
2using system.collections.generic;
3using system.linq;
4using system.web;
5using system.web.mvc;
6using system.web.mvc.ajax;
7using mvcdemo.models;
8using mvcdemo.models.interfaces;
9using mvcdemo.models.entities;
10
11namespace mvcdemo.controllers
12{
13public class announcecontroller : controller
14{
15public actionresult release()
16{
17icategoryservice cserv = servicebuilder.buildcategoryservice();
18listcategoryinfo> categories = cserv.getall();
19viewdata["categories"] = new selectlist(categories, "id", "name");
20return view("release");
21}
22
23public actionresult dorelease()
24{
25if (string.isnullorempty(request.form["title"]) || string.isnullorempty(request.form["content"]))
26{
27if (string.isnullorempty(request.form["title"]))
28{
29viewdata.modelstate.addmodelerror("titlevalidator","公告标题不能为空!");
30}
31if (string.isnullorempty(request.form["content"]))
32{
33viewdata.modelstate.addmodelerror("contentvalidator", "公告内容不能为空!");
34}
35
36return release();
37}
38
39announceinfo announce = new announceinfo()
40{
41id = 1,
42title = request.form["title"],
43category = int32.parse(request.form["category"]),
44content = request.form["content"],
45};
46
47iannounceservice aserv = servicebuilder.buildannounceservice();
48aserv.release(announce);
49
50viewdata["announce"] = announce;
51return view("releasesucceed");
52}
53}
54}
可以看到,我们的dorelease这个action方法多了不少东西。我们看多了什么:当从表单传递过来的标题或内容为空时,我们做了一定处理。注意,这个viewdata.modelstate.addmodelerror方法,它就是往我们刚才说的由html.validationmessage生成的span里加入错误信息的方法,它可以有两个参数,第一个指明哪个span,这个参数html.validationmessage中的参数是对应的。第二个参数就是要显示的信息。
相信结合视图和控制器,已经很好理解了。最后,如果标题或内容有空值的话,我们不再调用业务逻辑组件处理了,而是调用了release这个action。为什么我们不用redirect呢?因为我们要保持viewdata中的数据,刚才我们的错误信息可都放在里面的,而使用了redirect,viewdata的信息就传不过去了。
现在,我们再来发布公告。我们故意什么都不填,提交,看结果:
没有问题,我们的程序成功对标题和内容进行了完整性检测(这里就是均不能为空),在验证不通过时,返回了发布公告视图并正确显示了错误提示信息。
也许你有一个疑问,为什么第一次请求release视图时没有显示任何错误信息呢?因为那时viewdata中的modelerror是空的。而html.validationmessage生成的标签会自动寻找modelerror中同名的错误信息,找不到,当然是空的了。而在提交空信息时,dorelease这个action为viewdata的modelerror添加了内容,于是当再次返回release视图时,相应信息就显示在我们指定的位置了。
使用asp.net ajax实现客户端数据验证
上面的代码运行起来没问题,也达到了我们的要求。但是验证标题内容是否为空这种行为在客户端应该就可以完成。当然,为了放置恶意攻击或浏览器将javascript屏蔽的情况,我们应该在后台进行验证,但是我们不能每次都将这种请求发到后台去验证,这太费资源了,毕竟恶意攻击者和javascript被屏蔽的浏览器只是少数。所以,在数据被送到后台前,我们应该先进行一遍验证,这样可以节约很多资源。
下面,我们使用asp.net ajax框架完成客户端的数据验证。
说实话,在asp.net mvc中使用asp.net ajax或jquery实在太方便了,不信你展开scripts文件夹,看到没,微软已经把这些库放到里面了,所以,我们要做的只是直接引用。看我们修改后的release.aspx。
release.aspx:
1@ page language="c#" autoeventwireup="true" codebehind="release.aspx.cs" inherits="mvcdemo.views.announce.release" %>
2@ import namespace="mvcdemo.models.entities" %>
3
4doctype html public "-//w3c//dtd xhtml 1.0 transitional//en" "http://www.w3.org/tr/xhtml1/dtd/xhtml1-transitional.dtd">
5
6html xmlns="http://www.w3.org/1999/xhtml" >
7head runat="server">
8title>title>
9script type="text/javascript" src="~/scripts/microsoftajax.debug.js") %>
">
10
标签: asp.net, mvc, asp.net mvc, 例子, 案例, net
绿色通道:好文要顶关注我收藏该文与我联系
categories:
[03]asp.net mvc
tags:
asp.net, mvc, asp.net mvc, 例子, 案例, net
add your comment
58 条回复
2201557
#1楼 astar 2008-11-03 23:00
回复 引用 查看
#2楼 小狼壮壮 2008-11-03 23:33
好文,拜读。
感谢楼主,好老师。
回复 引用 查看
#3楼 有容乃大 2008-11-04 09:39
这个验证(html.validationmessage)不能在客户端触发吧。感觉asp.net mvc比传统的asp.net麻烦不少,就以验证来说,传统方式只需拉一个验证控件(输入正则式)就能完成客户端和服务器端的双重验证,而这里这种验证方式真有些恶心。
本人一直关注asp.net mvc,看了不少文章,也不知道是到底对这种模式感兴趣还是在找一个让自己喜欢asp.net mvc的理由,困惑中,望大家指点!
-----------------------------------------
http://www.cnblogs.com/mrhgw/archive/2008/10/09/1307247.html
回复 引用 查看
#4楼 ohsam[未注册用户]2008-11-04 10:22
没有看到ajax的应用啊 ??
回复 引用
#5楼 cat chen 2008-11-04 10:41
封装为一个mvc的helper函数啊,这才符合mvc思维方式,rails就是这样做的。你现在相当于把jquery从mvc那里割裂开来用。
回复 引用 查看
#6楼 erererererer[未注册用户]2008-11-04 12:56
感觉没多大用途,,这种入门的文章实在是...
多弄些原理性的文章才有意思哦。
回复 引用
#7楼 龙龙ago[未注册用户]2008-11-04 16:19
服务器验证非空的这个地方,无法保持上一次的表单状态,要再做些处理,相对webform麻烦了些
正确得控制器这边代码要多两个东西
public actionresult dorelease()
{
if (string.isnullorempty(request.form["title"]) || string.isnullorempty(request.form["content"]))
{
if (string.isnullorempty(request.form["title"]))
{
viewdata.modelstate.addmodelerror("titlevalidator", "公告标题不能为空!");
}
else
{
viewdata["title"] = request.form["title"].tostring();
}
if (string.isnullorempty(request.form["content"]))
{
viewdata.modelstate.addmodelerror("contentvalidator", "公告内容不能为空!");
}
else
{
viewdata["content"] = request.form["content"].tostring();
}
return release();
}
在release.aspx这边要
mvc公告发布系统——发布公告
标题:
分类:
内容:
这样才能保持好上次的表单状态
回复 引用
#8楼[楼主] t2噬菌体 2008-11-04 19:42
@龙龙ago
原来如此。学习了!谢谢!
回复 引用 查看
#9楼[楼主] t2噬菌体 2008-11-04 19:44
@ohsam
其实在本文中我们并没有使用到ajax,而仅仅是整合了javascirpt,但是这已经足够了,因为ajax无非就是在这些javascript里包含了异步后台调用。
回复 引用 查看
#10楼[楼主] t2噬菌体 2008-11-04 19:46
@cat chen
我也是这么想的,不过后来发现这样做有些困难,似乎为了符合mvc付出的代价太大了。所以目前我还是使用分割开javascript的方式。不过微软目前正在封装这部分,目前版本中的ajaxhelper还不够强大。希望在正式版中可以看到功能强大的ajaxhelper
回复 引用 查看
#11楼 microbar2[未注册用户]2009-01-22 14:55
求救:怎么弄都运行不了!
未能从程序集“system.web.routing, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35”中加载类型“system.web.routing.stoproutinghandler”。
说明: 执行当前 web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。
异常详细信息: system.typeloadexception: 未能从程序集“system.web.routing, version=3.5.0.0, culture=neutral, publickeytoken=31bf3856ad364e35”中加载类型“system.web.routing.stoproutinghandler”。
源错误:
行 15:public static void registerroutes(routecollection routes)
行 16:{
行 17:routes.ignoreroute("{resource}.axd/{*pathinfo}");
行 18:
行 19:routes.maproute(
源文件: e:\project\2008\mvc\mvcdemo\mvcdemo\global.asax.cs行: 17
回复 引用
#12楼[楼主] t2噬菌体 2009-01-24 21:20
@microbar2
你有没有安装asp.net mvc扩展包?
回复 引用 查看
#13楼 飞飞双双 2009-02-09 16:48
@有容乃大
在实际开发中考虑到页面布局和用户体验 验证表单一般都是用js,如果需要读取服务器数据进行验证则使用webservice或ajax
个人感觉在webforms下使用ajax比较费劲(用其它轻量级的js框架或者自己写),原因在于不可避免的要使用服务器控件,而服务器控件的id在客户端将发生变化!
mvc抛弃服务器控件,抛弃页面生存周期,抛弃事件驱动,看似费力,却更加触及web底层。架构设计时更容易实现低耦合,高聚合的原则,希望微软可以陆续提供更多的helper,相信可以吸引到更多的web程序员
回复 引用 查看
#14楼 青格儿[未注册用户]2009-02-24 11:48
asp.net mvc扩展包?这个是什么?我装了rc
那还用不用装asp.net mvc扩展包?
回复 引用
#15楼[楼主] t2噬菌体 2009-02-24 12:48
@青格儿
你装了asp.net mvc rc就可以了^_^
回复 引用 查看
#16楼 sunk 2009-03-31 00:52
一个疑问dorelease()的开始部分,判断为空为什么要进行两次判断呢?
回复 引用 查看
#17楼[楼主] t2噬菌体 2009-03-31 15:05
@sunk
外层的判断,是决定是否进入错误处理逻辑。内层的判断,是细化判断到底是title为空还是content为空。
回复 引用 查看
#18楼 shuihanyu2009-04-22 10:31
楼主,我发现一个问题呀,就是你第一次什么都不填,故意让它显示不能为空的消息,然后,再填写内容,点提交的时候,没有反应。
小菜鸟请问有什么解决办法吗?
回复 引用
#19楼 john liu 2009-05-10 22:22
@有容乃大
兄弟,就会拉控件的方式才是恶心呢。如果你对某一文本框要多个验证,同时要求,不为空,符合某一正则表达式,甚至再要求ajax方式验证。验证控件就很难完成任务。而且,如果页面上的表单元素比较多,而每个元素要需要不止一个验证,那你的页面需要多少验证控件。
回复 引用 查看
#20楼 john liu 2009-05-10 22:26
楼主的jquery水平有待提高啊,取value值直接用$("#title").val()就可以了啊。赋值直接用$("#titlevalidator").html("标题不能为空!")就可以了吧。
回复 引用 查看
#21楼 lvhejin[未注册用户]2009-05-12 15:16
顶一下
回复 引用
#22楼[楼主] t2噬菌体 2009-05-12 18:31
@john liu
呵呵,我不怎么会jquery,没大用过。
回复 引用 查看
#23楼 assuka[未注册用户]2009-05-22 11:29
照着你的列子写,到“使用asp.net ajax实现客户端数据验证”
这步的时候,调试出现问题
microsoftajax.debug.js中2935行
microsoft jscript 运行时错误: sys.argumentnullexception: value cannot be null.
parameter name: element
不知道是为什么。
回复 引用
#24楼 assuka[未注册用户]2009-05-22 14:49
@assuka
帮助楼主回答我自己。
因为在>的release页面里面
上没有id = "submit"。
所以到本篇的时候,我沿用了上一次的页面,修改时候没有加上id属性,导致调试失败。
回复 引用
#25楼 husteric[未注册用户]2009-06-11 13:28
谢谢博主,受益匪浅啊,是asp.net mvc的入门好教程
回复 引用
#26楼 寻影追梦 2009-07-01 14:10
支持,经常光顾
回复 引用 查看
#27楼 用爱用心追梦 2009-07-13 13:53
我来了!!!
回复 引用 查看
#28楼 kevin.zeng[未注册用户]2009-08-27 11:30
@龙龙ago
貌似也不能保存~试过了还是空的~不知道为什么!
回复 引用
#29楼 随风178 2009-09-23 19:04
看不懂的东西好
回复 引用 查看
#30楼 邀月 2009-10-15 13:14
不错!
回复 引用 查看
#31楼 ( ⊙ o ⊙ )[未注册用户]2009-11-05 10:53
这个jquery写的那么麻烦,不是有更简单的写法吗
回复 引用
#32楼 321111123333[未注册用户]2009-11-11 17:33
这个算ajax?????
回复 引用
#33楼[楼主] ericzhang(t2噬菌体) 2009-11-11 19:56
引用321111123333:这个算ajax?????
请注意文章中的一句话:“其实在本文中我们并没有使用到ajax,而仅仅是整合了javascirpt,但是这已经足够了,因为ajax无非就是在这些javascript里包含了异步后台调用。
”
回复 引用 查看
#34楼 cmj[未注册用户]2009-11-20 11:02
修改一下文章题目吧,确实没有用ajax,仅仅就是客户端的简单javascript验证,题目有点误导。
回复 引用
#35楼 bdnet 2009-12-03 16:39
是用博主的microsoftajax验证方式在ie下通过
但在firefox下测试,验证没通过也被提交了
firefox版本3.5.5
回复 引用 查看
#36楼 莫慌 2009-12-05 16:40
引用飞飞双双:@有容乃大
在实际开发中考虑到页面布局和用户体验 验证表单一般都是用js,如果需要读取服务器数据进行验证则使用webservice或ajax
个人感觉在webforms下使用ajax比较费劲(用其它轻量级的js框架或者自己写),原因在于不可避免的要使用服务器控件,而服务器控件的id在客户端将发生变化!
mvc抛弃服务器控件,抛弃页面生存周期,抛弃事件驱动,看似费力,却更加触及web底层。架构设计时更容易实现低耦合,高聚合的原则,希望微软可以陆续提供更多的helper,相信可以吸引到更多的web程序员
抛弃服务器控件未必就是好事。在这个例子中,为了在提交到服务器端验证且通不过时保存原来的状态,需要查询数据库(release(),得到categroys),这就增加了数据库的查询次数,而webform的服务器控件就不会有这个问题,除非这里完全用ajax。
回复 引用 查看
#37楼 itliyi 2009-12-08 21:34
请教楼主我不输入怎么都提交过去了?
服务端是 客户端也是
回复 引用 查看
#38楼 廖勇军 2009-12-23 10:46
没看到ajax啊
回复 引用 查看
#39楼 aisoon99 2010-01-04 16:08
"为什么我们不用redirect呢?因为我们要保持viewdata中的数据,刚才我们的错误信息可都放在里面的,而使用了redirect,viewdata的信息就传不过去了"-----好像使用tempdata就能保存一次数据到新的页面
回复 引用 查看
#40楼 进步的小菜 2010-04-16 15:17
学习了,感谢楼主
回复 引用 查看
#41楼 飞碟工作室 2010-05-26 15:53
教程还可以..
入门的好文章..
回复 引用 查看
#42楼 新猪猪 2010-06-21 16:46
楼主的jquery可以再简化一点,呵呵。
if($("#title").val() == "") {
$("#titlevalidator").html("标题不能为空!");
}
回复 引用 查看
#43楼 青山yoyo 2010-08-30 17:38
学习
回复 引用 查看
#44楼 牧马 2010-11-02 19:51
客户端验证弄不出来,我用的是mvc2,有影响吗?
回复 引用 查看
#45楼 staid 2010-11-26 17:30
jquery验证里面的
$("#submit").click
应该是 $("#按钮id").click,其他的挺好的。
希望继续把该系列写下去
回复 引用 查看
#46楼 stone1314 2011-03-28 23:25
学习~
回复 引用 查看
#47楼 ^懒洋洋^ 2011-05-13 15:57
刷新评论列表刷新页面返回页首
发表评论
昵称: [登录]
[注册]
主页:
邮箱:(仅博主可见)
验证码:看不清。
换一个
评论内容:
记住我的昵称和主页
-->
登录注册
[使用ctrl+enter键快速提交评论]
0
1325840
enbvet3uilm=
首页博问闪存新闻园子招聘知识库
最新it新闻:
·android平台12月广告浏览份额51.6% 超越ios
·测试版ios源代码显示ipad 3或将支持siri
·斯蒂芬·霍金的新电脑
·京东商城2.95亿竞得北京商业地一块
·美报业巨头合作facebook谷歌 传媒重视网络网络
» 更多新闻...
最新知识库文章:
·javascript 面向对象编程
·持续集成之“everything is code”
·持续集成之“软件自我识别”
·持续集成之戏说check-in dance
·什么是闭包。
我的理解
» 更多知识库文章...
china-pub 2011秋季教材巡展
china-pub 计算机绝版图书按需印刷服务