• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
皇图霸业谈笑间
更高、更快、更强
博客园    首页    新随笔    联系   管理    订阅  订阅
基于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表示:

<posts>
    
<post>
        
<id>1</id>
        
<title>标题1</title>
        
<content>内容</content>
        
<posterId>12</posterId>
    
</post>
    
<post>
        
<id>2</id>
        
<title>标题2</title>
        
<content>内容</content>
        
<posterId>13</posterId>
    
</post>
</posts>

使用JSON:

{posts:[
    {
        id:
1,
        title:
"标题1",
        content:
"内容",
        posterId:
12
    },
    {
        id:
2,
        title:
"标题2",
        content:
"内容",
        posterId:
13
    }
]};

     让我们在看一下ASP.NET 3.5 Web Service的JSON扩展应用。为什么第一次访问Web服务通过HTTP POST和Get?因为,有时候你要调用的服务使用

JavaScript和AJAX ,例如:这种做法的缺点是,你仍然会得到XML返回到服务,你必须分析和转换一些JavaScript对象。 有许多关于在.NET 3.5中的JSON

补充另一种标准方式来调用ASP.NET Web服务。

      在使用JSON期间,即使从Web服务方法的XML内SOAP标识中返回JSON序列化对象,这也优于并行化对象在客户端,并能在服务器重复使用的 Web服务

的代码。我不喜欢这个方法,当写相同功能的时候付出工作流的两倍,因为它们以不同的格式返回的数据,但在其他方面相同的,即使功能只是包含一个行要 求

一些共享功能的库,相同的代码逐步改变并失去同步,最终分解成不同的版本。

      所以,我很高兴地发现的.NET3.5使我们能够以这样一种方式解析WCF服务,它们可以通过相互配合JSON ;也就是说,可以通过在这两个JSON编码的参

数和接收JSON编码的对象。由于JSON是JavaScript的,在客户端不必做任何分析或串行化。不过,我不希望有一个JSON的服务和一个 XML服务,我想的服务

可以相互使用JSON或XML 。我们需要有一个.NET 3.5框架的ASP.NET Web服务支持JSON。

     这个想法是能够进行标记的操作程序,我们希望可随时取回JSON与同一个属性,例如[JSONMethod]。属性的部分是非常简单,只要创建一个新的属 性类。

它可以是一个空类,因为在这个时候只需使用属性的标志,我们可以加入特殊的属性以帮助程序文档,例如:

public class JSONMethodAttribute : System.Attribute
{
    public JSONMethodAttribute()
    {
    }
}

    在未来需要做的事情是建立一个新的Web服务类:这是一个扩展类System.Web.Services.WebService。如果在过去创造了服务将 会看到默认情况

下,他们扩展了WebService类。我们真正需要的是能够拦截调用的网页的方法,因此,执行我们自己的WebService类,并获得非常好的 扩展我们的网络

服务,我们得到一个好方法,其中用代码来来处理JSON请求。

    在这个例子中,创建了一个名为EnhancedWebService类扩展System.Web.Services.WebService 。我们将利用这一类构建截获JSON请求。这引出

一个问题:我们将如何知道如果请求是一个JSON?有可能以多种方式做到这一点,因为我们的目的是刚刚检查的请求查询字符串,变量命名为 “from”设置

为JSON 。这里是最初的EnhancedWebService类:

public class EnhancedWebService : System.Web.Services.WebService
    {
        
public EnhancedWebService()
            : 
base()
        {
            
string ServiceMethodName = GetMethodName();
            
bool IsJSON = Context.Request.QueryString["form"] == "json";
            
if (IsJSON) InterceptJSONMethodRequest(ServiceMethodName);
        }
        
private string GetMethodName()
        {
            
return Context.Request.Url.Segments[Context.Request.Url.Segments.Length - 1];
        } 
        
private void InterceptJSONMethodRequest(string ServiceMethodName)
        { 
            JSONMethodAttribute JMA 
= GetMethodJSONMethodAttribute(ServiceMethodName);
            
if (JMA == null)
            {
                Context.Response.Write(
"throw new Exception('The Web Service method " + 
                                       ServiceMethodName 
+ " is not available " + 
                                       
"as a JSON function. For more " + 
                                       
"information contact " + 
                                       
"the Web Service Administrators.');");
            }
            
else
            { 
                
//ToDo: deserialize parameters, call target method, 
                
//      deserialize and write return value
            }
            Context.Response.Flush();
            Context.Response.End();
        } 
        
private JSONMethodAttribute GetMethodJSONMethodAttribute(string WebServiceMethodName)
        {
            MethodInfo ActiveMethod 
= this.GetType().GetMethod(WebServiceMethodName);
            JSONMethodAttribute JMA 
= null;
            
if (ActiveMethod != null)
            {
                
object[] Attributes = ActiveMethod.GetCustomAttributes(true);
                
foreach (object Attribute in Attributes)
                {
                    
if (Attribute.GetType() == typeof(JSONMethodAttribute))
                    {
                        JMA 
= (JSONMethodAttribute)Attribute;
                    }
                }
            }
            
return JMA;
        }
    }
}

public class EnhancedWebService : System.Web.Services.WebService
    {
        public EnhancedWebService()
            : base()
        {
            string ServiceMethodName 
= GetMethodName();
            bool IsJSON 
= Context.Request.QueryString["form"] == "json";
            
if (IsJSON) InterceptJSONMethodRequest(ServiceMethodName);
        }
        private string GetMethodName()
        {
            
return Context.Request.Url.Segments[Context.Request.Url.Segments.Length - 1];
        } 
        private 
void InterceptJSONMethodRequest(string ServiceMethodName)
        { 
            JSONMethodAttribute JMA 
= GetMethodJSONMethodAttribute(ServiceMethodName);
            
if (JMA == null)
            {
                Context.Response.Write(
"throw new Exception('The Web Service method " + 
                                       ServiceMethodName 
+ " is not available " + 
                                       
"as a JSON function. For more " + 
                                       
"information contact " + 
                                       
"the Web Service Administrators.');");
            }
            
else
            { 
                
//ToDo: deserialize parameters, call target method, 
                //      deserialize and write return value
            }
            Context.Response.Flush();
            Context.Response.End();
        } 
        private JSONMethodAttribute GetMethodJSONMethodAttribute(string WebServiceMethodName)
        {
            MethodInfo ActiveMethod 
= this.GetType().GetMethod(WebServiceMethodName);
            JSONMethodAttribute JMA 
= null;
            
if (ActiveMethod != null)
            {
                object[] Attributes 
= ActiveMethod.GetCustomAttributes(true);
                foreach (object Attribute 
in Attributes)
                {
                    
if (Attribute.GetType() == typeof(JSONMethodAttribute))
                    {
                        JMA 
= (JSONMethodAttribute)Attribute;
                    }
                }
            }
            
return JMA;
        }
    }
}

    GetMethodName检索功能的名称来自URL函数调用。当希望Web方法通过HTTP POST或GET的时候,该方法的名字是在URL中。上述InterceptJSONMethodRequest

仍然需要完成,但是,我们如何取消响应,并结束时有权终止响应。如果不这样做,将离开EnhancedWebService类构造器,我们不希望让 发生ASP.NET服务控制将进行服务

的请求完成SOAP响应,很显然我们正在处理一个JSON请求。
    此外,我们内部InterceptJSONMethodRequest 和GetMethodJSONMethodAttribute检索[JSONAttribute]的方法被调用,如果还没有被调用那么我们将抛出一个异 常。

你可以在服务器端抛出,但是当它到达用户端时候,浏览器将不能消息调试。显然,我们也将需要有一种方式从JSON来序列化和反序列化。由 于.NET3.5已经是内置的Ajax,先

添加下面两项功能的ExtendedWebService类:

private string JSONSerialize(object SerializationTarget)
{
    DataContractJsonSerializer serializer 
= 
      
new DataContractJsonSerializer(SerializationTarget.GetType());
    MemoryStream ms 
= new MemoryStream();
    serializer.WriteObject(ms, SerializationTarget);
    
string Product = Encoding.Default.GetString(ms.ToArray());
    ms.Close();
    
return Product;
}
private object JSONDeserialize(string DeserializationTarget, Type TargetType)
{
    MemoryStream ms 
= new MemoryStream(Encoding.Unicode.GetBytes(DeserializationTarget));
    DataContractJsonSerializer serializer 
= new DataContractJsonSerializer(TargetType);
    
object Product = serializer.ReadObject(ms);
    ms.Close();
    
return Product;
}

     您需要使用的System.Runtime.Serialization.Json名字空间,这将需要提及 System.Runtime.Serialization , System.ServiceModel ,和System.ServiceModel.Web 。
最后,我们只需要在InterceptJSONMethodRequest功能完成待办事项。代码如下:

…
    
else
    {
        Type Service 
= this.GetType();
        MethodInfo JSONMethod 
= Service.GetMethod(ServiceMethodName);
        
if (JSONMethod == null) return;
        ParameterInfo[] JSONMethodParameters 
= JSONMethod.GetParameters();
        
object[] CallParameters = new object[JSONMethodParameters.Length];
        
for (int i = 0; i < JSONMethodParameters.Length; i++)
        {
            ParameterInfo TargetParameter 
= JSONMethodParameters[i];
            
string RawParameter = Context.Request.Form[TargetParameter.Name];
            
if (RawParameter == null || RawParameter == "")
                RawParameter 
= Context.Request.QueryString[TargetParameter.Name];
            
if (RawParameter == null || RawParameter == "")
                
throw new Exception("Missing parameter " + TargetParameter.Name + ".");
            CallParameters[i] 
= JSONDeserialize(RawParameter, TargetParameter.ParameterType);
        }
        
object JSONMethodReturnValue = JSONMethod.Invoke(this, CallParameters);
        
string SerializedReturnValue = JSONSerialize(JSONMethodReturnValue);
        Context.Response.Write(SerializedReturnValue);
    }
…

      我们目前的Web服务类类型,该类型的“this”不是指的EnhanceWebService,但实际的Web服务类将在以后的时间创建,其中将有各种 Web方法。然后,我们开始

获取信息的方法被调用,如果不存在将发生错误便退出而终止响应,从而使ASP.NET Web服务处理程序继续进行。从方法的信息,我们将通过迭代获得其参数列表。对于

每个参数,我们期待双方的QueryString和form收集具有相同名称的的变量。我们可以通过两种方式检查这两个参数:如果没有变量存在到某 一特定的参数,那么这个参数

是没有提供的,我们抛出一个异常,在这里只是一个服务器端异常;否则,我们将其值化的对象,以后在储存。一并行化所有参数,我们使用目标的方法和获 得返回值。

当然,在这一点上,所有需要做的是连续的返回值,并完成相应。
     这是全部的EnhancedWebService类。现在,您可以解释任何Web方法的JSON同一条直线上,例如:

public class MyService : EnhancedWebService
{
    
public MyService () {
    }
    [JSONMethod]
    [WebMethod]
    
public string[] MethodThatSupportsJSON(string Parameter)
    {
        
return new string[] { Parameter, Parameter, Parameter };
    }
    [WebMethod]
    
public string[] MethodThatDoesNotSupportJSON(string Parameter)
    {
        
return new string[] { Parameter, Parameter, Parameter };
    }
}

      在这个例子中大家将会了解ASP.NET 3.5 Web Service 的JSON扩展应用的功能和开发原理,尤其对JSON的进一步了解,在以后

大型分布式开发中得到非常好的应用。

posted on 2010-04-15 21:05  布颜书  阅读(868)  评论(1)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3