Professional ASP.NET 1.1 [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Professional ASP.NET 1.1 [Electronic resources] - نسخه متنی

Alex Homeret

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید






WebMethod and WebService Attributes

Although the

WebMethod attribute will be used most often when authoring ASP.NET Web services, there are other attributes at your disposal that provide additional functionality.Apart from marking a method or property with an attribute, you can set some attribute properties that influence the behavior of attributes, and which in turn affect the target of the attribute. We'll use the following syntax to set attribute properties. Using VB.NET, you would write:


... <AttributeName(PropertyName:="Value")> ...


Note the colon after

PropertyName:="Value" . This syntax is only required for VB.NET. Using C#, you would write:


[AttributeName(PropertyName="Value")]


We won't discuss all the available attributes here – we'll concentrate on the

WebMethod and

WebService attributes. Let's take a detailed look at the

WebMethod attribute.


The WebMethod Attribute


The

WebMethod attribute is used to mark a method or property as Web-callable, and is represented by the

WebMethodAttribute class. There are six properties on the

WebMethod attribute that you can manipulate:



Description



EnableSession



MessageName



TransactionOption



CacheDuration



BufferResponse



Let's examine each of these in turn.

Commenting the WebMethod


The

Description property is used to provide a brief description of the functionality of the Web-callable method or property. Using VB.NET, you could write:


...<WebMethod(Description:="[string]")>...


Using C#, you could write:


[WebMethod(Description="[string]")]


The value of the

Description property is added to the WSDL and to the web service Help page.

Using the Description Property

If you add a

Description property to the Fibonacci example and then request this through the browser, the description shows up under the link for the Web-callable method:

<%@ WebService Language="C#" class="Fibonacci" %>
using System.Web.Services;
public class Fibonacci : WebService{

[WebMethod(Description="Returns value of index into Fibonacci series")]
public int GetSeqNumber(int fibIndex){
if (fibIndex < 2)
return fibIndex;
int[] FibArray = {0,1};
for (int i = 1; i< fibIndex; i++){
FibArray[1] = FibArray[0] + FibArray[1];
FibArray[0] = FibArray[1] - FibArray[0];
}
return FibArray[1];
}
}


When the

.asmx file is requested by a browser, the screen shown in Figure 19-7 appears:


Figure 19-7:

If you view the Service Description (WSDL), you can also see the description as shown in Figure 19-8:


Figure 19-8:

The entries in the

Description property may contain HTML formatting. This formatting is then used to display a description in the Help page. However, keep in mind that the description text is entered into the WSDL. Other applications may consume the WSDL, and they might not understand the HTML tags found in the description.

Enabling Session State


Classes that inherit from the

WebService base class or use the

HttpContext can take advantage of session state to maintain state between calls. Session state, however, involves additional overhead, and is bound to the HTTP protocol since it uses HTTP cookies. Although SOAP is theoretically transport- independent, it relies on the transport protocol for application functionality when HTTP cookies are used. If you moved the SOAP message to SMTP, you wouldn't have the HTTP cookies functionality available.

By default, session state is disabled. To enable session state support, you can use one of the

WebMethod properties,

EnableSession . Using VB.NET, you would write:


...<WebMethod(EnableSession:="[true/false]")>...


Using C#, you would write:


[WebMethod(EnableSession="[true/false]")]


To enable session state,

EnableSession is set to

true (it is

false by default).

One caveat is that the session state is only valid as long as the caller presents the same session

ID . In the next chapter, when we build proxies to use against our web services, session state is available only for the duration of the existence of the proxy instance. The HTTP cookie is never stored on disk, and a new session is created for each new proxy instance, since the proxy, by default, doesn't persist the session cookie containing the

ID . We'll also look at an example of how to persist and reuse the session cookie.

Aliasing Web Method Names


The

MessageName property is used to alias method or property names. The most common use of the

MessageName property is to uniquely identify polymorphic methods within a class that is to be marked as web-callable. Using VB.NET, you would write:


...<WebMethod(MessageName:="[string]")>...


Using C#, you would write:


[WebMethod(MessageName="[string]")]


Using the MessageName Property

Here's a snippet of C# code that has two

Add methods that differ only by method signature:


...

[WebMethod]

public int Add(int a, int b){

return a+b;

}

[WebMethod]

public int Add(int a, int b, int c){

return a+b+c;

}

...


This generates an exception when requested through the browser. Both

Int32 Add(Int32, Int32, Int32) and

Int32 Add(Int32, Int32) use the message name

Add . You can use the

MessageName property of the custom

WebMethod attribute to specify unique message names for the methods. The problem is that ASP.NET cannot differentiate between the two methods, and requires the use of the

MessageName property to differentiate between the method names:

...
[WebMethod]
public int Add(int a, int b){
return a+b;
}

[WebMethod(MessageName="Add2")]
public int Add(int a, int b, int c){
return a+b+c;
}
...


Additionally, the WSDL that is generated must also be able to uniquely identify the element name when it is used to construct a message. When you use the

MessageName property, this is reflected in your WSDL, as shown in Figure 19-9:


Figure 19-9:

The

MessageName property simply aliases our method name.

Building Transacted Web Services


ASP.NET Web services support transactions, but only ones that the web service originates. A transaction cannot be started by another application and then flow into a web service.

Using VB.NET, you would write:


...<WebMethod(TransactionOption:="[TransactionOption]")>...


Using C#, you would write:


[WebMethod(TransactionOption="[TransactionOption]")]


Using the TransactionOption Property

Suppose you had a banking transaction, in which the client makes a web service remote call to a method named

DebitAccount , the transaction started by the client cannot be stretched through the web service remote call. The schematic diagram is shown in Figure 19-10:


Figure 19-10:

In this diagram, a Bank Application begins a transaction (Tx1). It then calls a web service, which begins another transaction (Tx2). The transaction (Tx1) started by the Bank Application does not flow through the web service.

If the web service transaction (Tx2) succeeds, it will allow the application's transaction (Tx1) to continue. However, failure of the

DebitAccount call will fail the application's transaction. The

DebitAccount call, which provides the web service, can also choose to participate in a transaction, but it is a new transaction context, not the transaction context started by the calling application.

The options for using transacted web methods are:



Disabled : We cannot control automatic transactions on the object.



NotSupported : The object does not run within the scope of a transaction, irrespective of whether a transaction already exists or not.



Supported : If a transaction exists, the object runs in the context of that transaction. If there is no existing transaction, the object runs without one.



Required : The object requires a transaction in order to execute. It will either use an existing transaction, or create a new one if none exists.

Required is the default.



RequiresNew : The object requires a new transaction, so a new transaction is created for each request.



Calling

SetComplete or

SetAbort in code is no longer necessary. Simply raising an exception is considered as a

SetAbort , and successful completion of the call is considered a

SetComplete .





Note

The

SetAbort and

SetComplete methods are used to indicate to MTS or COM+ whether a transaction completed or failed.


Caching Web Services


Like ASP.NET pages, ASP.NET Web services support output caching. Output caching allows for the result of a particular resource to be saved to a cache rather than executed on each request. High traffic resources whose data changes infrequently can take advantage of caching for better scalability and performance.

The use of caching for web services is configured on a method-by-method basis through the use of the

WebMethod attribute's

CacheDuration property. Using VB.NET, you would write:


...<WebMethod(CacheDuration:=[int])>...


Using C#, you would write:


[WebMethod(CacheDuration=[int])]


Using the CacheDuration Property

The following is a VB.NET example use of

CacheDuration (

WebMethodCacheDuration.asmx ):


<%@ WebService class="CacheDurationExample" %>


Imports System

Imports System.Web.Services


Public Class CacheDurationExample

<WebMethod(CacheDuration:=30)> Public Function TimeLastCached As String

Return DateTime.Now.ToString("r")

End Function

End Class


This simple sample returns the value of the current time on its first execution. This result is then cached for 30 seconds, and the same result is returned until the cached entry has expired (30 seconds after the initial call), at which time the code will execute again.

Although this simple example highlights that caching is working, what would happen in a more complex example in which the

WebMethod had parameters? You obviously wouldn't want to serve the same response for all requests; you'd rather vary the response on the basis of the request.

For example, if the result that the web service returned from a SQL Server database was dependent on one of the parameters of the

WebMethod , you might not only want to cache the result (for the performance gain), but would also want different variations of that cached result based on the supplied parameters. This is supported by default.

Let's take a look at a VB.NET code sample to illustrate this better (

WebMethodCacheData.asmx ):


<%@ WebService class="DataExample" %>


Imports System.Web.Services

Imports System.Data

Imports System.Data.SqlClient

Public Class DataExample : Inherits WebService

<WebMethod(CacheDuration:=30)> Public Function _

GetDataSet(City As String) As DataSet

If (Application("ProductData" + City) Is Nothing) Then

Application("ProductData" + City) = LoadDataSet(City)

End If


Return CType(Application("ProductData" + City), DataSet)

End Function


Private Function LoadDataSet(City As String) As DataSet

Dim dsn As String

Dim sql As String


dsn = "server=localhost;uid=sa;pwd=;database=pubs"

sql = "SELECT * FROM Authors WHERE City = '" + City + "'"

Dim myConnection As New SqlConnection(dsn)

Dim myCommand As New SqlDataAdapter(sql, myConnection)


Dim products As New DataSet


myCommand.Fill(products, "products")


Return products

End Function

End Class






Note

You might have to alter the server name in the preceding code to reflect your own database.


Here, a

GetDataSet WebMethod accepts a single parameter:

City . The result from the request will be output cached. The ASP.NET Web service is executed once and served statically on subsequent requests for 30 seconds, and the cache will vary based on the different value for

City . If you have a request where the value of

City is

Dallas , the web service will execute once and the result will be cached. If there is another request for

Dallas within the allotted time period of 30 seconds, it will be served from the cache – the ASP.NET Web service does not need to execute and query the database.

This can be a serious performance enhancement, but should be used wisely – only items that vary by a few parameters are good candidates for web services output caching.

Buffering the Server Response


Buffering allows the server to buffer the output from the response, and transmit it only once the response is completely buffered. This might not be optimal for long running methods – you'd rather want to send the response as you receive it rather than wait for the complete response.

By default, ASP.NET Web services buffer the response before sending it, as this is usually most optimal for the server. However, the

BufferResponse property allows you to configure ASP.NET Web services to not buffer the response. By default, this property is set to

true .

Using VB.NET, you would write:


...<WebMethod(BufferResponse:="[true|false]")>...


Using C#, you would write:


[WebMethod(BufferResponse="[true|false]")]


The other attribute we'll look at, the

WebService attribute, gives additional control over the class that contains the Web-callable methods rather than the individual methods.


The WebService Attribute


The

WebService attribute is used to configure properties for the class – rather than the method or property – named in the

WebService directive. These properties apply to the web service Help page as well as the WSDL. It does not, however, mark the methods within the class as Web-callable.

There are three properties of the

WebService attribute that you can manipulate:



Description



Namespace



Name



Commenting the Web Service


The

Description property is used to provide a brief description of the functionality of the class that contains Web-callable methods and properties. It's similar to the

Description property of the

WebMethod attribute, but it's a description for the entire class, not individual methods and properties. Using VB.NET it would be written as:


<WebService (Description:="[string]")> Public Class [Class Name]


Using C# it would be written as:


[WebService(Description="[string]")]

public class [Class Name]


Using the Description Property of the WebService Attribute

The value from the

Description property is added to the WSDL, and is also added to the output generated when the ASP.NET Web service is requested by the browser. For example, you can add a

Description property to the

Fibonacci example (

WebServiceDescription.asmx ):

<%@ WebService Language="C#" class="Fibonacci" %>
using System.Web.Services;

[WebService(Description=

"This class contains methods for working with Fib series")]
public class Fibonacci : WebService{
[WebMethod]
public int GetSeqNumber(int fibIndex){
if (fibIndex < 2)
return fibIndex;
int[] FibArray = {0,1};
for (int i = 1; i< fibIndex; i++){
FibArray[1] = FibArray[0] + FibArray[1];
FibArray[0] = FibArray[1] - FibArray[0];
}
return FibArray[1];
}
}


The output would be as shown in Figure 19-11:


Figure 19-11:

In the WSDL, it would appear as shown in Figure 19-12:


Figure 19-12:

Controlling the Namespace


XML uses namespaces to uniquely identify sections of an XML document. Multiple documents can share markup vocabularies to describe particular regions of information. For example, in the case of two XML documents that both contain an

<Add> element, how can software differentiate between the two elements in the composite document?

Organizations may qualify their markup vocabulary with a universal name that is unique to their markup vocabulary through the use of XML namespaces.

The default namespace that ASP.NET assigns to ASP.NET Web services is http://tempuri.org. tempuri.org will be discussed in the WSDL section of the next chapter. For now, the

Namespace property of the

WebService attribute can be used to change the namespace value to a value of your choosing.

Using VB.NET, it would be written as:


<WebService(Namespace:="[string]")> Public Class [Class Name]


Using C#, it would be written as:


[WebServiceNamespace="[string]")]
public class [Class Name]


Using the Namespace Property

If you viewed the WSDL from either the VB or C# Fibonacci Web service, you would see http://tempuri.org/ used for the value of the namespace. To change the namespace to http://rhoward/Fibonacci

/ , you could make the following change to the code (

WebServiceNamespace.asmx ):

<%@ WebService Language="C#" class="Fibonacci" %>
using System.Web.Services;

[WebService(Namespace="http://rhoward/Fibonacci/")]
public class Fibonacci : WebService{
[WebMethod]
public int GetSeqNumber(int fibIndex){
if (fibIndex < 2)
return fibIndex;
int[] FibArray = {0,1};
for (int i = 1; i< fibIndex; i++){
FibArray[1] = FibArray[0] + FibArray[1];
FibArray[0] = FibArray[1] - FibArray[0];
}
return FibArray[1];
}
}


Now the WSDL appears as shown in Figure 19-13:


Figure 19-13:

This affects what our SOAP message looks like, as shown in Figure 19-14:


Figure 19-14:

Changing the Name of the Web Service


When the WSDL is generated for an ASP.NET Web service, the name of the class is used for the

service name value within the WSDL. When a proxy uses the WSDL and builds a proxy class, the name of the class generated corresponds to the

name value of

service . The

Name property of the

WebService attribute allows you to override the default value.

Using VB.NET, you would write:


<WebService(Name:="[string]")> Public Class [Class Name]


Using C#, you would write:


[WebService(Name="[string]")]


Using the Name Property

If you viewed the WSDL of the

Fibonacci class, you would see the output as shown in Figure 19-15:


Figure 19-15:

If you set the

Name value to

WebServiceExample in the

WebService attribute (as in

WebServiceName.asmx ):


[WebService(Name="WebServiceExample")]


You would see the change in the WSDL as shown in Figure 19-16. All instances of

Fibonacci in the WSDL have been replaced with

WebServiceExample .


Figure 19-16:

This property is useful if you want to control the name of the class that proxies generate, as tools that consume the WSDL to build the proxy will now build a

WebServiceExample class as the proxy instead of building a class with the name

Fibonacci .

Now that we've seen the two attributes used most often to build ASP.NET Web services, let's discuss how to go about designing web services, and look at some more advanced issues involved.

/ 244