基于ASP.NET 3.5 Web Service 的JSON扩展应用

如果你经常使用ASP.NET Web服务,那么你知道他们可以以不同的方法进行通信。可以使用SOAP 1.1/1.2,HTTP POST和HTTP GET的一些支持的协议调用ASP.NET Web服务。我们可以通过HTTP POST或GET非常好的调用Web服务,并且也有能力进行传递和接收简称JSON编码的对象,而不是使用普通的字符串和XML。

      JSON(JavaScript Object Notation)是一种轻量级的数据交换格式,它采用完全独立于语言的文本格式,可替换XML成为AJAX程序中的数交换格式。它类似于XML和SOAP,同样具有跨平台的特性,是基于JavaScript 的一个子集,并易于人阅读和编写,同时也易于机器解析和生成。而且也使用了类似于C语言家族的习惯(包括C, C++, C#, Java, JavaScript, Perl, Python等),这些特性使JSON成为理想的数据交换语言。微软选择JSON在服务器和Ajax客户端可以实现数据交换。在客户端和服务器端均实现了(数据的)串行化器和并行化器以使数据按JSON的格式交换。这提供了一种使浏览器向服务器发出Web Service请求的方法。同时,它也提供一个异步通信层,连接浏览器与网络终端。Ajax从Beta版开始全面用JSON格式描述服务器和客户端之间传输的数据,Microsoft.Web.Script.Services命名空间提供这方面的支持。

  尽管有许多宣传关于XML如何拥有跨平台,跨语言的优势,然而,除非应用于 Web Services,否则,在普通的Web应用中,开发者经常为XML的解析伤透了脑筋,无论是服务器端生成或处理 XML,还是客户端用 JavaScript 解析 XML,都常常导致复杂的代码,极低的开发效率。实际上,对于大多数Web 应用来说,他们根本不需要复杂的 XML 来传输数据,XML 的扩展性很少具有优势,许多 AJAX 应用甚至直接返回HTML片段来构建动态 Web 页面。和返回 XML 并解析它相比,返回 HTML 片段大大降低了系统的复杂性,但同时缺少了一定的灵活性。

    现在,JSON 为Web应用开发者提供了另一种数据交换格式。让我们来看看JSON到底是什么?同 XML 或 HTML 片段相比,JSON 提供了更好的简单性和灵活性。JSON 数据格式解析和XML一样,JSON 也是基于纯文本的数据格式。由于JSON天生是为 JavaScript 准备的,因此,JSON的数据格式非常简单,您可以用 JSON 传输一个简单的String,Number,Boolean,也可以传输一个数组,或者一个复杂的 Object对象。

它有两种结构:


    1、 “名称/值”对的集合(A collection of name/value pairs)。不同的语言中,它被理解为对象(object),纪录(record),结构(struct),
字典(dictionary),哈希表(hash table),有键列表(keyed list),或者关联数组 (associative array)。

    2、 值的有序列表(An ordered list of values)。在大部分语言中,它被理解为数组(array)。先看看用下面Xml表示:
  1. <posts>
  2.     <post>
  3.         <id>1</id>
  4.         <title>标题1</title>
  5.         <content>内容</content>
  6.         <posterId>12</posterId>
  7.     </post>
  8.     <post>
  9.         <id>2</id>
  10.         <title>标题2</title>
  11.         <content>内容</content>
  12.         <posterId>13</posterId>
  13.     </post>
  14. </posts>
复制代码
使用JSON:
  1. {posts:[
  2.     {
  3.         id:1,
  4.         title:"标题1",
  5.         content:"内容",
  6.         posterId:12
  7.     },
  8.     {
  9.         id:2,
  10.         title:"标题2",
  11.         content:"内容",
  12.         posterId:13
  13.     }
  14. ]};
复制代码
让我们在看一下ASP.NET 3.5 Web Service的JSON扩展应用。为什么第一次访问Web服务通过HTTP POST和Get?因为,有时候你要调用的服务使用
JavaScript和AJAX ,例如:这种做法的缺点是,你仍然会得到XML返回到服务,你必须分析和转换一些JavaScript对象。 有许多关于在.NET 3.5中的JSON 
补充的另一个标准的方式来调用ASP.NET Web服务。在使用JSON期间,即使返回JSON序列化对象从Web服务方法的XML内SOAP标识,这优于并行化对象
在客户端,并能在服务器重复使用的Web服务的代码。我不喜欢这个方法并写相同功能的两倍,因为它们以不同的格式返回的数据,但在其他方面相同的,即
使功能只是包含一个行要求一些共享功能的库,相同的代码失去 同步,逐步改变,并最终分裂成不同的版本。 


      所以,我很高兴地发现的.NET3.5使我们能够以这样一种方式解析WCF服务,它们可以通过相互配合JSON ;也就是说,可以通过在这两个JSON编码的参
数和接收JSON编码的对象。由于JSON是JavaScript的,在客户端不必做任何分析或解串。不过,我不希望有一个JSON的服务,一个XML服务,我想的服务可
以相互使用JSON或XML 。我们需要有一个.NET 3.5 框架标准的ASP.NET Web服务支持JSON。

    这个想法是能够标记操作程序,我们希望可随时取回JSON与同一个属性,例如[JSONMethod]。属性的部分是非常简单,只要创建一个新的属性类。它可
以是一个空类,因为在这个时候只需使用属性的标志,我们可以加入特殊的属性以帮助程序文档,例如:
  1. public class JSONMethodAttribute : System.Attribute
  2. {
  3.     public JSONMethodAttribute()
  4.     {
  5.     }
  6. }
复制代码
在未来的事情需要做的是建立一个新的Web服务类:这是一个扩展类System.Web.Services.WebService。如果在过去创造了服务将会看到默认情况
下,他们扩展了WebService类。我们真正需要的是能够拦截方法调用的网页,因此,执行我们自己的WebService类,并获得非常好的扩展我们的网络服
务,我们得到一个好地方,其中用代码来来处理JSON请求。


    在这个例子中,创建了一个名为EnhancedWebService类扩展System.Web.Services.WebService 。我们将利用这一类构建截获JSON请求。这引出
一个问题:我们将如何知道如果请求是一个JSON?有可能以多种方式做到这一点,因为我们的目的,刚刚检查的请求查询字符串变量命名为“from”设置为
JSON 。 这里是最初的EnhancedWebService类:
  1. public class EnhancedWebService : System.Web.Services.WebService
  2.     {
  3.         public EnhancedWebService()
  4.             : base()
  5.         {
  6.             string ServiceMethodName = GetMethodName();
  7.             bool IsJSON = Context.Request.QueryString["form"] == "json";
  8.             if (IsJSON) InterceptJSONMethodRequest(ServiceMethodName);
  9.         }
  10.         private string GetMethodName()
  11.         {
  12.             return Context.Request.Url.Segments[Context.Request.Url.Segments.Length - 1];
  13.         } 
  14.         private void InterceptJSONMethodRequest(string ServiceMethodName)
  15.         { 
  16.             JSONMethodAttribute JMA = GetMethodJSONMethodAttribute(ServiceMethodName);
  17.             if (JMA == null)
  18.             {
  19.                 Context.Response.Write("throw new Exception('The Web Service method " + 
  20.                                       ServiceMethodName + " is not available " + 
  21.                                       "as a JSON function. For more " + 
  22.                                       "information contact " + 
  23.                                       "the Web Service Administrators.');");
  24.             }
  25.             else
  26.             { 
  27.                 //ToDo: deserialize parameters, call target method, 
  28.                 //      deserialize and write return value
  29.             }
  30.             Context.Response.Flush();
  31.             Context.Response.End();
  32.         } 
  33.         private JSONMethodAttribute GetMethodJSONMethodAttribute(string WebServiceMethodName)
  34.         {
  35.             MethodInfo ActiveMethod = this.GetType().GetMethod(WebServiceMethodName);
  36.             JSONMethodAttribute JMA = null;
  37.             if (ActiveMethod != null)
  38.             {
  39.                 object[] Attributes = ActiveMethod.GetCustomAttributes(true);
  40.                 foreach (object Attribute in Attributes)
  41.                 {
  42.                     if (Attribute.GetType() == typeof(JSONMethodAttribute))
  43.                     {
  44.                         JMA = (JSONMethodAttribute)Attribute;
  45.                     }
  46.                 }
  47.             }
  48.             return JMA;
  49.         }
  50.     }
  51. }
  52. public class EnhancedWebService : System.Web.Services.WebService
  53.     {
  54.         public EnhancedWebService()
  55.             : base()
  56.         {
  57.             string ServiceMethodName = GetMethodName();
  58.             bool IsJSON = Context.Request.QueryString["form"] == "json";
  59.             if (IsJSON) InterceptJSONMethodRequest(ServiceMethodName);
  60.         }
  61.         private string GetMethodName()
  62.         {
  63.             return Context.Request.Url.Segments[Context.Request.Url.Segments.Length - 1];
  64.         } 
  65.         private void InterceptJSONMethodRequest(string ServiceMethodName)
  66.         { 
  67.             JSONMethodAttribute JMA = GetMethodJSONMethodAttribute(ServiceMethodName);
  68.             if (JMA == null)
  69.             {
  70.                 Context.Response.Write("throw new Exception('The Web Service method " + 
  71.                                       ServiceMethodName + " is not available " + 
  72.                                       "as a JSON function. For more " + 
  73.                                       "information contact " + 
  74.                                       "the Web Service Administrators.');");
  75.             }
  76.             else
  77.             { 
  78.                 //ToDo: deserialize parameters, call target method, 
  79.                 //      deserialize and write return value
  80.             }
  81.             Context.Response.Flush();
  82.             Context.Response.End();
  83.         } 
  84.         private JSONMethodAttribute GetMethodJSONMethodAttribute(string WebServiceMethodName)
  85.         {
  86.             MethodInfo ActiveMethod = this.GetType().GetMethod(WebServiceMethodName);
  87.             JSONMethodAttribute JMA = null;
  88.             if (ActiveMethod != null)
  89.             {
  90.                 object[] Attributes = ActiveMethod.GetCustomAttributes(true);
  91.                 foreach (object Attribute in Attributes)
  92.                 {
  93.                     if (Attribute.GetType() == typeof(JSONMethodAttribute))
  94.                     {
  95.                         JMA = (JSONMethodAttribute)Attribute;
  96.                     }
  97.                 }
  98.             }
  99.             return JMA;
  100.         }
  101.     }
  102. }
复制代码
GetMethodName检索功能的名称来自URL函数调用。当希望Web方法通过HTTP POST或GET的时候,该方法的名字是在URL中。上述InterceptJSONMethodRequest仍然需要完成,但是,我们如何取消响应,并有权结束时终止响应。如果不这样做,控制离开EnhancedWebService类构造器, ASP.NET服务控制将进行服务的请求完成SOAP响应,我们不希望让发生,很明显我们正在处理一个JSON请求。 

    此外,内部InterceptJSONMethodRequest 我们调用GetMethodJSONMethodAttribute检索[JSONAttribute]的方法被调用,如果还没有,那么我们抛出一个异
常。你可以在服务器端抛出,但是当它到达用户端,浏览器将不会有一个好的消息调试。显然,我们也将需要有一种方式从JSON来序列化和反序列化。由于.NET3.5已经是内置的,在刚刚添加下面两项功能的ExtendedWebService类:
  1. private string JSONSerialize(object SerializationTarget)
  2. {
  3.     DataContractJsonSerializer serializer = 
  4.       new DataContractJsonSerializer(SerializationTarget.GetType());
  5.     MemoryStream ms = new MemoryStream();
  6.     serializer.WriteObject(ms, SerializationTarget);
  7.     string Product = Encoding.Default.GetString(ms.ToArray());
  8.     ms.Close();
  9.     return Product;
  10. }
  11. private object JSONDeserialize(string DeserializationTarget, Type TargetType)
  12. {
  13.     MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(DeserializationTarget));
  14.     DataContractJsonSerializer serializer = new DataContractJsonSerializer(TargetType);
  15.     object Product = serializer.ReadObject(ms);
  16.     ms.Close();
  17.     return Product;
  18. }
复制代码
您需要使用的System.Runtime.Serialization.Json名字空间,这将需要提及System.Runtime.Serialization , System.ServiceModel ,和System.ServiceModel.Web 。 

最后,我们只需要完成待办事项在InterceptJSONMethodRequest功能;在这里:

  1.     else
  2.     {
  3.         Type Service = this.GetType();
  4.         MethodInfo JSONMethod = Service.GetMethod(ServiceMethodName);
  5.         if (JSONMethod == null) return;
  6.         ParameterInfo[] JSONMethodParameters = JSONMethod.GetParameters();
  7.         object[] CallParameters = new object[JSONMethodParameters.Length];
  8.         for (int i = 0; i < JSONMethodParameters.Length; i++)
  9.         {
  10.             ParameterInfo TargetParameter = JSONMethodParameters;
  11.             string RawParameter = Context.Request.Form[TargetParameter.Name];
  12.             if (RawParameter == null || RawParameter == "")
  13.                 RawParameter = Context.Request.QueryString[TargetParameter.Name];
  14.             if (RawParameter == null || RawParameter == "")
  15.                 throw new Exception("Missing parameter " + TargetParameter.Name + ".");
  16.             CallParameters = JSONDeserialize(RawParameter, TargetParameter.ParameterType);
  17.         }
  18.         object JSONMethodReturnValue = JSONMethod.Invoke(this, CallParameters);
  19.         string SerializedReturnValue = JSONSerialize(JSONMethodReturnValue);
  20.         Context.Response.Write(SerializedReturnValue);
  21.     }

复制代码
我们目前的Web服务类类型,该类型的“this”不是EnhanceWebService ,但实际的Web服务类将在以后的时间创建,其中将有各种Web方法。然后,我们开始获取信息的方法被调用,如果不存在,讲发生错误,我们只是退出而终止响应,从而使ASP.NET Web服务处理程序继续进行。从方法的信息,我们将获得其参数列表迭代通过。

对于每个参数,我们期待双方的QueryString和form收集具有相同名称的的变量。我们可以通过两种方式检查这两个参数:如果没有变量存在到某一特定的参数,那么这个参数是没有提供的,我们抛出一个异常,在这里,只是一个服务器端异常;否则,我们将其值化的对象,以后储存。一并行化所有参数,我们使用目标的方法和获得返回值。

当然,在这一点上,所有需要做的是连续的返回值,并完成相应。 

    这是全部的EnhancedWebService类。现在,您可以解释任何Web方法的JSON同一条直线上,例如:
  1. public class MyService : EnhancedWebService
  2. {
  3.     public MyService () {
  4.     }
  5.     [JSONMethod]
  6.     [WebMethod]
  7.     public string[] MethodThatSupportsJSON(string Parameter)
  8.     {
  9.         return new string[] { Parameter, Parameter, Parameter };
  10.     }
  11.     [WebMethod]
  12.     public string[] MethodThatDoesNotSupportJSON(string Parameter)
  13.     {
  14.         return new string[] { Parameter, Parameter, Parameter };
  15.     }
  16. }
复制代码
如果在这个例子中使用的代码,您可能要检查的附加条件,例如是否目标的方法是void(不返回值),并写了一个空字符串的时候是这种情况,但应已经足够好了就可以开始。


文/ξ箫音ξ  出处/博客园
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值