Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 40 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
40
Dung lượng
735,11 KB
Nội dung
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 You might have to alter the server name in the code above to reflect your own database. Here, a WebMethod named GetDataSet 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 we 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. For long running methods this might not be optimal - we'd probably want to send the response as we receive it rather than waiting 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 us to configure ASP.NET Web Services to not buffer the response. By default this property is set to true. Using VB.NET we would write: <WebMethod(BufferResponse:="[true|false]")> Using C# we would write: [WebMethod(BufferResponse="[true|false]")] The other attribute we're going to look at, the WebService attribute, gives us additional control over the class that contains the web-callable methods rather than the individual methods themselves. 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 both 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 we 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 we would write: <WebService (Description:="[string]")> Public Class [Class Name] Using C# we would write: [WebService(Description="[string]")] public class [Class Name] Using the Description Property 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, we can add a Description property to our Fibonacci example ( WebServiceDescription_cs.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]; } } We would see the output both in the browser: and in the WSDL: 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, if we have 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. We'll talk more about tempuri.org in the WSDL section in the next chapter. For now, all we need to know is that we can use the Namespace property of the WebService attribute to change the namespace value to a value of our choosing. Using VB .NET we would write: <WebService(Namespace:="[string]")> Public Class [Class Name] Using C# we would write: [WebServiceNamespace="[string]")] public class [Class Name] Using the Namespace Property If we viewed the WSDL from either our VB or C# Fibonacci Web Service, we would see http://tempuri.org/ used for the value of the namespace: If we wanted to change the namespace to http://rhoward/Fibonacci/, we would make the following change to our code ( WebServiceNamespace_cs.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 our WSDL appears as follows: This affects what our SOAP message looks like: 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 us to override the default value. Using VB .NET we would write: <WebService(Name:="[string]")> Public Class [Class Name] Using C# we would write: [WebService(Name="[string]")] Using the Name Property For example, if we viewed the WSDL of our Fibonacci class we would see the following: If we were to set the Name value to WebServiceExample in the WebService attribute (as in WebServiceName.asmx): [WebService(Name="WebServiceExample")] we would see the following change in our WSDL: All instances of Fibonacci in the WSDL have been replaced with WebServiceExample. This property is useful if we 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 looked at the two attributes we will use most often to build ASP.NET Web Services, we're ready to discuss how we should go about designing Web Services, and look at some more advanced issues involved. Designing ASP.NET Web Services Web Services provide access to application logic, and application logic can take many forms- from stored procedures to components. Although ASP.NET Web Services take the form of classes with implementations, this should not imply that normalized object-oriented design principles must be adhered to. We shouldn't ever consider a Web Service to be a class, method, or property. Rather a Web Service is an endpoint that we send data to and receive data from. Let's start the discussion of building ASP.NET Web Services by discussing API design, namely "chunky versus chatty" patterns. Chunky Versus Chatty Web Services rely on XML and HTTP to encode and transmit serialized application data. The combination of these two technologies provides a powerful means to create cross-platform distributed applications, as well as the ability to push application requests through proxies. However, there are some downsides to this technology as well. It's an extremely verbose way of describing what should be a simple exchange of data between two applications, and it's stateless. Thus, the design recommendation is that we should try to reduce the number of network calls to the Web Service wherever possible. Stateless Versus Stateful HTTP is a stateless protocol, and this doesn't change for ASP.NET Web Services that use HTTP to transport SOAP messages. ASP.NET provides workarounds for this stateless barrier, but the workarounds rely on the use of a session token which can either be stored in an HTTP cookie, or embedded within the URL. We should definitely take the stateless nature of HTTP into account when building web applications. If we need to solve that stateless problem with a solution such as Session state, it's worth considering the implications to the Web Service - using HTTP cookies builds reliance on the protocol rather than the SOAP message. The discussion of stateless versus stateful applies most to discussions of design - how will we expose our application logic and how end-users interact with that logic? For example, will we use the methods or properties in our classes? Methods or Properties ASP.NET Web Services use a class with methods marked with the WebMethod attribute to enable us to send and receive SOAP messages. Although we've shown how to use the WebMethod attribute applied to methods within the class, this attribute can also be applied to properties: <%@ WebService Class="MethodsAndProperties" %> Imports System.Web.Services Public Class MethodsAndProperties [...]... and scalability of the system An asynchronous design, on the other hand, allows the ASP.NET thread of execution to start up another thread, which can call back onto an ASP.NET thread when the work is complete That way, the ASP.NET application is not stalled because of resource constraints on available threads Advanced ASP.NET Web Services In this section we're going to focus on some of the esoteric areas... a brief example is necessary A simple ASP.NET Web Service (Books_vb.asmx) that returns a Books class follows: Imports System.Web.Services Public Class ReturnBooks Public Function GetBooks() As Books Dim b As New Books b.Title = "Professional ASP.NET" b.Price = 59.99 b.Description = "This book covers Microsoft's ASP.NET technology " & _ "for building... template used for all ASP.NET Web Services when a request is made through the browser to a particular Web Service In Chapter 16, when we discussed ASP.NET configuration, we covered how each application can support its own Web Service Help page- it's simply a configuration option to tell the application which ASP.NET page to use Since the Web Service Help page is implemented as an ASP.NET page, we can... any modification to the server's DefaultWsdlHelpGenerator.aspx will apply to all ASP.NET Web Services on that server, unless you alter the ASP.NET configuration However, there are some modifications that we can make to this file which will be useful in debugging our ASP.NET Web Service HTML Form (Post Support) If an ASP.NET Web Service is capable of supporting the HTTP-POST protocol and we wish to... System.Web.Services Imports System.Xml.Serialization Public Class ReturnBooks Public Function GetBooks() As Books Dim b As New Books b.Title = "Professional ASP.NET" b.Price = 59.99 b.Description = "This book covers Microsoft's ASP.NET technology " & _ "for building Web Applications" ReDim b.Authors(5) b.Authors(0) = "Alex Homer" b.Authors(1) = "David Sussman" b.Authors(2) = "Rob Howard"... description of our service that ASP.NET was able to generate for us The details of the ASP.NET asmx file, which is the file format used to expose our application logic We discussed the directives, the System.Web.Services namespace, and the WebMethod and WebService attributes, including the properties that each supports Design suggestions, and some of the more advanced aspects of ASP.NET Web Services, specifically... integrating with Windows DNA, and shaping the SOAP/XML document exposed by our Web Services Controlling and Shaping the XML ASP.NET provides us with several additional attributes (which we didn't discuss earlier) that allow us to shape the XML generated by the XML serializer used by ASP.NET There are two separate types of attributes: those that apply to the XML documents generated by the HTTP-GET and HTTP-POST... Synchronous Web Services can be designed to be synchronous or asynchronous: A synchronous design allows the ASP.NET thread of execution to run until it's complete If an action within the code has the potential to block, such as network I/O or an extensive database lookup, this can stall the ASP.NET worker thread Since a thread is a resource, and there are only a limited number of resources available... Headers The use of headers is only supported within the SOAP protocol, not HTTP-GET or HTTP-POST ASP.NET Web Services that we create use SOAP as the default protocol for application-to-application communication For example, here is the SOAP response to a call to our Fibonacci Web Service: . 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] ; } }. 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] ; } }. other hand, allows the ASP. NET thread of execution to start up another thread, which can call back onto an ASP. NET thread when the work is complete. That way, the ASP. NET application is not