ASP.NET MVC案例教程(基于ASP.NET MVC beta)——第五篇:MVC整合Ajax


======================================================
注:本文源代码点此下载
======================================================

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 计算机绝版图书按需印刷服务


======================================================
在最后,我邀请大家参加新浪APP,就是新浪免费送大家的一个空间,支持PHP+MySql,免费二级域名,免费域名绑定 这个是我邀请的地址,您通过这个链接注册即为我的好友,并获赠云豆500个,价值5元哦!短网址是http://t.cn/SXOiLh我创建的小站每天访客已经达到2000+了,每天挂广告赚50+元哦,呵呵,饭钱不愁了,\(^o^)/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值