事实证明Ajax的世界更需要ASP.NET MVC

 我来答
黑科技1718
2022-11-16 · TA获得超过5872个赞
知道小有建树答主
回答量:433
采纳率:97%
帮助的人:81.7万
展开全部

  真正走进ASP NET MVC的世界 才知道它的精彩

   抛弃WebService 在 NET 中用 jQuery 调用 WCF ——原来抛弃WebService之后 还可以用jQuery调用ASP NET MVC的Controller

   Ajax为主的应用不需要ASP NET MVC 原来Ajax的世界更需要ASP NET MVC

  曾经天真的想法 在实践中证明了它的天真 但在从天真到事实的过程中 得到的是成长

  下面就谈谈我是如何认识到这个的 相比于结论 其中旦液的过程更重要

  还是以之前文章中的博客园站内短消息功能(显示当前用户短消息列表)为例 开始用的是jQuery插件Templates进行列表数据绑定 后来遇到了两个问题

   ) 在绑定时需要根据条件判断生成不同的元素 比如用户发过来的短消息 发件人显示为链接 如果是系统通知 则显示为文本 Templates对这样的操作处理起来不是很方便

   ) 绑定后的数据无法在服务端重用 有时从搜索引擎友好或者用户体验的角度 在页面第一次加载时 不用ajax 在页面加载后点击刷新或分页链接时 才使用ajax 这样就要在服务端与客户端分别维护数据瞎源绑定操作

  也就是说原来服务端返回的是实体类对象列表 现在要返回的是将数据与Html组装起来的字符串

   开始我们考虑的是一种丑陋的方法 用StringBuilder进行字符串拼接生成数据绑定结果 服务器端WCF服务中的代码如下

  

  显然这种方法易出错 维护性差

   接着我们考虑了第二种方法(参考自Render User Control as String Template) 通过Web User Control生成字符串 WCF服务中的代码如下

   <!--

Code highlighting produced by Actipro CodeHighlighter (freeware)


--> Page page = new Page();Control control = page LoadControl( ~/Controls/MsgListControl ascx );((IRenderable<List<SiteMsg>>)control) PopulateData(siteMsgList); StringBuilder *** = new StringBuilder();using (StringWriter sw = new StringWriter( *** )){ using (HtmlTextWriter h = new HtmlTextWriter(sw)) { control RenderControl(h); return *** ToString(); }}

  由于MsgListControl ascx的类型是动态编译生成的 所以无法通过强制类型转换将control转换为MsgListControl类型 然后传递数据给它

  这里需要通过一个另外的IRenderable<T>接口来实现数据的绑定 MsgListControl实现了这个接口模神物 代码如下

   <!--

Code highlighting produced by Actipro CodeHighlighter (freeware)


--> public partial class MsgListControl : UserControl IRenderable<List<SiteMsg>>{ public void PopulateData(List<SiteMsg> siteMsgList) { rptMsgList DataSource = siteMsgList; rptMsgList DataBind(); }}public interface IRenderable<T>{ void PopulateData(T data);}

  在WCF服务中通过调用接口中的PopulateData方法进行数据的绑定

  这个方法增加了额外的接口 显得有些复杂

   后来我们想到了ASP NET MVC 虽然不熟悉 但要尝试一下 看能否更好地解决这个问题

  于是 上ASP NET MVC 用Razor 咱们也MVC一把

   应用场景 在现有的VS Web Site项目中应用ASP NET MVC MsgController收到请求后 由Inbox(一个Action)将包含短消息列表的整个页面视图返回给客户端 当用户点击页面的刷新或者分页链接时 通过Ajax发起POST请求以获取短消息列表 MsgController收到请求后 由List(一个Action)将短消息列表的视图返回给客户端

   期望的效果 短消息列表视图能重用 Inbox与List使用的是同一个视图

  一开始遇到了两个小问题

  a) MapRoute配置之后 访问出现 HTTP Error Not Found 错误 原因是访问的网址没有文件名 未走ASP NET管线 解决方法是在nfig的system webServer中加上以下的配置

   <!--

Code highlighting produced by Actipro CodeHighlighter (freeware)


--> <validation validateIntegratedModeConfiguration= false /><modules runAllManagedModulesForAllRequests= true /> 

  b) 继续访问 出现 The resource cannot be found 错误 解决方法 由于用的是Web Site项目 要将Controllers文件夹移至App_Code

  然后进入MVC相关代码编写 先从Ajax调用部分开始

  Controller的代码如下

   <!--

Code highlighting produced by Actipro CodeHighlighter (freeware)


--> public class MsgController : Controller{ [HttpPost] public ActionResult List(SiteMsgQuery msgQuery) { List<SiteMsg> siteMsgList = GetInboxMsgList(msgQuery); return View( MsgList siteMsgList); }}

  需要注意的就一个地方 [HttpPost] 既然是Ajax调用 当然要响应POST请求

  View的代码(MsgList cs)如下

   <!--

Code highlighting produced by Actipro CodeHighlighter (freeware)


--> @using CNBlogs UcHome ExternalService MsgWcfService@model List<SiteMsg> @foreach(SiteMsg msg in Model){ <div class= msg_item > <div class= msg_sender >@msg SenderName</div> <div class= msg_title ><a /msg/item/@msg id/ >@msg Subject</a></div> <div class= msg_sendtime >@msg SendTime ToString( yyyy MM dd HH:mm )</div> </div>}

  比在 ascx中写起来方便多了

  客户端js调用代码如下

   <!--

Code highlighting produced by Actipro CodeHighlighter (freeware)


--> function GetMsgList(pageIndex pageSize) { var msgQuery = {} msgQuery PageIndex = pageIndex; msgQuery PageSize = pageSize; $ ajaxSettings dataType = plain/text ;//不要用json $ ajaxSettings url = /msg/list ; $ ajaxSettings data = { msgQuery : + JSON stringify(msgQuery) + } ; $ ajaxSettings success = function (data) { $( #msg_list l(data); }; $ ajax();}

  需要注意的是两个地方(因为服务器端Controller返回的不是json格式的数据)

  a) dataType不要用json 用jQuery默认的就行 如果指定的话 就用plain/text

  b) 返回数据就在data中 不要通过data d获取

  这样 用ASP NET MVC就轻松搞定Ajax调用 比之前的WCF StringBuider ascx都要方便

  原来在ASP NET MVC中使用Ajax如此方便 完全可以取代以前用的WCF中转站

  解决了Ajax的问题 接着处理整个页面的显示

  在页面的View中直接重用刚才Ajax所用的View就行了 示例代码如下

  View(Inbox cs)

   <!--

Code highlighting produced by Actipro CodeHighlighter (freeware)


--> <!DOCTYPE ><> <head> <title></title> </head> <body> @Html Partial( MsgList ) </body></>

  Control

   <!--

Code highlighting produced by Actipro CodeHighlighter (freeware)


--> public class MsgController : Controller{ public ActionResult Inbox() { SiteMsgQuery msgQuery = new SiteMsgQuery() { PageIndex = PageSize = }; List<SiteMsg> siteMsgList = GetInboxMsgList(msgQuery); return View( Inbox siteMsgList); } }

lishixinzhi/Article/program/net/201311/13877

已赞过 已踩过<
你对这个回答的评价是?
评论 收起
推荐律师服务: 若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询

为你推荐:

下载百度知道APP,抢鲜体验
使用百度知道APP,立即抢鲜体验。你的手机镜头里或许有别人想知道的答案。
扫描二维码下载
×

类别

我们会通过消息、邮箱等方式尽快将举报结果通知您。

说明

0/200

提交
取消

辅 助

模 式