Instead, the decision you have to make as an ASP.NET developer is whether you let ASP.NET build server controls automatically for you by just building your sites using ASP.NET pages and/
Trang 1appear in
DefaultValue The default value of the property
Description Text describing the property This appears at the bottom of the property grid in the
"Description" box
PersistenceMode How (or whether) changes made to the value of this property should be persisted
Browsable Whether a property is displayed in the designer
TypeConverter,
Editor Hooks up extended UI for setting the property
The following example shows how we'd use the Browsable property to hide the SomeProperty from the properties window:
Custom Control Builders
A custom control builder is a class that derives from the class ControlBuilder, and overrides one or more methods that influence how a server deals with declaration within an ASP.NET page
The following control builder class overrides the AllowWhitespaceLiterals method and returns false to indicate that spaces are not significant If this method returned true, a LiteralControl containing spaces would be created and added to the Controls collection:
public class NoWhiteSpaceBuilder: ControlBuilder
Trang 2Why Create Your Own Server Controls?
Trang 3"Why Create Your Own Controls?" isn't really the right question to ask Instead, the decision you have to make as an ASP.NET developer is whether you let ASP.NET build server controls automatically for you (by just building your sites using ASP.NET pages and/or user controls), or whether you take over some of the control creation yourself In the latter case, you can build your site using a mixture of ASP.NET pages, user controls, and custom server controls
So there's no right answer to the original question However, here are a few pointers that should help you decide for yourself:
ASP.NET controls enable a fine-grained level of black box reuse ASP.NET user controls and pages can also provide this reuse, but since they are far more coarse-grained and typically have fixed UI traits (pages don't support templates, although user controls can), they are likely to provide far less re-use
ASP.NET controls ultimately provide the most flexibility, but take longer to write and require more coding skill
If you think you want a custom control, but are not 100% sure, start with a user control as you can always change it to become a custom control later All the code you write will work as a control, but you will need to convert any HTML sections of your user control into code using control composition
Only custom controls and user controls can be 'lookless', and therefore support templates If you want people to
be able to extend and manage the UI of your control, you must use these control types
User controls and custom controls can be written in different languages, and then used within the same hosting page At present only one language can be used directly within any single ASP.NET page
Only custom controls are compiled You may therefore want to use them if you need to protect your sourcecode
Summary
In this chapter we've examined how to develop ASP.NET server controls using C# and VB There are many topics we have not covered in this chapter, such as advanced state management, but we've hopefully given you enough information to start developing server controls
We started the chapter by looking at how to develop a really elementary server control with a hard-coded user interface
We then evolved this into a more useful label control supporting attributes to allow the text content of a label to be specified, along with server style attributes to define font size and text control
Then we saw how the WebControl class is designed for server controls that require styles, and also want to provide an object model consistent with the built-in ASP.NET server controls Next we looked at how server controls can interact with postback and use viewstate to become intelligent - automatically round tripping their values in the browser, and raising events to allow server-side event handlers to react to changes in state
We also looked at several miscellaneous topics, including how to use attributes to influence the design-time experience of
Trang 4a server control, and how to determine the capabilities of a browser to enable a control's user interface to be adaptive
Finally, we looked at some of the reasons why you might want to write server controls in preference to user controls or plain ASP.NET pages
In the next chapter we'll look at how to expose Web Services, allowing you to share information across networks and the Internet
Trang 5Exposing Web Services
Web Services aren't a new concept They allow distributed applications to share business logic over a network The classic Web Service example scenario is a stock quote service: one company provides a service that can accept requests for stock symbols and responds with stock quote details A company building an investment site can then use the application logic provided by the stock quote company to retrieve stock quote details
This problem sounds relatively simple, but it has proven quite difficult to solve in the past That's due largely to proprietary protocol formats, such as RMI, and the lock-down of open ports to only port 80 (for HTTP) and port 443 (for HTTPS)
What is new is the use of XML and HTTP, which are open standards, rather than proprietary serialization formats such as DCOM, RMI, or CORBA (although CORBA isn't proprietary, each vendor's CORBA implementation is unique to that vendor)
By using standard web protocols such as HTTP, and data description languages such as XML, to exchange data over common ports Web Services can utilize the ubiquitous HTTP infrastructure support that is already in place
The technical definition of a Web Service is programmable application logic accessible via standard web protocols Behind this definition are two important points:
Programmable application logic- Web Service is implementation-non-specific The application logic can be implemented by components, by Perl scripts, or by any other mechanism that supports XML
Standard web protocols- Web Services use Internet transport protocols such as HTTP or SMTP
The union of XML and HTTP forms Simple Object Access Protocol (SOAP) SOAP is a W3C submitted note (as of May 2000) that uses HTTP and XML to encode and transmit application data
Consumers of a Web Service don't need to know anything about the platform, object model, or programming language used to implement the service; they only need to understand how to send and receive SOAP messages ASP.NET makes building Web Services easy, and since it uses the standard ASP development model, ASP developers already have the skills required to build Web Services with ASP.NET Although a Web Service makes use of XML and HTTP as part of the plumbing, ASP.NET abstracts this for us and makes building SOAP based end-points as simple as coding application logic The plumbing is still accessible if we need to work with the transport or serialization mechanisms for some reason
Here's what we'll cover in this chapter:
Trang 6 We'll start with an overview of what a Web Service is, look at some of the common problems associated with building distributed applications, and briefly discuss the public specifications used for building Web Services.
We'll look at how we build Web Services with ASP.NET, starting with some simple application logic that we'll enable, and going on to look at the additional attributes and classes we can use when creating ASP.NET Web Services
ASP.NET Web Services support three protocols for exchanging data through a Web Service: HTTP GET and POST and SOAP We'll take a look at these protocols and the supported data types
We'll look at some strategies for building Web Services and tracing Web Service requests, as well as how we can build services that operate asynchronously on the server We'll also look at some of the general ASP.NET features that we can leverage
In this chapter, any discussion of Web Services implies the use of SOAP unless otherwise stated
Let's get started with an overview of what a Web Service is
Web Services Overview
Today the most common way to access information on the Internet is via a browser that sends and receives messages via HTTP The browser receives HTML that is then parsed and used to render the user interface
The web browser only begins to scratch the surface of what can be done with Internet when it comes to building applications We're already seeing a migration to other Internet applications that use a similar set of underlying protocols, but don't always rely on HTML to control the user interface or exchange data Examples include PDAs, cellular phones, blackberry devices, and rich-client peer-to-peer applications
Web Services are designed to facilitate the move to this next generation of the Internet Using Web Services it's simple
to enable peer-to-peer and distributed application development, as we can use a common protocol for all these applications It's easy to envision applications that use a broad set of Web Services for authentication, e-mail, buddy lists, and so on
As the protocol format is standardized, any application that understands SOAP can take advantage of Web Services For example, if eBay built an auction Web Service, or Hotmail built an e-mail Web Service, SOAP-aware applications would be able to utilize these services However, various implementations can "interpret" the meaning of the SOAP specification differently Microsoft has worked to ensure that ASP.NET Web Services are compatible with other common SOAP implementations
As great as all this sounds, there are some common issues and questions that surround Web Services
Trang 7Common Issues
Solving the problem of exposing application logic and details of services through XML and HTTP isn't difficult We could use classic ASP, Java, Perl (to name but some) to write a simple application that exposed data via XML For example, we could use ASP to write a simple application that accepted values passed on the query string, and generated an XML return document that represented a specific database table Other applications could then make calls against an end-point (say
a URL exposing our database tables) to fetch, parse, and derive values from the document
However, designs like this are tightly coupled The client is expecting a highly structured XML document, and if the application providing this document is changed, the client implementations may be broken In the majority of cases this can be addressed by using public XML schemas, but maintaining a set of schemas for each application would be cumbersome Also, the XML document will be dependent upon the server implementation
Typically, even minor changes to the application logic can require large changes in the code used to expose that application logic as an XML document The classic example of this problem is encountered with screen-scraping, in which the HTML of a site is parsed for specific values As long as the HTML remains static the known values can easily be extracted, but if the HTML changes, it will usually break the application that consumes the HTML
Other common issues include:
Publishing the service- once the service is available, how do clients find or discover the Web Service? Just as we have web sites such as MSN and Yahoo!that publish the location of web sites, shouldn't we have something similar for Web Services?
Describing the service- how do consumers of the service call the service? For example, what protocol does the service support? How does the protocol serialize data? What data types does the service support? Does the Web Service require a schema?
The network- one of the problems with other protocols such as DCOM, RMI, or CORBA is that they use TCP/IP ports that are closed or restricted, or in some cases require additional software or a specific operating system Administrators use firewalls to lock down their Internet exposure, usually leaving only ports 80 and 443 left open for HTTP and HTTPS traffic respectively If the required ports are not accessible, or are blocked, building successful distributed applications is more difficult Additionally, most web applications are an amalgamation of technologies and operating systems
The development framework and tools- given some application logic, is there a common development framework
- as opposed to a choice of language, or even platform - that we can use to easily create Web Services?
These challenges are not particularly difficult to overcome In fact, the work done by Microsoft, IBM, Intel, and HP (to name just a few), has meant that many of these issues have already been addressed through development frameworks (such as Microsoft NET) or through specifications that have been submitted to standards organizations
The specifications form part of the solution to the problems we listed Rather than each company driving its own view of the world, they can agree on a single specification and provide an implementation of it Standards-based specifications work especially well at the network level since each application can then leverage all the features provided by its native
Trang 8 Discovery- there are two specifications that address the discovery of Web Services Universal Description, Discovery and Integration (UDDI) - see http://www.UDDI.org for more details- is a directory that we can use to publish and discover public Web Services Another specification, DISCO (abbreviated from Discovery) can also
be used to group common services together on a server, and provide links to the schema documents the services
it describes may require We'll discuss both of these in the next chapter
Description- Web Service Description Language (WSDL), another Microsoft co-submitted W3C specification, defines an XML grammar for describing Web Services This description includes details such as where we find the Web Service (its URI), what methods and properties that service supports, the data types, and the protocols used to communicate with the service Tools can consume this WSDL and build proxy objects that clients use to communicate with the Web Services We'll talk more about what proxies are and how to build them in the next chapter The WSDL specification is available at http://www.w3.org/TR/wsdl
Protocol- as we've already mentioned, SOAP describes an extensible XML serialization format that uses HTTP to transport data We will discuss SOAP in this chapter, but not in any great detail The specification is available at
http://www.w3.org/TR/SOAP
Using Discovery, Description, and Protocols
When we want to build a Web Service, UDDI, DISCO, and WSDL are, for the most part, technologies to be used at design time Here's a scenario for using a Credit Card Validation Web Service:
Trang 9The steps here are as follows:
• We communicate our interest in a Credit Card Web Service to a UDDI node (nodes maintain the available services), either through UDDI's public Web Services, or through the browser
• UDDI responds with a listing of credit card services (if they're available- we'll assume they are)
• The list of services returned by UDDI provides us with URIs that map to either DISCO or WSDL documents We'll use the DISCO documents In addition to the programmatic details provided by UDDI, we can also discover documentation for the Web Service at one of the UDDI.org nodes Hopefully the provider of the service would provide additional details about what the service offered
• We follow the URI for the DISCO document Within the DISCO document we find a listing of the location of WSDL documents
• After parsing the DISCO document, we follow the URI for the WSDL document related to the Credit Card Validation Web Service
• We parse the WSDL document, and build a proxy object based on the details provided within the WSDL Although the DISCO and the WSDL documents can reside on the same server as the Web Service, it is not a requirement The DISCO document can be stored anywhere since it is only responsible for linking to WSDL documents Similarly the WSDL document can exist anywhere as long as it accurately describes the Web Service (the description includes the end point of the Web Service)
We now have a proxy object that we can use locally within our code, which looks and feels like the application logic it represents - it exposes the same methods and properties, but rather than the application logic executing locally, the proxy encapsulates the calls to the Web Service We're now ready to use our Web Service at runtime
Trang 10We can build an application that uses the proxy (we'll call it the CreditCardWebService proxy) The proxy encapsulates all the details of how to use the remote Web Service From our perspective, we're working with a local object
If the company providing the Credit Card Web Service decides to add some more functionality to the Web Service, it can simple update the WSDL If it only adds new members, and don't change the signatures of existing members, our proxy will continue to work fine
A lot of companies, including Microsoft and IBM, believe strongly that Web Services will be the next great enabler of the Internet Support for Web Services is one of the most important features in ASP.NET In the next chapter we'll look at how
we can use the services we build First though, we need to discuss how we can use ASP.NET to build Web Services
Building ASP.NET Web Services
ASP.NET Web Service files are simply source files (that are part of an ASP.NET application) with a .asmx file extension
Like ASP.NET Pages, ASP.NET Web Services are compiled on their first request, and support a code behind model, in which the code for the Web Service can reside in a pre-compiled NET Assembly
In this section we'll discuss the programming model Our emphasis will be how we expose application logic as a Web Service, rather than upon the application logic itself
A Simple Web Service
We're going to take as our example a simple class that calculates the value of an index in a Fibonacci series A Fibonacci series is a series of numbers beginning with 0 and 1, in which the next number in the sequence is calculated by adding the previous two numbers So, the third number in the sequence is 0 + 1 = 1, the fourth number is 1 + 1 = 2, the seventh
is 3 + 5 = 8, and so on The first seven numbers of the Fibonacci series are 0, 1, 1, 2, 3, 5, and 8 Let's implement this
in code
Fibonacci Application Logic
Below is the logic that allows us to interact with a Fibonacci series Using VB NET we would write:
Public Class Fibonacci
Public Function GetSeqNumber (fibIndex As Integer) As Integer
If (fibIndex < 2) Then
Trang 11FibArray(1) = FibArray(1) + FibArray(0)
FibArray(0) = FibArray(1) - FibArray(0)
Next
Return FibArray(1)
End Function
End Class
Using C# we would write:
public class Fibonacci {
public int GetSeqNumber(int fibIndex){
if (fibIndex < 2)
return fibIndex;
Trang 12int[] FibArray = {0,1};
for (int i = 1; i< fibIndex; i++){
FibArray[1] = FibArray[0] + FibArray[1];
FibArray[0] = FibArray[1] - FibArray[0];
A two-element array is created and initialized with the first series values of 0 and 1 For these numbers in the series, the value is the same as the index number, so we can just use that as a return value If the fibIndex parameter is greater than 1, we iterate in a For Next (VB) or for loop (C#), performing the necessary math to calculate the current values Finally we return the requested element in the array - the last value we calculated in the loop
This is simply application logic, and is no different from the type of application logic we author when we build ASP.NET pages or components However, there are some special considerations that we need to be aware of when we design application logic to be a Web Service, such as supported data types and behaviors specific to Web Services We'll cover those later in the chapter
Next, let's see what we need to do to enable this simple application logic as a Web Service using ASP.NET Our goal is that
we want another application to be able to easily call and use our Fibonacci class The difference is that our Fibonacciclass needs to be able to communicate using SOAP Fortunately, ASP.NET helps us to do that very easily
Fibonacci ASP.NET Web Service
We can use ASP.NET to expose our application logic as a Web Service by simply adding attributes to our code An attribute
is declarative code that adds additional behavior to our code - such as the ability to support SOAP - without us having to
Trang 13add new programmatic code that changes the behavior of our application logic It sounds complicated, but it's really not
There are several attributes that a Web Service makes use of The most notable of which is the WebMethod attribute The methods or properties that have this attribute are treated as Web Services They can receive, process, and respond with XML messages All of the internal serialization and de-serialization (that is, how the data being sent back-and-forth as XML
is represented) is handled internally
Let's look at our Fibonacci code, reworked as an ASP.NET Web Service: Using VB NET we would write:
<%@ WebService class="Fibonacci"%>
Imports System.Web.Services
Public Class Fibonacci
<WebMethod> Public Function GetSeqNumber (fibIndex as Integer) as Integer
FibArray(1) = FibArray(1) + FibArray(0)
FibArray(0) = FibArray(1) - FibArray(0)
Trang 14Next
Return FibArray(1)
End Function
End Class
Using C# we would write:
<%@ WebService Language="C#" class="Fibonacci" %>
for (int i = 1; i< fibIndex; i++){
FibArray[1] = FibArray[0] + FibArray[1];
FibArray[0] = FibArray[1] - FibArray[0];
}
return FibArray[1];
Trang 15}
}
The application logic for both files remains identical The difference is that the code now exists within an ASP.NET Web Service source file (Fibonacci_vb.asmx or Fibonacci_cs.asmx), and has some additional declarative code, such as the use of the WebMethod attribute
We'll discuss the details of these changes in a moment, but first let's test our Web Service
Testing Our Web Service
Our Fibonacci ASP.NET Web Service code is now a functional Web Service To test its functionality we can use a browser and request the URL that is represented by the ASP.NET Web Service file
Keep in mind that a Web Service is not intended to service requests for web browsers The web browser functionality shown is only for testing purposes, or design-time information In the next chapter we'll look at an IE 5.5 behavior that allows us to consume Web Services for rich browser clients
To run our fibonacci_cs.asmx (or fibonacci_vb.asmx file), we must make it accessible through a web server, just
as we would do for an ASP.NET page Once you've saved the code to a file on your web server, you can navigate to it with your browser You should see something like this:
ASP.NET provides an ASP.NET Web Service Help file template On receiving an HTTP Get request, the Web Service Help file template programmatically examines the code in the asmx file (using reflection), and generates the UI This includes details such as the class and method name Later, we'll see how we can get even more information out of this file The UI also provides some handy ways of testing the functionality of the Web Service
Trang 16The template page that does this is called DefaultWsdlHelpGenerator.aspx, and can be found in the
\WinNt\Microsoft.NET\Framework\[version] directory As it's just an ASP.NET page, we can easily customize it for our application We can, in fact, have custom Help file templates files for different ASP.NET applications
In the previous screenshot there is a Service Description link This link provides us with the WSDL (our XML contract for this Web Service) The WSDL for any ASP.NET Web Service is available as [webservice name].asmx?WSDL: so in this case we can access it as fibonacci_cs.asmx?WSDL We'll return to WSDL in the next chapter when we talk about how
we use the WSDL to build a proxy to use a Web Service
The other link on the page names the GetSeqNumber method This represents the method that we marked as a WebMethod in our Fibonacci class If we select this link we are presented with information about the GetSeqNumbermethod we have exposed as a Web Service:
We can use the HTML form that this provides to pass values to the GetSeqNumber method Enter a number into the parameter textbox and press the Invoke button to view the results:
What's shown here is the XML returned from the GetSeqNumber method call The element is named <int/>, and the return value is 8 Note that the value of fibIndex=6 is passed as an argument in the query string We could change this argument's value directly, and the Web Service would return the appropriate result
Trang 17This isn't a SOAP return, it's another protocol type that ASP.NET Web Services support: HTTP-GET The Web Service help page generates a simple HTML form that makes a GET request to the Fibonacci_cs.asmx file When we build proxies
to use our Web Service, the default protocol will be SOAP
Let's take a closer look at the changes we just made to our code in order to implement it as a Web Service
Coding ASP.NET Web Services
The .asmx file format is very straightforward We have two options for exposing application logic as an ASP.NET Web Service Both options involve creating a file with the extension .asmx:
Inline - the application logic exists within the .asmx file
Code-behind - the application logic exists outside the .asmx file
To be able to reference an external assembly, the assembly must reside in the ASP.NET application's bin directory The bin directory is a special directory used by the ASP.NET application, to which assemblies can be deployed and
'automatically' registered
To use the code-behind option we simply create a small ASP.NET Web Service .asmx file (which we'll call
Fibonacci_Codebehind.asmx) that contains a single line:
<%@ WebService Codebehind="Fibonacci.vb" Class="Fibonacci" %>
We need an implementation of our Fibonacci class in a separate assembly, either compiled and deployed in our ASP.NET application's bin directory, or as part of an assembly named directly in our configuration file Here's what the
Trang 18source would look like for the VB.NET version of our Fibonacci example (Fibonacci.vb):
Imports System
Imports System.Web
Imports System.Web.Services
Public Class Fibonacci
<WebMethod()> Public Function GetSeqNumber(fibIndex As Integer) _
FibArray(1) = FibArray(1) + FibArray(0)
FibArray(0) = FibArray(1) - FibArray(0)
Next
Trang 19Return FibArray(1)
End Function
End Class
We can simply use the following command line to compile the source into a NET assembly:
vbc /t:library /r:System.Web.dll /r:System.Web.Services.dll Fibonacci.vb
The result of this is a single file, Fibonacci.dll, which we need to place in a directory, named bin, that is located below the root directory of the application We can easily deploy the assembly (Fibonacci.dll) so that both ASP.NET pages and Web Services may use it- it's simply a component with a WebMethod attribute For example, if decide that the functionality encapsulated within a class would make a great Web Service we can simply make some minor changes to the assembly's application logic, and create a one line ASP.NET Web Service .asmx file (as above), to enable the application logic as a SOAP based end-point
As code-behind is the default behavior, the use of the Codebehind statement in Fibonacci.asmx is optional Visual Studio NET will use the Codebehind attribute, but we can just as easily remove it and still achieve the same functionality,
so long as the assembly contains the class our ASP.NET Web Service references Also, there is no difference in
performance between using inline or code-behind
Further discussion of Web Services will use the inline style, unless otherwise noted The only tangible benefit for using code-behind over the inline style is:
Code is compiled and the source cannot be viewed once deployed
Since the code-behind option is an assembly, the assembly can also be used in ASP.NET pages
Both the inline and code-behind options share a common set of directives that are used to give ASP.NET special instructions when handling ASP.NET Web Service requests
The WebService Directive
Like ASP.NET pages, ASP.NET Web Services support directives that instruct ASP.NET how to process the request For example, when we converted our Fibonacci examples to ASP.NET Web Services, the first thing we added was a directive
at the top of the .asmx file Using VB NET we wrote:
<%@ WebService Class="Fibonacci" %>
Trang 20And using C# we wrote:
<%@ WebService Language="C#" Class="Fibonacci" %>
The WebService directive is a required addition for all ASP.NET Web Services We'll look at the directive syntax, and then
at the attributes we'll use most often
<%@ WebService Attribute="Value" Attribute="Value"%>
An ASP.NET Web Service may contain multiple classes However, only one of the classes can contain methods marked with WebMethod attributes This relationship is enforced with a WebService directive attribute named Class
The Class Attribute
The Class attribute is special, since it is required and forces us to always declare the WebService directive within
a .asmx file Fortunately, it's not complicated The Class attribute simply names the NET class, whether inline or code-behind, that contains exposed methods or properties:
<%@ WebService Class="[Namespace.Class | Class]" %>
Using the Class Attribute
Our Fibonacci class must be named in the Class attribute as the Fibonacci class contains the logic to be exposed:
<%@ WebService Class="Fibonacci" %>