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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了事实证明Ajax的世界更需要ASP.NET MVC相关的知识,希望对你有一定的参考价值。

参考技术A

  真正走进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

Asp.net MVC 中Ajax的使用


             Asp.net MVC 抛弃了Asp.net WebForm那种高度封装的控件,让我们跟底层的HTML有了更多的亲近。可以更自由、更灵活的去控制HTML的结构、样式和行为。而这点对于Ajax的应有来说,Asp.net MVC确实要比WebForm优秀很多。我对Asp.net MVC更便捷的使用Ajax做了一下探讨,拿出来分享,欢迎拍砖。

第一、直接写JS代码实现Ajax:

因为Asp.net 浏览器端的代码能更好的控制,所以我们完全可以在HTML中直接通过JS发出Ajax请求,而在Controller的action中返回XML或者Json,来实现Ajax效果,这种方法是最原始的方法,需要考虑浏览器和诸多问题,不推荐使用。

参考代码如下:

JS代码:

var xhr;
  function getXHR()
  
  try 
  xhr=new ActiveXObject("Msxml2.XMLHTTP");
   catch (e) 
  try 
  xhr=new ActiveXObject("Microsoft.XMLHTTP");
   catch (e) 
  xhr=false;
  
  
  if(!xhr&&typeof XMLHttpRequest!='undefined')
  
  xhr=new XMLHttpRequest();
  
  return xhr;
  
  function openXHR(method,url,callback)
  
  getXHR();
  xhr.open(method,url);
  xhr.onreadystatechange=function()
  
  if(xhr.readyState!=4)return;
  callback(xhr);
  
  xhr.send(null);
  
  function loadXML(method,url,callback)
  
  getXHR();
  xhr.open(method,url);
  xhr.setRequestHeader("Content-Type","text/xml");
  xhr.setRequestHeader("Content-Type","GBK");
  xhr.onreadystatechange=function()
  
  if(xhr.readyState!=4)return;
  callback(xhr);
  
  xhr.send(null);
  


后台代码:

public ActionResult GetNews(int CategoryID)
        
            NewsCollectionModel newsCollection = new NewsCollectionModel();
            …………
            JsonResult myJsonResult = new JsonResult();
            myJsonResult = newsCollection;
            return myJsonResult;
        


第二种:使用Jquery进行Ajax调用:

在VS 2010中,IDE全面支持Jquery的智能显示,在开发中使用Jq来实现JS效果非常的棒,而且可以节省很多精力和时间。所以在Ajax中使用JQuery进行开发,也是一种不错的方法。

大概的实现代码如下:

    <% using (Html.BeginForm("AddComment","Comment",FormMethod.Post,new @class="hijax"))  %>    
        <%= Html.TextArea("Comment", newrows=5, cols=50) %>
        <button type="submit">Add Comment</button>
             <span id="indicator" style="display:none"><img src="http://www.cnblogs.com/content/load.gif" alt="loading..." /></span>                                 
    <%  %>
    在View中引用Jquery:
    <script src="http://www.cnblogs.com/Scripts/jquery-1.4.1.min.js" type="text/javascript"></script>
    添加下面脚本:
    <script type="text/javascript">
        //execute when the DOM has been loaded
        $(document).ready(function () 
            //wire up to the form submit event
            $("form.hijax").submit(function (event) 
                event.preventDefault();  //prevent the actual form post
                hijack(this, update_sessions, "html");
            );
        );

        function hijack(form, callback, format) 
            $("#indicator").show();
            $.ajax(
                url: form.action,
                type: form.method,
                dataType: format,
                data: $(form).serialize(),
                completed: $("#indicator").hide(),
                success: callback
            );
        

        function update_sessions(result) 
            //clear the form
            $("form.hijax")[0].reset();
            $("#comments").append(result);
        
    
    </script>


第三种方法:使用微软自带的Ajax Helper框架来实现.

<% using (Ajax.BeginForm("AddComment", new AjaxOptions
                                            
                                                HttpMethod = "POST", 
                                                UpdateTargetId = "comments",
                                                InsertionMode = InsertionMode.InsertAfter                                                
                                            ))  %>
    
        <%= Html.TextArea("Comment", newrows=5, cols=50) %>
        <button type="submit">Add Comment</button>
                                            
    <%  %>


第二种和第三种方法在博客园有篇博客中有所讲解,我直接进行了引用,具体地址如下:http://www.cnblogs.com/zhuqil/archive/2010/07/18/1780285.html

主要是对Ajax helper记录下我自己的看法和注意的事项。

第一、Ajax Helper是微软提供的一种Ajax框架,为了使用Ajax Helper必须使用微软提供的两个Js框架:

 

<script src="http://www.cnblogs.com/Scripts/MicrosoftAjax.js" type="text/javascript"></script>
    <script src="http://www.cnblogs.com/Scripts/MicrosoftMvcAjax.js" type="text/javascript"></script>

第二、Ajax Helper有几个用法

 

 Ajax.ActionLink():它将渲染成一个超链接的标签,类似于Html.ActionLink()。当它被点击之后,将获取新的内容并将它插入到HTML页面中。

Ajax.BeginForm():它将渲染成一个HTML的Form表单,类似于Html.BeginForm()。当它提交之后,将获取新的内容并将它插入到HTML页面中。

Ajax.RouteLink():Ajax.RouteLink()类似于Ajax.ActionLink()。不过它可以根据任意的routing参数生成URL,不必包含调用的action。使用最多的场景是自定义的IController,里面没有action。

Ajax.BeginRouteForm():同样Ajax.BeginRouteForm()类似于Ajax.BeginForm()。这个Ajax等同于Html.RouteLink()。

而每个方法里面的参数会有所不同,具体的用法见:http://msdn.microsoft.com/zh-cn/library/system.web.mvc.ajaxhelper_methods(v=VS.98).aspx

其中一个重要的参数为:AjaxOption,存在有以下几个属性,主要是来规定Ajax的行为的。


 名称描述
Confirm获取或设置提交请求之前,显示在确认窗口中的消息。
HttpMethod获取或设置 HTTP 请求方法(“Get”或“Post”)。
InsertionMode获取或设置指定如何将响应插入目标 DOM 元素的模式。
LoadingElementDuration获取或设置一个值(以毫秒为单位),该值控制显示或隐藏加载元素时的动画持续时间。
LoadingElementId获取或设置加载 Ajax 函数时要显示的 HTML 元素的 id 特性。
OnBegin获取或设置更新页面之前,恰好调用的 JavaScript 函数的名称。
OnComplete获取或设置实例化响应数据之后但更新页面之前,要调用的 JavaScript 函数。
OnFailure获取或设置页面更新失败时,要调用的 JavaScript 函数。
OnSuccess获取或设置成功更新页面之后,要调用的 JavaScript 函数。
UpdateTargetId获取或设置要使用服务器响应来更新的 DOM 元素的 ID。
Url获取或设置要向其发送请求的 URL。

 

 

以上是关于事实证明Ajax的世界更需要ASP.NET MVC的主要内容,如果未能解决你的问题,请参考以下文章

asp.net mvc 4控制器并行执行多个ajax调用

ASP.NET MVC 中的 ASP.NET AJAX 与 jQuery

ASP.NET MVC AJAX日历

关于Asp.net mvc的诡异问题

如何摆脱 ASP.Net MVC 中的 Home?

ASP.Net MVC、AJAX 和渐进增强