好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

ASP.NET MVC 扩展之 JsonpResult ,用来提供轻量级跨域调用服务

ASP.NET MVC 扩展之 JsonpResult ,用来提供轻量级跨域调用服务

ASP.NET MVC 扩展之 JsonpResult ,用来提供轻量级跨域调用服务

2012-06-21 23:16 by 自由的生活, 522 阅读,  1  评论,  收藏 ,  编辑

关于 JSONP,我想大家都已经很熟悉了,还不是很清楚的童鞋可以在网上搜索一下。众所周知, Ajax 是不能跨域请求的,默认情况下,浏览器是阻止的。那如何来实现跨域提供服务呢?举一个很简单的例子。比如我现在有一个网站  www.abc.com  ,其中有一个页面需要提供百度的搜索框,并且还要像百度首页一样,提供智能的提示,就是在我输入文字的同时,及时补全我的搜索,列出供我选择的项。

由于前面我们说到 Ajax 是不能跨域的,那怎样调用百度的搜索服务呢?答案就是 JSONP。JSONP 说白了就是在  www.abc.com  一个页面里,通过 Javascript 动态构造一个 <Script> </script>,其中 src= 'http://search.baidu.com/service.php?word=博客园&callback=showSearch", 其中 word=博客园 是我们在  www.abc.com  搜索框里面输入的文字,callback=showSearch 就是百度返回的结果里面回调函数的名称,比如 showSearch({ word: '博客园', result : [{博客园a},{博客园b}] }) 。

由于动态构建 <script> 不是 Ajax 请求,而是普通的 GET 请求,所以它是可以跨域的。

废话了这么多,下面就贴出我的代码了:

JsonpResult:

 using   System.Web.Mvc;
  using   System.Web.Script.Serialization;
  using   System.Text;

  namespace   DearBruce.JsonpActionResultDemo.WebUI.Extensions
{
      ///   <summary> 
     ///   Jsonp 返回结果
      ///   </summary> 
     public   class   JsonpResult : ActionResult
    {
          ///   <summary> 
         ///   默认的 callback 参数名称
          ///   </summary> 
         public   static   readonly   string  _defaultCallbackName =  "  jsoncallback  "  ;

          ///   <summary> 
         ///   默认的密码的参数名称
          ///   </summary> 
         public   static   readonly   string  _defaultPasswordName =  "  password  "  ;

          ///   <summary> 
         ///   构造函数
          ///   </summary> 
         ///   <param name="data">  要序列化为 Jsonp 数据的对象  </param> 
         public  JsonpResult( object   data)
            :   this (data,  null  )
        {

        }

          ///   <summary> 
         ///   构造函数
          ///   </summary> 
         ///   <param name="data">  要序列化为 Jsonp 数据的对象  </param> 
         ///   <param name="callbackName">  回调函数的名字,如果为空,则默认为 "jsoncallback"  </param> 
         public  JsonpResult( object  data,  string   callbackName)
        {
              this .Data =  data;
              this .CallBackName =  callbackName;
        }

          ///   <summary> 
         ///   验证权限
          ///   </summary> 
         ///   <param name="context">  控制器上下文  </param> 
         ///   <returns>  授权是否成功,如果已经授权,则返回 true  </returns> 
         protected   virtual   bool   ValidatePrivilege(ControllerContext context)
        {
              if  (! string  .IsNullOrEmpty(PasswordValue))
            {
                  //   这里验证密码是否正确 
                 string  password =  context.HttpContext.Request.QueryString[PasswordName];
                  if  (password !=  PasswordValue)
                {
                      return   false  ;
                }
            }
              return   true  ;
        }

          ///   <summary> 
         ///   核心处理
          ///   </summary> 
         ///   <param name="context"></param> 
         public   override   void   ExecuteResult(ControllerContext context)
        {
              if  (! ValidatePrivilege(context))
            {
                HandleUnAuthorizedRequest(context);
                  return  ;
            }
              string  jsonData =  null  ;
              if (Data !=  null  )
            {
                jsonData  =  new   JavaScriptSerializer().Serialize(Data);
            }
              string  callbackValue =  context.HttpContext.Request.QueryString[CallBackName];

              string   result;
              string   contentType;
              if  ( string  .IsNullOrEmpty(callbackValue))
            {
                result  =  jsonData;
                contentType  =  "  application/json  "  ;
            }
              else  
            {
                result  = callbackValue +  "  (  "  + jsonData +  "  )  "  ;
                contentType  =  "  application/x-javascript  "  ;
            }
            context.HttpContext.Response.ContentType  =  contentType;
              if  ( this .ContentEncoding !=  null  )
            {
                context.HttpContext.Response.ContentEncoding  =  this  .ContentEncoding;
            }
              if (result !=  null  )
            {
                context.HttpContext.Response.Write(result);
            }
        }

          ///   <summary> 
         ///   处理为授权的请求
          ///   </summary> 
         ///   <param name="context">  控制器上下文  </param> 
         protected   virtual   void   HandleUnAuthorizedRequest(ControllerContext context)
        {
              //   暂时不实现
              //  context.HttpContext.Response.ContentType = "text/plain";
              //  context.HttpContext.Response.Write(string.Empty); 
         }

          ///   <summary> 
         ///   要序列化为 Jsonp 数据的对象
          ///   </summary> 
         public   object  Data {  get ;  set  ; }

          private   Encoding _contentEncoding;

          ///   <summary> 
         ///   内容编码
          ///   </summary> 
         public   Encoding ContentEncoding
        {
              get  
            {
                  return  _contentEncoding;  //   ?? Encoding.UTF8; 
             }
              set  
            {
                _contentEncoding  =  value;
            }
        }

          private   string   _callBackName;

          ///   <summary> 
         ///   回调函数名称
          ///   </summary> 
         public   string   CallBackName
        {
              get  
            {
                  return  _callBackName ??  _defaultCallbackName;
            }
              set  
            {
                _callBackName  =  value;
            }
        }


          private   string  _passwordName {  get ;  set  ; }

          ///   <summary> 
         ///   密码的参数名称,默认为 "password"
          ///   </summary> 
         public   string   PasswordName
        {
              get  
            {
                  return  _passwordName ??  _defaultPasswordName;
            }
              set  
            {
                _passwordName  =  value;
            }
        }

          ///   <summary> 
         ///   正确的密码值
          ///   </summary> 
         public   string  PasswordValue {  get ;  set  ; }
    }
} 

测试的 Controller:

     public   class   HomeController : Controller
    {
          public   ActionResult Index()
        {
            ViewBag.Message  =  "  欢迎使用 ASP.NET MVC!  "  ;

              return   View();
        }

          public   ActionResult TestJsonp1()
        {
              return   new  JsonpResult( new  { success =  true , message =  "  测试 jsonp1  "   });
        }

          public   ActionResult TestJsonp2()
        {
              return   new  JsonpResult( new  { success =  true , message =  "  测试 jsonp2  "  },  "  callback  "  );
        }

          public   ActionResult TestJsonp3()
        {
            JsonpResult result  =  new  JsonpResult( new  { success =  true , message =  "  测试 jsonp3  "  },  "  callback  "  )
            {
                PasswordValue  =  "  bruce123456  "  ,
            };
              return   result;
        }
    } 

测试的 View:

 <  p  >  
    @Html.ActionLink("测试 Jsonp 之不带 jsoncallback 参数和不需要密码,则返回 json 数据", "TestJsonp1")
  </  p  > 
 <  p  >  
    @Html.ActionLink("测试 Jsonp 之带 callback 参数,则返回 javascript 代码", "TestJsonp2", new { callback = "ShowMessage" })
  </  p  > 
 <  p  >  
    @Html.ActionLink("测试 Jsonp 之需要密码 - 为空或错误的密码", "TestJsonp3")
  </  p  > 
 <  p  >  
    @Html.ActionLink("测试 Jsonp 之带 callback 参数和需要密码 - 正确的密码", "TestJsonp3", new { password = "bruce123456", callback = "ShowMessage" })
  </  p  > 

虽然很简单,只给需要帮助的人!

谢谢浏览!

作者: 音乐让我说 ( 音乐让我说 - 博客园 )
微博: http://weibo.com/liuzuliang  
出处: http://music.cnblogs.com/
文章版权归本人所有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

分类:  ASP.NET MVC

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于ASP.NET MVC 扩展之 JsonpResult ,用来提供轻量级跨域调用服务的详细内容...

  阅读:42次