热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何理解.asmx处理程序提供的XML映射功能

本篇文章为大家展示了如何理解.asmx处理程序提供的XML映射功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能

本篇文章为大家展示了如何理解.asmx处理程序提供的XML映射功能,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。

将 XML映射到对象
在 WebMehod 处理程序确定了要调用的方法之后,它需要将 XML 消息反序列化为可在方法调用过程中提供的 .NET 对象。如同消息调度一样,该处理程序通过以下方法来实现上述目标:通过反射来检查该类,以便确定如何处理传入的 XML 消息。XmlSerializer 类在 System.Xml.Serialization 命名空间中自动完成 XML 和对象之间的映射。

XmlSerializer 使将任何公共的 .NET 类型映射到 XML 架构类型成为可能,在建立了这样的映射之后,它可以在 .NET 对象和 XML 实例文档之间自动映射(请参阅图 4)。目前,XmlSerializer 被限制于 XML 架构所支持的模型中,因此无法处理当今所有复杂的现代对象模型,例如,复杂的非树型对象图、双重指针等。不过,XmlSerializer 能够处理开发人员倾向使用的大多数复杂类型。

对于上面说明的 Add 示例,XmlSerializer 会将 x 和 y 元素映射为 .NET 双精度值,这些值随后会在调用 Add 时提供。Add 方法向调用方返回一个双精度值,该值随后将需要重新序列化为 SOAP 响应中的一个 XML 元素。

如何理解.asmx处理程序提供的XML映射功能

图 4. 将 XML映射到对象
XmlSerializer 还可以自动处理复杂的类型(除了上面描述的限制)。例如,下面的 WebMethod 计算两个 Point 结构之间的距离:

using System;   using System.Web.Services;   public class Point {   public double x;    public double y;   }   [WebService(Namespace="urn:geometry")]   public class Geometry {   [WebMethod]   public double Distance(Point orig, Point dest) {   return Math.Sqrt(Math.Pow(orig.x-dest.x, 2) +   Math.Pow(orig.y-dest.y, 2));   }   }

此操作的 SOAP 请求消息将包含一个 Distance 元素,该元素中包含两个子元素,一个叫做 orig,另一个叫做 dest,它们都应当包含 x 和 y 子元素,如下所示:

< soap:Envelope    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"   >   < soap:Body>   < Distance xmlns="urn:geometry">   < orig>   < x>0< /x>   < y>0< /y>   < /orig>   < dest>   < x>3< /x>   < y>4< /y>   < /dest>   < /Distance>   < /soap:Body>   < /soap:Envelope>

在本例中,SOAP 响应消息将包含一个 DistanceResponse 元素,该元素包含一个双精度类型的 DistanceResult 元素:

< soap:Envelope    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"   >   < soap:Body>   < DistanceResponse    xmlns="urn:geometry">   < DistanceResult>5< /DistanceResult>    < /DistanceResponse>   < /soap:Body>   < /soap:Envelope>

默认的 XML映射将方法的名称用作请求元素的名称,将参数的名称用作请求元素的子元素的名称。每个参数的结构都取决于类型的结构。公共字段和属性的名称只是映射到子元素(在本例中是 Point 中的x 和 y)。在默认情况下,响应元素的名称是请求元素的名称后面加上 "Response"。响应元素也包含一个子元素,名称是请求元素的名称后面加上 "Result"。

您可以通过使用大量的内置映射属性从标准的 XML 映射中解放出来。例如,可以使用 [XmlType] 属性来自定义类型的名称和命名空间。可使用 [XmlElement] 和 [XmlAttribute] 属性来控制参数或类成员分别映射到元素或属性的方式。还可以使用 [SoapDocumentMethod] 属性来控制方法本身如何映射到请求/响应消息中的元素名称。例如,使用散布于下面程序片段中的多种属性检查如下版本的 Distance:

using System;   using System.Web.Services;   using System.Web.Services.Protocols;   using System.Xml.Serialization;   public class Point {   [XmlAttribute]   public double x;   [XmlAttribute]    public double y;   }   [WebService(Namespace="urn:geometry")]   public class Geometry {   [WebMethod]   [SoapDocumentMethod(RequestElementName="CalcDistance",   RespOnseElementName="CalculatedDistance")]   [return: XmlElement("result")]   public double Distance(   [XmlElement("o")]Point orig, [XmlElement("d")]Point dest) {   return Math.Sqrt(Math.Pow(orig.x-dest.x, 2) +   Math.Pow(orig.y-dest.y, 2));   }   }

这个版本的 Distance 希望传入具有如下外观的 SOAP 消息:

< soap:Envelope    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"   >   < soap:Body>   < CalcDistance xmlns="urn:geometry">   < o x="0" y="0" />   < d x="3" y="4" />   < /CalcDistance>   < /soap:Body>   < /soap:Envelope>

而且,它将生成一个如下所示的 SOAP 响应消息:

< soap:Envelope    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"   >   < soap:Body>   < CalculatedDistance xmlns="urn:geometry">   < result>5< /result>   < /CalculatedDistance>   < /soap:Body>   < /soap:Envelope>

.asmx 处理程序使用 SOAP document/literal 样式来实现和描述上面显示的默认映射。这意味着该 WSDL 定义将包含用来描述 SOAP 消息中所使用的请求和响应元素的字面上的 XML 架构定义(例如,不使用 SOAP 编码规则)。

.asmx 处理程序还可以使用 SOAP rpc/encoded 样式。这意味着 SOAP 正文中包含一个 RPC 调用的 XML 表示形式,而且参数都使用 SOAP 编码规则(例如,不需要 XML 架构)进行了序列化。为了实现这个目标,可以使用 [SoapRpcService] 和 [SoapRpcMethod] 属性,而不使用 [SoapDocumentService] 和 [SoapDocumentMethod] 属性。有关这些样式之间的区别的更多信息,请查看 Understanding SOAP。

正如您所看到的一样,可以完全自定义给定方法映射到 SOAP 消息的方式。XmlSerializer 提供一个功能强大的序列化引擎,以及许多我们在本文中没有时间进行讨论的功能。有关 XmlSerializer 如何工作的更多信息,请查看 Moving to .NET and Web Services。在我的每月 MSDN Magazine 的 XML Files 专栏(可在联机存档中查看专栏列表)中,我还介绍了 XmlSerializer 的许多不易察觉的细微差别。

除了对参数的反序列化进行处理以外,.asmx 处理程序还能够对 SOAP 头进行反序列化/序列化。SOAP 头的处理方法与参数不同,因为它们通常被视为带外信息,并未直接关联到某个特定的方法。因此,SOAP 头的处理通常是通过侦听层完成的,从而使得 WebMethod 完全无须对 SOAP 头进行处理。

但是,如果您希望亲自处理 WebMethod 中的头信息,则必须提供一个从 SoapHeader 派生的 .NET 类,此类代表该头的 XML 架构类型(遵循上面描述的同一映射准则)。然后定义该类型的成员变量,以便让其充当头实例的占位符。***,批注每个需要访问该头的 WebMethod,以便指定您想要到达的字段的名称。

例如,考虑下面的 SOAP 请求,其中包含有一个用于进行身份验证的 UsernameToken 头:

< soap:Envelope    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"   >   < soap:Header>   < x:UsernameToken xmlns:x="http://example.org/security">   < username>Mary< /username>   < password>yraM< /password>   < /x:UsernameToken>   < /soap:Header>   < soap:Body>   < CalcDistance xmlns="urn:geometry">   ...

为了使 .asmx 处理程序能够反序列化该头,首先需要定义一个表示隐含的 XML 架构类型的 .NET 类(注:如果您实际上已经知道了该头的 XML 架构,则可以使用 xsd.exe /c 来生成该类)。在本例中,相应类的外观如下所示:

[XmlType(Namespace="http://example.org/security")]   [XmlRoot(Namespace="http://example.org/security")]   public class UsernameToken : SoapHeader {   public string username;   public string password;   }

接着,只需在 WebMethod 类中定义一个用来保存头类的实例的成员变量,并用 [SoapHeader] 属性批注 WebMethod,如下所示:

using System;   using System.Web.Services;   using System.Web.Services.Protocols;   [WebService(Namespace="urn:geometry")]   public class Geometry {   public UsernameToken Token;   [WebMethod]   [SoapHeader("Token")]   public double Distance(Point orig, Point dest) {   if (!Token.username.Equals(Reverse(Token.password)))   throw new Exception("access denied");   return Math.Sqrt(Math.Pow(orig.x-dest.x, 2) +   Math.Pow(orig.y-dest.y, 2));   }   }

然后,您可以在 WebMethod 中访问 Token 字段并提取在该头中提供的信息。您也可以使用同样的方法将头重新发送到客户端 — 您只需在 [SoapHeader] 属性中指定头的方向。有关在 WebMethod 框架中处理 SOAP 头的更多信息,请查看 Digging into SOAP Headers with the .NET Framework。

.asmx 处理程序也提供了 .NET 异常的自动序列化。由 .asmx 处理程序捕获的任何未经处理的异常都自动序列化为响应中的 SOAP Fault 元素。例如,在上例中,如果用户名与反转密码不匹配,代码将引发一个 .NET 异常。.asmx 处理程序随后将捕获该异常,并将它序列化为 SOAP 响应,如下所示:

< soap:Envelope    xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"   >   < soap:Body>   < soap:Fault>   < faultcode>soap:Server< /faultcode>       < faultstring>Server was unable to process request. --> access denied< /faultstring>   < detail />   < /soap:Fault>   < /soap:Body>   < /soap:Envelope>

如果您希望对 SOAP Fault 元素进行更多的控制,则还可以显式引发 SoapException 对象,以便指定所有的 SOAP Fault 元素细节,例如,faultcode、faulstring、faultactor 和 detail 元素。有关更多信息,请查看 Using SOAP Faults。

正如您所看到的一样,要知晓 WebMethod 如何工作必须了解基础序列化引擎及其各种选项。序列化引擎的好处在于,它隐藏了所有的基础 XML API 代码,而在自定义处理程序中,您通常必须编写这些代码。尽管多数开发人员发现这很好,但是,有一些开发人员却认为它是一个缺陷,因为他们仍希望亲自处理 WebMethod 实现中的原始 SOAP 消息。

上述内容就是如何理解.asmx处理程序提供的XML映射功能,你们学到知识或技能了吗?如果还想学到更多技能或者丰富自己的知识储备,欢迎关注编程笔记行业资讯频道。


推荐阅读
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • Spring源码解密之默认标签的解析方式分析
    本文分析了Spring源码解密中默认标签的解析方式。通过对命名空间的判断,区分默认命名空间和自定义命名空间,并采用不同的解析方式。其中,bean标签的解析最为复杂和重要。 ... [详细]
  • t-io 2.0.0发布-法网天眼第一版的回顾和更新说明
    本文回顾了t-io 1.x版本的工程结构和性能数据,并介绍了t-io在码云上的成绩和用户反馈。同时,还提到了@openSeLi同学发布的t-io 30W长连接并发压力测试报告。最后,详细介绍了t-io 2.0.0版本的更新内容,包括更简洁的使用方式和内置的httpsession功能。 ... [详细]
  • 本文介绍了如何使用C#制作Java+Mysql+Tomcat环境安装程序,实现一键式安装。通过将JDK、Mysql、Tomcat三者制作成一个安装包,解决了客户在安装软件时的复杂配置和繁琐问题,便于管理软件版本和系统集成。具体步骤包括配置JDK环境变量和安装Mysql服务,其中使用了MySQL Server 5.5社区版和my.ini文件。安装方法为通过命令行将目录转到mysql的bin目录下,执行mysqld --install MySQL5命令。 ... [详细]
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
  • 本文讨论了如何在codeigniter中识别来自angularjs的请求,并提供了两种方法的代码示例。作者尝试了$this->input->is_ajax_request()和自定义函数is_ajax(),但都没有成功。最后,作者展示了一个ajax请求的示例代码。 ... [详细]
  • 如何查询zone下的表的信息
    本文介绍了如何通过TcaplusDB知识库查询zone下的表的信息。包括请求地址、GET请求参数说明、返回参数说明等内容。通过curl方法发起请求,并提供了请求示例。 ... [详细]
  • 本文介绍了OpenStack的逻辑概念以及其构成简介,包括了软件开源项目、基础设施资源管理平台、三大核心组件等内容。同时还介绍了Horizon(UI模块)等相关信息。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • Windows下配置PHP5.6的方法及注意事项
    本文介绍了在Windows系统下配置PHP5.6的步骤及注意事项,包括下载PHP5.6、解压并配置IIS、添加模块映射、测试等。同时提供了一些常见问题的解决方法,如下载缺失的msvcr110.dll文件等。通过本文的指导,读者可以轻松地在Windows系统下配置PHP5.6,并解决一些常见的配置问题。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • 单点登录原理及实现方案详解
    本文详细介绍了单点登录的原理及实现方案,其中包括共享Session的方式,以及基于Redis的Session共享方案。同时,还分享了作者在应用环境中所遇到的问题和经验,希望对读者有所帮助。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • Spring学习(4):Spring管理对象之间的关联关系
    本文是关于Spring学习的第四篇文章,讲述了Spring框架中管理对象之间的关联关系。文章介绍了MessageService类和MessagePrinter类的实现,并解释了它们之间的关联关系。通过学习本文,读者可以了解Spring框架中对象之间的关联关系的概念和实现方式。 ... [详细]
author-avatar
手机用户2502923513
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有