ASP.NET MVC 实现 AJAX 跨域请求

来源:互联网 发布:电脑网络参数怎么设置 编辑:程序博客网 时间:2024/06/05 06:38
ActionResult是控制器方法执行后返回的结果类型,控制器方法可以返回一个直接或间接从ActionResult抽象类继承的类型,如果返回的是非ActionResult类型,控制器将会将结果转换为一个ContentResult类型。默认的ControllerActionInvoker调用ActionResult.ExecuteResult方法生成应答结果。

    MVC中实现的默认ActionResult如下:

ActionResult

1、ContentResult: 返回简单的纯文本内容,可通过ContentType属性指定应答文档类型,通过ContentEncoding属性指定应答文档的字符编码。可通过Controller类中的Content方法便捷地返回ContentResult对象。如果控制器方法返回非ActionResult对象,MVC将简单地以返回对象的ToString()内容为基础产生一个ContentResult对象。
2、EmptyResult: 返回一个空的结果。如果控制器方法返回一个null,MVC将其转换成EmptyResult对象。
3、RedirectResult: 表示一个连接跳转,相当于ASP.NET中的Response.Redirect方法。对应的Controller方法为Redirect。
4、RedirectToRouteResult:同样表示一个调转,MVC会根据我们指定的路由名称或路由信息(RouteValueDictionary)来生成Url地址,然后调用Response.Redirect跳转。对应的Controller方法为RedirectToAction和RedirectToRoute。
5、ViewResult: 表示一个视图结果,它根据视图模板产生应答内容。对应Controller方法为View。
6、PartialViewResult: 表示一个部分视图结果,与ViewResult本质上一致,只是部分视图不支持母版,对应于ASP.Net,ViewResult相当于一个Page,而PartialViewResult则相当于一个UserControl。它对应的Controller方法为PartialView。
7、HttpUnauthorizedResult: 表示一个未经授权访问的错误。MVC会向客户端发送一个401的应答状态。如果在web.config中开启了表单验证(authentication mode="Forms"),则401状态会将Url转向指定的loginUrl链接。
8、JavaScriptResult: 本质上是一个文本内容,只是将Response.ContentType设置为 application/x-JavaScript,此结果应该和MicrosoftMvcAjax.js脚本配合使用,客户端接收到Ajax应答后,将判断Response.ContentType的值,如果是application/x-javascript,则直接eval执行返回的应答内容。此结果类型对应的Controller方法为JavaScript。
9、JsonResult: 表示一个JSON结果。MVC将Response.ContentType设置为application/json,并通过JavaScriptSerializer类将指定对象序列化为Json表示方式。需要注意,默认情况下,MVC不允许GET请求返回JSON结果,要解除此限制,在生成JsonResult对象时,将其JsonRequestBehavior属性设置为JsonRequestBehavior.AllowGet。此结果对应的Controller方法为Json。
10、FilePathResult、FileContentResult、FileStreamResult: 这三个类继承于FileResult,表示一个文件内容,三者的区别在于,FilePath通过路径传送文件到客户端,FileContent通过二进制数据的方式,而FileStream是通过Stream的方式来传送。Controller为这三个文件结果类型提供了一个名为File的重载方法。

        通过直接或间接地从ActionResult继承,可实现自定义的结果类型,下例将实现一个XmlResult类型,用于返回XML应答内容:

1、创建一个空的MVC项目

2、实现XmlResult类

[csharp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public class XmlResult : ActionResult  
  2.  {  
  3.     public XmlResult(Object data)  
  4.     {  
  5.         this.Data = data;  
  6.     }  
  7.     public Object Data  
  8.     {  
  9.         get;  
  10.         set;  
  11.     }  
  12.     public override void ExecuteResult(ControllerContext context)  
  13.     {  
  14.         if (Data == null)  
  15.         {  
  16.             new EmptyResult().ExecuteResult(context);  
  17.             return;  
  18.         }  
  19.         context.HttpContext.Response.ContentType = "application/xml";  
  20.         using (MemoryStream ms = new MemoryStream())  
  21.         {  
  22.             XmlSerializer xs = new XmlSerializer(Data.GetType());  
  23.             xs.Serialize(ms, Data);  
  24.             ms.Position = 0;  
  25.             using (StreamReader sr = new StreamReader(ms))  
  26.             {  
  27.                 context.HttpContext.Response.Output.Write(sr.ReadToEnd());  
  28.             }  
  29.         }  
  30.     }  
  31. }  

3、创建一个HomeController,实现Index方法

[csharp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public ActionResult Index()  
  2. {  
  3.     return new XmlResult(new Product()  
  4.     {  
  5.         ID = "000001",  
  6.         Name = "测a试?",  
  7.         Description = ""  
  8.     });  
  9. }  
  10.    
  11.     /// <summary>  
  12.     /// This code was found here:  
  13.     /// http://blogs.msdn.com/b/miah/archive/2008/11/13/extending-mvc-returning-an-image-from-a-controller-action.aspx  
  14.     /// </summary>  
  15.     public class ImageResult : ActionResult  
  16.     {  
  17.         public ImageResult(Stream imageStream, string contentType)  
  18.         {  
  19.             if (imageStream == null)  
  20.                 throw new ArgumentNullException("imageStream");  
  21.             if (contentType == null)  
  22.                 throw new ArgumentNullException("contentType");  
  23.    
  24.             this.ImageStream = imageStream;  
  25.             this.ContentType = contentType;  
  26.         }  
  27.    
  28.         public Stream ImageStream { getprivate set; }  
  29.         public string ContentType { getprivate set; }  
  30.    
  31.         public override void ExecuteResult(ControllerContext context)  
  32.         {  
  33.             if (context == null)  
  34.                 throw new ArgumentNullException("context");  
  35.    
  36.             HttpResponseBase response = context.HttpContext.Response;  
  37.    
  38.             response.ContentType = this.ContentType;  
  39.           
  40.             byte[] buffer = new byte[4096];  
  41.             while (true)  
  42.             {  
  43.                 int read = this.ImageStream.Read(buffer, 0, buffer.Length);  
  44.                 if (read == 0)  
  45.                     break;  
  46.    
  47.                 response.OutputStream.Write(buffer, 0, read);  
  48.             }  
  49.    
  50.             response.End();  
  51.         }  
  52.     }  


ASP.NET MVC 实现AJAX跨域请求的两种方法

通常发送AJAX请求都是在本域内完成的,也就是向本域内的某个URL发送请求,完成部分页面的刷新。但有的时候需要向其它域发送AJAX请求,完成数据的加载,例如Google。

    在ASP.Net MVC 框架里实现跨域的AJAX请求有几种方式可以实现,以下就介绍常用的两种方法。

1.     发送JSONP请求

客户端:

jQuery对发送JSONP请求有很好的支持,客户端通过. ajax() 函数发送请求,其中需要制定 dataType 为“jsonp”  jsonpCallback 为指定的回调函数名(如  “UpdateDiv),也就是客户端需要定义一个UpdateDiv 函数,当请求成功后会自动调用该函数。

服务器:

ASP.NET MVC没有内置对 JSONP 请求的支持,不过使用 JsonResult 可以很方便的实现。我们只需要定义一个类(如 JsonpResult)继承自JsonResult,并重写 ExecuteResult()方法,在输出数据时,调用客户端定义的那个回调函数(这个函数必须是存在的,并且必须是全局和唯一的)。需要注意的是,在自定义的JsonpResult 里,需要设置 JsonRequestBehavior 为 AllowGet,否则会出错,因为 JSONP 请求必须是 Get 方式提交的。

客户端代码:

[javascript] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <scripttype="text/JavaScript">  
  2.             functionUpdateDiv(result) {  
  3.                 $("#div1").html(result.ID +result.Name);  
  4.             }  
  5.         $(function() {  
  6.             $(".btn").click(function () {            
  7.                 $.ajax({  
  8.                    type: "GET",  
  9.   
  10.                    url:"http://localhost:50863/Home/Index2",    //跨域url  
  11.                    dataType: "jsonp",   
  12.  //指定 jsonp 请求  
  13.                    jsonpCallback: "UpdateDiv" // 指定回调函数  
  14.   
  15.                 });  
  16.             })  
  17.         })  
  18. </script>  

服务端:

[csharp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1.  public class JSONPResult :JsonResult  
  2.   
  3.     {  
  4.   
  5.         public JSONPResult()  
  6.   
  7.        {  
  8.   
  9.           JsonRequestBehavior=JsonRequestBehavior.AllowGet;  
  10.   
  11.        }  
  12.   
  13.    
  14.   
  15.         public string Callback{get;set;}        
  16.   
  17.    
  18.   
  19.         ///<summary>  
  20.   
  21.         ///对操作结果进行处理  
  22.   
  23.         ///</summary>  
  24.   
  25.         ///<paramname="context"></param>  
  26.   
  27.         public override void  ExecuteResult(ControllerContext context)  
  28.   
  29.         {  
  30.   
  31.             var httpContext = context.HttpContext;  
  32.   
  33.             var callBack = Callback;  
  34.   
  35.   
  36.   
  37.             if(string.IsNullOrWhiteSpace(callBack))  
  38.   
  39.                    callBack = httpContext.Request["callback"]; //获得客户端提交的回调函数名称  
  40.   
  41.              
  42.   
  43.             // 返回客户端定义的回调函数  
  44.   
  45.             httpContext.Response.Write(callBack +"(");  
  46.   
  47.             httpContext.Response.Write(Data);          //Data 是服务器返回的数据          
  48.   
  49.              httpContext.Response.Write(");");            //将函数输出给客户端,由客户端执行  
  50.   
  51.         }  
  52.   
  53.    
  54.   
  55. }  
  56.   
  57.           //操作器和其它操作没什么区别,只是返回值是JsopnpResult结果  
  58.   
  59.          public ActionResult Index2()  
  60.   
  61.         {  
  62.   
  63.             var str = "{ID :'123', Name : 'asdsa' }";  
  64.   
  65.             return new JSONPResult{Data = str };  //返回 jsonp 数据,输出回调函数  
  66.   
  67.         }  


2.    跨域资源共享

相比 JSONP 请求,跨域资源共享要简单许多,也是实现跨域 AJAX 请求的首选。

客户端:

    客户端不在发送 JSONP 类型的请求,只需要发送普通的 JSON 请求即可,也不用定义回调函数,用 .success 即可。

服务端:

     服务端也很简单,操作结果还是返回普通的操作结果就可以,唯一要指定的是 HTTP 报文头部的Access-Control-Allow-Origi

指定为 “*” 即可,表示该输出允许跨域实现。

       跨域资源共享可以很方便的实现,不过在 IE9 还没有对该技术的支持,FireFox 就已经支持了。

 

代码:

客户端:

[javascript] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <scripttype="text/javascript">  
  2.   
  3.         $(function() {  
  4.   
  5.             $(".btn").click(function (){  
  6.   
  7.                 $.ajax({  
  8.   
  9.                     type:"GET",  
  10.   
  11.                     url:"http://localhost:50863/Home/Index3", //跨域URL  
  12.   
  13.                     dataType:"json",   
  14.   
  15.                     success:function (result){  
  16.   
  17.                         $("#div1").html(result.ID +result.Name);  
  18.   
  19.                     },  
  20.   
  21.                     error:function (XMLHttpRequest, textStatus,errorThrown) {                         
  22.   
  23.                         alert(errorThrown); // 调用本次AJAX请求时传递的options参数  
  24.   
  25.                     }  
  26.   
  27.                 });  
  28.   
  29.             })  
  30.   
  31.         })  
  32.   
  33.     </script>  

服务端:

[csharp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. ///<summary>  
  2.   
  3.       ///跨站资源共享实现跨站AJAX请求  
  4.   
  5.       ///</summary>  
  6.   
  7.       ///<returns></returns>  
  8.   
  9.       public ActionResult Index3()  
  10.   
  11.       {  
  12.   
  13.           var str = new { ID="123", Name= "asdsa" };  
  14.   
  15.           HttpContext.Response.AppendHeader("Access-Control-Allow-Origin","*");  
  16.   
  17.           return Json(str, JsonRequestBehavior.AllowGet);  
  18.   
  19.       }  

3.

[csharp] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. public class JsonpResult : JsonResult  
  2.     {  
  3.         private static readonly string JsonpCallbackName = "callback";  
  4.         private static readonly string CallbackApplicationType = "application/json";  
  5.   
  6.         /// <summary>  
  7.         /// Enables processing of the result of an action method by a custom type that inherits from the <see cref="T:System.Web.Mvc.ActionResult"/> class.  
  8.         /// </summary>  
  9.         /// <param name="context">The context within which the result is executed.</param>  
  10.         /// <exception cref="T:System.ArgumentNullException">The <paramref name="context"/> parameter is null.</exception>  
  11.         public override void ExecuteResult(ControllerContext context)  
  12.         {  
  13.             if (context == null)  
  14.             {  
  15.                 throw new ArgumentNullException("context");  
  16.             }  
  17.             if ((JsonRequestBehavior == JsonRequestBehavior.DenyGet) &&  
  18.                   String.Equals(context.HttpContext.Request.HttpMethod, "GET"))  
  19.             {  
  20.                 throw new InvalidOperationException();  
  21.             }  
  22.             var response = context.HttpContext.Response;  
  23.             if (!String.IsNullOrEmpty(ContentType))  
  24.                 response.ContentType = ContentType;  
  25.             else  
  26.                 response.ContentType = CallbackApplicationType;  
  27.             if (ContentEncoding != null)  
  28.                 response.ContentEncoding = this.ContentEncoding;  
  29.             if (Data != null)  
  30.             {  
  31.                 String buffer;  
  32.                 var request = context.HttpContext.Request;  
  33.                 var serializer = new JavaScriptSerializer();  
  34.                 if (request[JsonpCallbackName] != null)  
  35.                     buffer = String.Format("{0}({1})", request[JsonpCallbackName], serializer.Serialize(Data));  
  36.                 else  
  37.                     buffer = serializer.Serialize(Data);  
  38.                 response.Write(buffer);  
  39.             }  
  40.         }  
  41.     }  
  42.   
  43.     public static class ContollerExtensions  
  44.     {  
  45.         /// <summary>  
  46.         /// Extension methods for the controller to allow jsonp.  
  47.         /// </summary>  
  48.         /// <param name="controller">The controller.</param>  
  49.         /// <param name="data">The data.</param>  
  50.         /// <returns></returns>  
  51.         public static JsonpResult Jsonp(this Controller controller, object data)  
  52.         {  
  53.             JsonpResult result = new JsonpResult()  
  54.             {  
  55.                 Data = data,  
  56.                 JsonRequestBehavior = JsonRequestBehavior.AllowGet  
  57.             };  
  58.   
  59.             return result;  
  60.         }  
  61.     }  
原创粉丝点击