zoukankan      html  css  js  c++  java
  • 通过aps.net创建web services 3

     ASP.NET web services 之路

          .net 的两个主要特征是创建web service服务器和创建 web services客户端的能力,我们需要了解它的几个组件:用于DISCO(web services Discovery Language,web 服务发现语言)和WSDL(web services Description Language ,web 服务描述语言)

      构建服务器

        1.确认你是否安装了IIS和.Net Framework (或者安装了vs2005等以上版本)

        2.创建一个Asp.net 需要的虚拟目录。将其命名为"Test"(或者使用vs2008创建一个空的web项目).

        3.创建一个Test.asmx,把它放在这个虚拟目录中(如果使用vs不需要发布的话,就不需要后者了)。

        4.在这个文件的第一行添加webService 指示符(使用vs开发工具就无需下面两步操作)

          <%@ webService Class="TestClass" Language="C#"%>

        5.引用System和 System.web.Services命名空间。

        6.创建一个类"TestClass".

        7.使用如下代码:     

          public int add(int a,int  b),给类添加一个方法add.

         8.使用webMethod特性把这个方法声明为可调用的XML web Service,如下

          [webMethod]

          public int add(int a,int b)

          {

            return a+b;

          }

          9.我们可以使用本地的地址打开:http://localhost/text/test.asmx .(如果使用的是vs开发工具直接按F5)

        web service 公开的方法(都会使用webMethod的特性来标记)

        如果你需要查看生成的WSDL文档或者是DISCO的话只需要在地址后面加上"?WSDL"或"?DISCO  "就行了

    剖析web service

           当请求进入IIS时,检查并且是否发出一个.asmx扩展文件,asp.net为了处理程序通过IIS进行注册,因此它请求完全被移交给ASP.Net进程。

      ASP.Net工作进程会检查这个请求,并且发现它在machine.config中注册了一个处理程序,用于扩展名为.asmx的资源请求。

        接着处理程序创建一个在处理程序中定义的类的实例,并且使用反射查看类所支持的操作以及这些操作如何路由。默认情况下,操作通过SOAPactiion HTTP标头映射

    到方法,但这可以改变为映射到SOAPbody的第一个子元素。

        一旦消息路由,这个处理程序将使用XML序列化器发序列化XML请求,使之成为方法期望的参数,一旦方法返回返回值和任何输出参数又通过XML序列化映射成XML

    。接着一个包含这个XML的SOAP响应被创建,并通过ASP.Net的HttpResquet上下文把响应发送回来,

      如果有异常会抛出到SoapException 中,一个SOAP错误将返回,同时HTTP状态码被设置为500或OK.

    构建文档字面服务

        webService 默认是基于架构的,或者称为字面的XML。

        在.NET中,这些文档/字面服务的编程模型的扩展性是相当好的,你可以使用多种XML创建接收或响应的操作。

        例如:这个操作将购买订单文档作为SOAP<Body>内的请求(与实际相比,作了大量的简化)

          <PurchaseOrder   ID="1234">

              <Date>1/2/2013</Date>

              <Item>Widgets</Item>

              <Amout>400</Amout>

         </PurchaseOrder>

        接收文档响应看起来:  

          <PurchaseOrderReceipt>

              <ReceiptID>5678</ReceipID>

          </PurchaseOrderReceipt>

      可以用几种方式把这个XML映射成方法。

        1.

            [webMethod]

            [return:XmlElement("PurchaseOrderReceipt")]

            public void PurchaseOrder([XmlAttribute]string ID,DateTime Date,int Amout,out string ReceiptID)

            {

                ReceiptID="5678";

                retrun;

            }

            由于XmlElementAttribute 和XmlAttributeAttribute特性类用于XML序列化,所以必须导入System.Xml.Serialization;

            默认情况下,方法名被映射成根元素,方法的每一个参数会被映射成子元素,但是ID参数会映射成XML属性而不是子元素,因为序列化这一点被利用

          XmlAttribute特性覆盖。

            因为ReceiptID是一个输出参数,它被序列化成XML用于响应,并且它被当成响应包装元素的子元素,默认情况下这个名称是方法的名称结尾添上"Response"

          本来应该是"PurchaseOrderResponse",但这里是"PurchaseOrderReceipt"。也是因为有一个特性用于这个方法的返回值;使用XMLAttribute类,这个值就被设置

          成正确的值了。

          这中序列化的方法被称为Wrapped(包装的),因为方法名称被用于文档的根元素。

        2.

          [webMethod]

          [return:XmlElement("PurchaseOrderReceipt")]

          [SoapDocumentMethod(ParameterStyle=SoapParameterStyle.Bare)]

          public string PurchaseOrder(string ID,DateTime Date,int Amout)

          {

            return "5946";

          }

          这样做的结果是,方法被SOAP请求序列化时,将不会使用方法名称作为包装素(通白的将:就是不会把方法名作为根元素),称为Bare(没有包装的).

          通过使用SoapDocumentMethod特性,命名空间要引用:System.web.Services.Protocols

          3.

            通过第2个列子使用Bare参数风格,使得这些请求和响应都是非描述性的。但是仍然可以创建看起来像包装过的消息。可以创建反映你想创建的XML文档的类,

        这些类将会被以一种类似于方法的方式序列化。

          首先创建类

          public class Po

          {

             [XmlAttribute]

            public string ID;

            public DateTime Date;

            public int Amount;

          }

          再创建响应的类

          public Class PoReceipt

          {

              public string ReceiptID=“5649”;

          }

          

          [webMethod]

          [return:XmlAttribute("PurchaseOrderReceipt")]

          [SoapDoucmentMethod(ParameterStyle=SoapParameterSytle.Bare)]

          public string PurchaseOrder(Po purchaseOrder)

          {

            PoReceipt receipt=new PoReceipt();

            retrun receipt.ReceiptID;

          }

      构建文档编程服务

          综合上述,所举的例子都是基于文档;通白的讲就是文档在SOAP消息内传递。在webservices 中的这些文档被映射成方法,这纯粹只是一种编程模型思维,这是

    请求-响应方式,但不同常规意义的远程方法调用。

          还有是基于模式,你可以在WSDL自动生成的类型部分中看到这个模式。模式包含序列化和反序列化XML所以信息时,WSDL将它称为字面(literal)消息。

        例如:

          要创建这个消息结构,需要在方法声明上改变一样东西,把SoapAttributeMethodAttribute特性的Use属性设置编码的(encoded)

          需要引入命名空间 System.web.services.Description

          [webMethod]

          [return:XmlElement("PurchaseOrderReceipt")]

          [SoapDocumentMethod(ParamentStyle=SoapParamentStyle.Bare,Use=SoapBindingUse.Encode)]

          public POReceipt PurchaseOrder(PO PurchaseOrder)

          {

              POReceipt receipt;

              return receipt;

          }

          使用编码的XML特性改成PO类,可以设置XML命名空间为:http://encode/

          [SoapType(Namespace="http://encode/")]

          [XmlRoot(Namespace="http://literal/")]

          public class PO

          {

            [XmlAttribute]

            public string ID;

            public DateTime Date;

            public int Amount;

          }

          注意,ID属性不再是XML属性。编码的SOAP不包括任何特性;全都是元素。

    构建RPC编码服务

        什么是RPC先了解一下,RPC(Remote Procedure Call Protocol 远程过程调用协议),它是一种通过网络从远程计算机程序请求服务,而不需要了解底层网络技术的协议。

       有两种方法可以改变web services,使它从默认处理文档/籽面操作转变到处理RPC编码操作:SoapRpcServiceAttribute特性和SoapRpcMethodAttribute特性。

    如果你使用SoapRpcServiceAttribute特性应用在类上,那么所以的方法都是Rpc编码的。但如果你想控制每一个方法,可以在每一个方法上用SoapRpcMethodAttribute特性。

      [webMethod]

      [SoapRpcMethod]

      public POReceipt PurchaseOrder(PO PurchaseOrder)

      {

        POReceipt receipt;

        return receipt;

      } 

    构建单向服务

    返回(202 Accepted);但不会有任何其他消息返回、

        返回值为Void的方法可以成为单向操作,除此之外,只需要把SoapDocumentMethodAttribute或者SoapRpcMethodAttribute属性的OneWay属性设置为True

      例如:

        [webMethod]

        [SoapRpcMethod(OneWay=true)]

        public void SubmitPurchaseOrder(PO PurchaseOrder)

        {

          retrun;

        }

      单向服务提供了一种快捷,激发并遗忘(fire-and-forget)的方式来发送消息的简单方法。它们还能更好地提高服务器的性能,因为在你的代码运行时,在保持打开的网咯连接上花费的时间更少。但是如果你要发送一个错误响应到客户端,将无法做到的。

    控制路由  

        如果你有不止一个方法被标记为[webMethod],asp.net 如何来决定哪个方法应该接收和处理这个请求呢?Asp.net有两种选择机制,用于路由或分发:

          使用SoapAction HTTP标头

          使用<Body>元素的第一个元素

      你可以用SoapDocumentServic和SoapRpcService特性来控制路由的方法,默认的情况路由是使用SoapAction的值完成的。这需要服务中每个操作有一个唯一 的SOAPAction,如果做不到你可以是用<Body>元素的第一个元素来代替。

      例如:

        [SoapDocumentService(RoutingStyle=SoapServiceRoutingStyle.RequestElement)]

        public class routing:System.web.Services.webService

        {}

        还有就是要引入命名空间:System.web.Services.Protocols;

    使用SOAP绑定

        webService描述语言(WSDL)是一种基于 XML的语法,用于描述XML WebService。 WSDL令人感兴趣的一个特征是它有对操作进行抽象的描述的能力,或者通常说的绑定(binding).

        使用webServiceBindingAttribute特性来指明一个webservice实现了一个众所周知的抽象绑定。

      这个特性会在自动生成的WSDL文档创建一个WSDL输入语句。然后通过SoapDocumentMethodAttribute或SoapRpcMethodAttribute,或者两者,指明在服务中那些方法实现在绑定中描述的那些操作。

    异步实现一个服务器 

        使用SOAP标头,先不管它有什么用途。

         1.创建一个派生于System.Web.Services.Procotols.SoapHeader类的类,它就是你要的序列化成SOAP的类

         2.在类中添加前面这个类类型的一个成员变量

         3、在任何你想要使用SOAP标头的方法上应用[SoapHeader]特性

         4.使用这个成员变量读写数据到标头中

          类中要引用System.Web.Services.Procotols和System.Xml.Serialization

          public Class AuthHeader:SoapHeader

          {  

              public string UserName;

              public string PassWord;

              [XmlAttribute]

              public String Domain;

          }

          public Class HeaderTest

          {  

              public AuthHeader auth;

              [webMethod]

              [SoapHeader("auth")]

              public String WhoAmI()

              {

                  retrun auth.UserName;

              }

          } 

        [SoapHeader]特性包含许多属性,包括描述标头的指示(Direction)属性,默认值为Out,或者 in或out。

         public Class HeaderTest

          {  

              public AuthHeader auth;

              [webMethod]

              [SoapHeader("auth",Direction=SoapHeaderDirection,InOut)]

              public String WhoAmI()

              {

                  retrun auth.UserName;

              }

          } 

  • 相关阅读:
    10年学到的编程经验总结
    测试框架 Mocha 实例教程
    在 Flutter 中玩转 Objective-C Block
    使用Gulp压缩混淆JS的相关配置
    Gulp前端自动化构建工具
    常用的十大 NodeJS 框架
    如何使用Vue中的嵌套插槽(包括作用域插槽)
    通过Python代码操作MySQL:
    使用python发邮件:
    jquery:
  • 原文地址:https://www.cnblogs.com/jzhou/p/3152928.html
Copyright © 2011-2022 走看看