1. Trang chủ
  2. » Công Nghệ Thông Tin

Building XML Web Services for the Microsoft .NET Platform phần 6 ppsx

38 346 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Building Xml Web Services For The Microsoft .Net Platform
Trường học University of Information Technology
Chuyên ngành Computer Science
Thể loại Bài tập lớn
Năm xuất bản 2025
Thành phố Ho Chi Minh City
Định dạng
Số trang 38
Dung lượng 261,89 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

/// public Securities { string urlSetting = System.Configuration.ConfigurationSettings.AppSettings ["SecuritiesWebServiceUrl"]; } The constructor sets the object’s Url property to t

Trang 1

Table 6-11: Selected Properties, Methods, and Events of the SoapHttpClientProtocol

Class

group to use when connecting to the Web service A connection group provides a mechanism for allowing multiple clients within the same application to share connections open to a given Web server

CookieContainer Used to access the cookies maintained by the proxy Also

provides a mechanism for setting cookies for a particular domain

Credentials Specifies authentication credentials that can be used to

log into the Web server The supported methods of authentication include Basic Authentication, Windows NT Challenge/Response, Kerberos, and Digest

PreAuthenticate Specifies whether the authentication credentials should

be sent immediately or as a result of receiving a 401 access denied error

Proxy Contains the information necessary to connect to the

proxy server This includes the URL, port, and user name/domain/password

RequestEncoding Specifies the type of encoding that will be used when

serializing the request message The default is UTF-8

Timeout Specifies the period of time, in milliseconds, that a

synchronous Web request has to complete before the request is aborted The default is infinity (−1)

Url Specifies the address of the Web service endpoint

UserAgent Specifies the value of the user agent header in the HTTP

request

Abort Used to abort any asynchronous method calls that are

currently executing

Discover Used to dynamically discover the location of the Web

service via the DISCO file referenced by the Url property

// -// <autogenerated>

// This code was generated by a tool

Trang 2

The date and time can be recorded by promptly checking the file into a source code

repository or by adding it as a comment to the generated file The WSDL document can be obtained by WSDL.exe itself You can accomplish this by using one of the optional

command-line parameters I discuss later in this section

[System.Xml.Serialization.SoapIncludeAttribute(typeof(SoapPaymentHeader))]

public class Securities : System.Web.Services.Protocols

SoapHttpClientProtocol {

public SoapPaymentHeader SoapPaymentHeaderValue;

Trang 3

public SoapReceiptHeader SoapReceiptHeaderValue;

The Securities class is defined within the BrokerageFirm namespace It is derived from the

SoapHttpClientProtocol class SoapHttpClientProtocol serves as the base class for all

ASP.NET proxies and contains the implementation necessary to communicate with most HTTP-based Web services

The Securities class is also decorated with three attributes The first is the

WebServiceBinding attribute, which serves the exact same role on the client as it does on

the Web service This attribute allows you to formally reference a particular binding defined

within another namespace The two other attributes are SoapInclude attributes They tell the XML Serializer to include the SoapPaymentHeaderValue and the SoapReceiptHeaderValue

member variables within the SOAP message

/// <remarks/>

public Securities() {

string urlSetting =

System.Configuration.ConfigurationSettings.AppSettings ["SecuritiesWebServiceUrl"];

}

The constructor sets the object’s Url property to the value of the SecuritiesWebServiceUrl

application configuration parameter defined in the application’s configuration file If the value

is not found, the Url property is set to the value contained within the HTTP extension

element that defines the address of the endpoint within the WSDL document’s service

definition

You should consider modifying the else logic to throw an exception instead of defaulting to a

hard-coded value This will make it easier to diagnose some problems within your

application For example, when you are trying to debug your application, it would be easy to

overlook the fact that the SecuritiesWebServiceUri parameter is misspelled within your

configuration file (Did you catch the misspelling?)

You might need to dynamically modify the Url property at run time For example, the

application might want to reissue its request to another server in the event of failure The Url

property is a publicly exposed read/write property, so it can be modified by the client at run time

You can also set the Url property to point to a DISCO file containing a reference to the

targeted Web service You can then call the Discover method to dynamically bind to the Web

service contained within the DISCO file I will cover DISCO files in more detail in Chapter 10

Trang 4

is for synchronously invoking the Web method, and the other two are used in combination to invoke the Web method asynchronously Here is the synchronous definition for the

InstantQuote method:

[System.Web.Services.Protocols.SoapHeaderAttribute

"SoapReceiptHeaderValue", Direction=System.Web.Services Protocols.SoapHeaderDirection.Out)]

The InstantQuote method is decorated with the SoapHeader, DebuggerStepThrough, and

SoapRpcMethod attributes The DebuggerStepThrough attribute is used by the Visual Studio

.NET debugger The Visual Studio NET debugger will not stop within the method marked

with this attribute

The SoapHeader and SoapRpcMethod attributes serve the same purpose as they do when applied to a Web method The SoapHeader attribute indicates which member variable

should be serialized into the header of the SOAP message The SoapRpcMethod attribute

indicates the encoding style and the format of the message as well as the value of the SOAP

HTTPAction header

The signature of the method itself is composed of NET types that match their XML

counterparts described within the types section of the WSDL document This wrapper

method definition allows code written against the proxy to take full advantage of the features provided by the NET platform For example, if a client attempts to pass invalid parameters,

such as passing two strings to the Add method instead of two integers, the compiler will

generate errors at compile time Developers using Visual Studio NET will also have full

IntelliSense capabilities when they write code against the proxy

The implementation of the InstantQuote method packages the parameters into an array of objects and calls the Invoke method Because this method is publicly exposed, you can call

it directly However, using the method exposed by the WSDL.exe-generated proxy provides

a more convenient and natural calling convention

In many circumstances, making a synchronous call to a Web method is not ideal This is especially true for Web services accessed via the Internet, where quality and speed of the connection might be uncertain This might also be true for Web services hosted within the walls of a corporate data center For example, a Web service might be used to expose data

Trang 5

contained within a mainframe A significant amount of initialization might need to be done to set up a connection to the mainframe, or the Web service might be accessed during times of peak load

The next two methods defined for the InstantQuote operation are BeginInstantQuote and

EndInstantQuote These methods are used to make an asynchronous call to the Securities

Web service’s InstantQuote Web method:

/// <remarks/>

public System.IAsyncResult BeginInstantQuote(string symbol, CurrencyType targetCurrency, System.AsyncCallback callback, object asyncState) {

By convention, the method used to invoke the asynchronous call is prefixed with Begin and

the method used to retrieve the parameters returned by the Web service is prefixed with

End The implementation invok es the BeginInvoke and EndInvoke methods, respectively

The asynchronous methods are not decorated with attributes used to describe the formatting

of the message The methodName parameter contains the name of the method that the

ASP.NET runtime will use to retrieve the formatting information If the asynchronous

message is decorated with any attributes such as SoapDocumentMethod, these attributes

will be ignored

[System.Xml.Serialization.SoapTypeAttribute("SoapReceiptHeader", "http://woodgrovebank.com/Securities/encodedTypes")]

public class SoapReceiptHeader : SoapHeader {

Trang 6

public enum CurrencyType {

attribute to explicitly define type information used by the XML Serializer to map the NET

types to their XML Schema counterparts

The use of the proxy to make a synchronous method call is fairly trivial The following

example writes the price of a security passed as a command-line argument out to the

console:

Trang 7

string symbol = args[0];

Securities securities = new Securities();

// Create and initialize the Payment header

SoapPaymentHeader paymentHeader = new SoapPaymentHeader(); paymentHeader.CreditCardNumber = "12345";

}

Because the Payment header is required to be passed to the InstantQuote method, I create

a new SoapPaymentHeader object Then I initialize it and set it to the

SoapPaymentHeaderValue property on the securities object The proxy is responsible for

serializing the SoapPaymentHeader object within the header of the SOAP request message Invoking the InstantQuote Web met hod asynchronously involves a little more work The

following code is contained within a WinForm application Let’s walk through an example I will write a console application that uses the Securities Web service proxy to make an

asynchronous method call:

static Securities securities = new Securities();

First I create a class that will contain the console application Then I create a static instance

of the Securities Web service proxy as a static member of the class I do this because the

Trang 8

static void Main(string[] args)

{

string symbol = args[0];

SoapPaymentHeader paymentHeader = new

As you have learned, WSDL.exe will properly handle generating proxies for Web services

that support headers The generated proxy code will contain a class declaration for each

header defined by the Web service Depending on the direction of the header, instances of the header class can be either retrieved or set using an associated property defined by the proxy class for the Web service By default, the property will have the same name as the

class, with a prefix of Value If the class declaration contains an XmlType attribute

(discussed in Chapter 7), the property on the client will simply be the name given to the XML type

The proxy class will also perform client-side validation of the SOAP headers before sending

the message to the server For example, the proxy will throw a SoapException if

SoapPaymentHeaderValue was set to null when the Web method was invoked

Within the Main function, a call is made to the BeginInstantQuote method This method

accepts two parameters in addition to the securities symbol and the target currency of the

quote I also pass an instance of the AsyncCallback delegate that serves as a reference to the InstantQuoteCallback method I will define shortly This tells the Web service proxy to execute the InstantQuoteCallback method once the Web service returns If there is no

callback method that should be invoked, you can pass null for the value of the parameter

The fourth parameter is intended to pass state that should be associated with the method

once the callback has been invoked The parameter is of type object and therefore accepts

an instance of any NET type In this case, I pass the symbol of the security for which I have requested the quote

public static void InstantQuoteCallback(IAsyncResult result) {

// Obtain the results

double price = securities.EndInstantQuote(result);

Trang 9

// Obtain the additional state that was sent by

// the call to BeginCallback

WebClientAsyncResult webResult =

(WebClientAsyncResult)result;

string symbol = (string)webResult.AsyncState;

// Display the results within a message box

Console.WriteLine("{0} = {1}", symbol, price);

to obtain the return value of the Web method call Next I obtain the additional state

information from the AsyncState property—in this case, the symbol passed to the Add

method Finally the price of the security is written to the console

Cookies

Proxies derived from SoapHttpClientProtocol fully support HTTP cookies However, the

proxies have cookies disabled by default To enable cookie support, you must set the

CookieContainer property on the proxy object to reference an instance of a CookieContainer

object

Earlier in the chapter, I leveraged session state to configure the target currency The client

first sets the target currency by calling SetCurrency Then the client calls InstantQuote to

obtain the price of the security Because the Web service relies on cookies to maintain

session state, clients using this Web service need to explicitly enable cookies The following code demonstrates how to enable session state:

string symbol = args[0];

Securities securities = new Securities();

// Enable session state by creating a new cookie container securities.CookieContainer = new CookieContainer();

Trang 10

// Receive a quote on the requested security in UK pounds securities.SetCurrency(CurrencyType.UK_POUNDS);

Summary

ASP.NET provides a robust, feature-rich platform for easily creating and consuming Web

services For a V1 product, it is remarkably feature complete

An ASP.NET Web service is represented by an asmx file hosted within an IIS Web

application The implementation of the Web service can be contained within the asmx file or within a compiled DLL If the code appears inline within the asmx file, the ASP.NET runtime will automatically compile it the first time it is accessed

A Web service is defined by a standard public class declaration Public methods defined

within the class can be exposed by the Web service if you decorate the method with the

WebMethod attribute This attribute exposes properties that can be optionally set to control

the behavior of the ASP.NET runtime The class can also be decorated with the WebService

attribute

All ASP.NET Web services expose a SOAP interface over HTTP Depending on the

complexity of the Web service’s interface, an ASP.NET Web service might also support

HTTP GET and HTTP POST The ASP.NET runtime will automatically map data contained within requests from the client and their corresponding responses to their corresponding

.NET datatypes

The ASP.NET platform will automatically generate documentation for the Web service A

human-readable HTML version of the documentation can be obtained by calling the asmx file with no parameters A programmatic WSDL version of the documentation can be

obtained by appending &wsdl to the URL that addresses the asmx file

ASP.NET supports two distinct encoding styles, Document and RPC Document is the

default and is used primarily for document-based message exchanges between the client and the server RPC is used primarily for procedure-based communication between the

client and the server You can select RPC by using the SoapRpcService or SoapRpcMethod

attribute

You should be careful when you pass value types as parameters because the ASP.NET

platform has some inconsistencies when identity is maintained The identities of built-in

value types such as int and double are never maintained, even when passed by reference

The identity of a custom value type when passed by reference is maintained when the

encoding style is set to RPC However, the identity of custom value types passed by value is improperly maintained when the encoding style is set to RPC

Regardless of the style of encoding, SOAP formally defines how errors returned to the client should be encoded within a SOAP message The ASP.NET runtime will automatically map

Trang 11

.NET exceptions into a well-formed SOAP Fault element You can also formally raise a fault

by throwing an exception of type SoapException

You can facilitate interface inheritance by referencing a port type or a binding definition from

an external namespace Of the two, ASP.NET supports referencing transport-specific

binding definitions You first reference the remote binding definition with the

WebServiceBinding attribute, and then you associate the reference to the binding with a

particular Web method via the Binding property of the SoapRpcMethod or

SoapDocumentMethod attribute

ASP.NET also provides a fairly robust state management system It supports three

configurations: In Process, Out of Process, and SQL Server Of the three, In Process is the most performant configuration You should consider Out of Process and SQL Server only if the Web service will be deployed on a Web farm Regardless of which model you use, the programming model is exactly the same

The ASP.NET platform also has good support for defining and consuming SOAP headers A

SOAP header is defined by deriving from the SoapHeader class You then use the

SoapHeader attribute to associate the header with a particular Web method ASP.NET

automatically deserializes any headers received from the client and serializes any headers sent from the Web server

Finally, the ASP.NET framework provides an interception mechanism called SOAP

extensions The SOAP extensions framework lets you examine and, if necessary, modify the contents of the SOAP messages exchanged between the client and the server

I didn’t cover a couple of key topics related to ASP.NET Web services because they deserve chapters of their own In Chapter 7, I will discuss how to control how individual parameters passed by a Web service or its client are encoded within a SOAP message In Chapter 9, I will also cover the security services provided by ASP.NET

Trang 12

Chapter 7: XML Serialization

Overview

The ASP.NET runtime is built on top of a technology called XML serialization XML

serialization is responsible for serializing instances of NET types to XML and deserializing XML to instances of NET types XML serialization is also responsible for serializing NET type definitions to XML schemas and deserializing XML schemas to NET type definitions Sometimes, this default behavior might not entirely meet your needs For example, public properties and fields will be serialized into elements within the resulting XML document, but many existing and emerging Web services interfaces such as UDDI and NET My Services expose interfaces that use attributes Therefore, you need a means of controlling how NET types and instances of NET types are serialized into XML

Consider the following SOAP message, which submits a purchase order:

<Name accountNumber="12345">ABC Company</Name>

<Street>123 Some Street</Street>

<Name accountNumber="12345">ABC Company</Name>

<Street>123 Some Street</Street>

Trang 13

The message contains a mixture of elements and attributes For example, the part number

for each item listed in the purchase order is serialized within the partNumber attribute of

each Item element The Name element within the billing and shipping addresses contains

the name of the company as well as an attribute that contains the company’s account

number

Controlling XML Serialization

For situations in which the default serialization support is not adequate, XML serialization

provides mechanisms for altering the way NET types are serialized to XML You do this

mostly by using the attributes defined in the System.Xml.Serialization namespace, which

Table 7-1 describes

Table 7-1: XML Serialization Attributes

XmlAnyAttribute Creates an “open” XML datatype in which any attribute can be

added to its root node

XmlAnyElement Creates an “open” XML datatype where any element can be

included as a child element

XmlArray Controls how the root node of an array is serialized

XmlArrayItem Controls how an item of an array is serialized

XmlAttribute Indicates that a public field, property, or parameter should be

serialized as an attribute

XmlElement Controls how a public field, property, or parameter is serialized as

an element

XmlEnum Controls how an enumeration is serialized

XmlIgnore Indicates that XML serialization should not serialize the

Trang 14

Table 7-1: XML Serialization Attributes

member

XmlInclude Tells XML serialization to include a particular datatype definition of

a class that derives from a base class exposed by a Web service’s interface

XmlRoot Identifies a type as the root of an XML document

XmlText Specifies that the member variable be serialized as the content of

the parent element

XmlType Maps an XML type to a particular class, structure, enumeration, or

interface declaration You can use the XML serialization attributes only with literal, document- oriented SOAP

messages For example, the attributes will be ignored if the Web method is decorated with

the SoapRpcMethod attribute or is decorated with the SoapDocumentMethod attribute and has the Use property set to SoapBinding-Use.Encoded

The attributes listed in the table control how XML serialization represents NET types in

XML For Web services, the attributes control how instances of.NET types are encoded into the body of a SOAP message They also control how NET types are represented as XML datatypes in the WSDL document that describes the Web service

In this chapter, I use the preceding attributes to create the PurchaseOrder NET type, which

can be used to define how a purchase order is serialized in the body of a SOAP message I

also create the AcceptPO Web method This Web method is used to receive purchase

orders similar to the one in the previous example

Defining the Root PurchaseOrder Datatype

The first step is to define the PurchaseOrder class, which will represent the root element

within the body of the SOAP message Recall from Chapter 4 that you can set elements to

null by setting the xsi:nil attribute to true For the SOAP message to be valid, it must not

contain a null reference to the purchase order

The following code defines the PurchaseOrder class:

To define the PurchaseOrder XML datatype, I need to define a public class by the same

name I also need to ensure that the PurchaseOrder element cannot contain a null value I can do this by decorating the class with the XmlRoot attribute

Trang 15

One of the properties exposed by the XmlRoot attribute is IsNullable This property indicates

whether the schema generated by XML serialization will permit instance documents to

contain a PurchaseOrder element with a null value

You can also use the XmlRoot attribute to control the behavior of XML serialization Table

7-2 describes the properties exposed by the XmlRoot attribute

Table 7-2: XmlRootAttribute Properties

Property Description

DataType Specifies the XML datatype in which the class should be encoded

ElementName Specifies the name of the root XML element

Form Specifies whether the XML element must be namespace

qualified It is set to one of three values defined by the

XmlSchemaForm enumeration: None, Qualified, or Unqualified

IsNullable Specifies whether the value of the XML element can be set to xsd:nil

Namespace Specifies the XML namespace in which the root element is

qualified

Most of the elements within the PurchaseOrder document contain attributes or child

elements themselves For example, the BillingAddress and ShippingAddress elements each contain Name, Street, City, State, and ZipCode child elements, as shown here:

<PurchaseOrder>

<BillingAddress>

<Name accountNumber="12345">ABC Company</Name>

<Street>123 Some Street</Street>

<Name accountNumber="12345">ABC Company</Name>

<Street>123 Some Street</Street>

Trang 16

You can model complex structures such as the preceding one using a class hierarchy The

following example defines an Address class and then defines two fields within the

PurchaseOrder class, BillingAddress and ShippingAddress Both fields are defined as type Address

[XmlRoot(IsNullable=false)]

public class PurchaseOrder

{

[XmlElemen t(IsNullable=true, DataType="normalizedString")]

public string Comments;

[XmlElement(IsNullable=false)]

public Address BillingAddress;

[XmlElement(IsNullable=false)]

public Address ShippingAddress;

// Additional type definitions

}

public class Address

{

public CompanyName Name;

public string Street;

public string City;

public string State;

public string ZipCode;

}

The preceding code uses the XmlElement attribute to control how properties and fields are serialized as elements within the resulting XML document For example, the Comments field can contain a null value, but neither the ShippingAddress field nor the BillingAddress field

can be set to null Like the XmlRoot attribute, the XmlElement attribute exposes an

IsNullable property

The Comments element can be set to null because XML serialization does not allow you to

specify that a particular element or attribute be able to optionally occur within a document

This is because the XmlElement attribute does not provide a means of explicitly setting the

minOccurs and maxOccurs constraints on an element I discuss another potential

workaround for this situation later in the chapter

The Comments element contained within the PurchaseOrder document contains text related

to the order In addition to setting the XmlElement attribute’s IsNullable property, the

preceding code sets the DataType property for the Comments field

Trang 17

XML serialization provides a default mapping between NET types and the built-in datatypes

defined by XML Schema For example, the Comments property is defined as type String By default, XML serialization will transform the String type to the XML built-in datatype string

Suppose the back-end system that will record the receipt of the purchase order does not

accept linefeeds or tabs In order to communicate this to the client, I set the datatype of the

Comments element to normalizedString By definition, normalizedString cannot contain

linefeeds or tabs

XML serialization supports all XML built-in datatypes Table 7-3 lists the supported mappings between XML datatypes and NET types

Table 7-3: Mapping Between XML Datatypes and NET Types

base64Binary Byte (array) Int Int32

dateTime DateTime negativeInteger String

duration String nonNegativeInteger String

ENTITY String nonPositiveInteger String

ENTITIES String normalizedString String

gDay String positiveInteger String

hexBinary Byte (array) token String

Even though XML serialization will transform an XML datatype into its corresponding NET

type, it will not perform any validation on the data For example, the XML datatype integer maps to the String NET type, but the client can pass non-numeric data to the Web service

Therefore, it is up to the Web service to enforce additional constraints over and above what

Trang 18

The XmlElement attribute exposes additional properties that you can use to control how a

.NET type is serialized to XML Table 7-4 describes these properties

Table 7-4: XmlElementAttribute Properties

DataType Specifies the XML Schema built-in datatype in which the property

or field should be encoded

ElementName Specifies the name of the XML element

Form Specifies whether the XML element must be namespace qualified

It is set to one of three values defined by the XmlSchemaForm enumeration: None, Qualified, or Unqualified

IsNullable Specifies whether the value of the XML element can have its xsi:nil

attribute set to true

Namespace Specifies the XML namespace in which the element is defined

Type Specifies the NET type that should be used to generate the

schema that describes the element

You can decorate a property or a field with more than one XmlElement attribute Doing so

specifies that an instance document must contain an element that complies with the criteria

specified by one of the XmlElement attributes Here is an example:

public class Person

{

[XmlElement("SocialSecurityNumber")]

[XmlElement("DriversLicenseNumber")]

public string Identifier;

public string Name;

}

The preceding NET type definition creates the following XML datatype definition:

<s:complexType name="Person">

<s:sequence>

<s:choice minOccurs="1" maxOccurs="1">

<s:element minOccurs="1" maxOccurs="1"

Trang 19

</s:complexType>

An instance of the Person XML datatype must contain the person’s name as well as the

person’s driver’s license number or social security number

You can use the XmlType attribute to control how NET types are serialized to an XML

datatype, and you can apply the attribute to a variety of NET type definitions, including

classes, structures, enumerations, and interface definitions You can use the XmlType

attribute to set the name of the resulting XML datatype and the namespace in which the

datatype is defined You can also use it to specify whether a datatype definition will be

generat ed within the Web service’s WSDL document

Table 7-5 describes the properties exposed by the XmlType attribute to control how XML

datatypes are generated

Table 7-5: XmlTypeAttribute Properties

IncludeInSchema Specifies whether the type will be included in the schema

Namespace Specifies the XML namespace in which the XML schema datatype is

qualified

TypeName Specifies the name of the XML datatype that describes the targeted

.NET type

You can also use the XmlIgnore attribute to exclude entities from type definitions For

example, suppose the internal implementation of the AcceptPO Web service needs to track

a processing code The following class definition adds a ProcessingCode public field to the

class for maintaining the state of this information:

public int ProcessingCode;

// Additional type definitions

}

Ngày đăng: 14/08/2014, 10:22

TỪ KHÓA LIÊN QUAN