Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to understand the XML mapping function provided by .asmx processor

2025-02-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article shows you how to understand the XML mapping function provided by the .asmx processor, which is concise and easy to understand, which will definitely brighten your eyes. I hope you can get something through the detailed introduction of this article.

Map XML to object

After the WebMehod handler determines the method to be called, it needs to deserialize the XML message into a .NET object that can be provided during the method call. Like message scheduling, the handler does this by examining the class through reflection to determine how to handle incoming XML messages. The XmlSerializer class automatically completes the mapping between XML and objects in the System.Xml.Serialization namespace.

XmlSerializer makes it possible to map any public .NET type to an XML schema type, and after such a mapping is established, it can automatically map between .NET objects and XML instance documents (see figure 4). Currently, XmlSerializer is limited to the models supported by the XML architecture, so it cannot handle all of today's complex modern object models, such as complex non-tree object graphs, double pointers, and so on. However, XmlSerializer can handle most of the complex types that developers tend to use.

For the Add example illustrated above, XmlSerializer maps x and y elements to .NET double values, which are then provided when Add is called. The Add method returns a double value to the caller, which then re-serializes the need to be a XML element in the SOAP response.

Figure 4. Map XML to object

XmlSerializer can also automatically handle complex types (in addition to the limitations described above). For example, the following WebMethod calculates the distance between two Point structures:

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));}

The SOAP request message for this operation will contain a Distance element that contains two child elements, one called orig and the other called dest, both of which should contain x and y child elements, as shown below:

< 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>

three

< /x>

< y>

four

< /y>

< /dest>

< /Distance>

< /soap:Body>

< /soap:Envelope>

In this example, the SOAP response message will contain a DistanceResponse element that contains a DistanceResult element of a double type:

< soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" >

< soap:Body>

< DistanceResponse xmlns="urn:geometry">

< DistanceResult>

five

< /DistanceResult>

< /DistanceResponse>

< /soap:Body>

< /soap:Envelope>

The default XML mapping uses the name of the method as the name of the request element and the name of the parameter as the name of the child element of the request element. The structure of each parameter depends on the structure of the type. The names of public fields and attributes are simply mapped to child elements (in this case, x and y in Point). By default, the name of the response element is the name of the request element followed by "Response". The response element also contains a child element whose name is the name of the request element followed by "Result".

You can free yourself from standard XML mappings by using a large number of built-in mapping attributes. For example, you can use the [XmlType] attribute to customize the name and namespace of a type. You can use the [XmlElement] and [XmlAttribute] attributes to control how parameters or class members map to elements or attributes, respectively. You can also use the [SoapDocumentMethod] attribute to control how the method itself maps to the element name in the request / response message. For example, check the following version of Distance using a variety of attributes scattered in the following program snippet:

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);}}

This version of Distance wants to pass in SOAP messages with the following appearance:

< 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>

Also, it will generate a SOAP response message like this:

< soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" >

< soap:Body>

< CalculatedDistance xmlns="urn:geometry">

< result>

five

< /result>

< /CalculatedDistance>

< /soap:Body>

< /soap:Envelope>

The .asmx processor uses the SOAP document/literal style to implement and describe the default mapping shown above. This means that the WSDL definition will contain a literal XML schema definition that describes the request and response elements used in SOAP messages (for example, without using SOAP encoding rules).

The .asmx processor can also use the SOAP rpc/encoded style. This means that the SOAP body contains an XML representation of the RPC call, and the parameters are serialized using SOAP encoding rules (for example, no XML schema is required). To achieve this goal, you can use the [SoapRpcService] and [SoapRpcMethod] attributes instead of the [SoapDocumentService] and [SoapDocumentMethod] attributes. For more information about the differences between these styles, see Understanding SOAP.

As you can see, you can completely customize how a given method is mapped to an SOAP message. XmlSerializer provides a powerful serialization engine and many features that we don't have time to discuss in this article. For more information about how XmlSerializer works, see the Moving to .NET and Web Services. In my monthly MSDN Magazine XML Files column (you can see a list of columns in the online archive), I also introduced many of the imperceptible nuances of XmlSerializer.

In addition to deserializing parameters,. Asmx handlers can also deserialize SOAP headers SOAP headers are handled differently from parameters because they are usually treated as out-of-band information and are not directly associated with a particular method. Therefore, the processing of SOAP headers is usually done through the listening layer, so that WebMethod does not have to deal with SOAP headers at all.

However, if you want to handle the header information in WebMethod yourself, you must provide a .NET class derived from SoapHeader that represents the XML schema type of the header (following the same mapping guidelines described above). Then define a member variable of that type so that it acts as a placeholder for the header instance. *, annotate each WebMethod that needs to access the header to specify the name of the field you want to reach.

For example, consider the following SOAP request that contains a UsernameToken header for authentication:

< 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">

...

In order for the .asmx processor to deserialize the header, you first need to define a .NET class that represents the implied XML schema type (note: if you actually know the XML schema for the header, you can use xsd.exe / c to generate the class). In this case, the corresponding class looks like this:

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

Next, simply define a member variable in the WebMethod class to hold the instance of the header class, and annotate the WebMethod with the [SoapHeader] attribute, as shown below:

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);}}

You can then access the Token field in WebMethod and extract the information provided in that header. You can also resend the header to the client using the same method-you just need to specify the direction of the header in the [SoapHeader] attribute. For more information about working with SOAP headers in the WebMethod framework, see the Digging into SOAP Headers with the .NET Framework.

The .asmx handler also provides automatic serialization of .NET exceptions. Any unhandled exceptions caught by .asmx handlers are automatically serialized into SOAP Fault elements in the response. For example, in the above example, if the user name does not match the reverse password, the code throws a .NET exception. The .asmx handler then catches the exception and serializes it into a SOAP response, as shown below:

< 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>

If you want more control over the SOAP Fault element, you can also explicitly throw a SoapException object to specify all the SOAP Fault element details, such as faultcode, faulstring, faultactor, and detail elements. For more information, see Using SOAP Faults.

As you can see, to understand how WebMethod works, you must understand the underlying serialization engine and its various options. The advantage of the serialization engine is that it hides all the underlying XML API code, which you usually have to write in custom handlers. While most developers find this good, some developers consider it a flaw because they still want to handle the raw SOAP messages in the WebMethod implementation themselves.

The above is how to understand the XML mapping function provided by the .asmx processor. Have you learned the knowledge or skills? If you want to learn more skills or enrich your knowledge reserve, you are welcome to follow the industry information channel.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report