Xem mẫu

used to describe the service so that it references the port type defined within another namespace. You would also need to disable the WSDL document that is automatically generated by ASP.NET. (See the “Web Service Documentation” section earlier in the chapter.) ASP.NET does provide a mechanism for facilitating transport-specific interface inheritance. You use the WebServiceBinding attribute to reference a binding defined within another namespace. You use the Binding property of the SoapDocumentMethod or SoapRpcMethod attribute to reference the binding definition referenced by the WebServiceBinding attribute. Next I modify the definition of the Securities Web service to inherit the interface defined within the MSN namespace. I do so by referencing the SecuritiesSoap binding definition. Suppose the preceding WSDL document is located at http://msn.com/Securities.wsdl. The following code defines the Securities Web service provided by www.woodgrovebank.com: using System; using System.Web.Services; using System.Web.Services.Protocols; namespace BrokerageFirm { [SoapRpcService] [WebServiceBinding("SecuritiesSoap", "http://msn.com/Securities", "http://msn.com/Securities.wsdl")] public class Securities : WebService { I reference the SecuritiesSoap binding definition using the WebServiceBinding attribute. The three parameters I pass to the attribute’s constructor are the name of the referenced binding definition, the namespace containing the definition, and the location of the WSDL document containing the definition. If the binding definition is referenced within the Web method, the ASP.NET runtime will add a reference to the WSDL namespace that contains the binding. The ASP.NET runtime will also add an import element to the autogenerated WSDL document. Finally, the ASP.NET runtime will add a port within the service definition that is associated with the referenced binding definition, as shown here: [WebMethod] [SoapRpcMethod(Binding="SecuritiesSoap")] public double InstantQuote(string symbol) { double price = 0; // Implementation... return price; } } 154 } I use the Binding property of SoapRpcMethod to associate the Web method with the binding definition. The value of the binding property must match the name assigned to a WebServiceBinding attribute defined at the class level; otherwise, a run-time exception will occur. Using the WebServiceBinding attribute to facilitate interface inheritance has some limitations. First, you can reference only SOAP binding definitions. There is also no tool support for referencing external binding definitions. Developers must take it upon themselves to create Web methods that match the referenced binding definition. Finally, there is no validation either at compile time or at run time to ensure that the Web service implements all the methods exposed by the inherited interface. To ensure that the Web service supports all the methods of the inherited interface, you can use the WSDL.exe tool to generate an abstract class representing the Web service. You can then add the resulting code to your project and derive from the abstract class instead of the WebService class. The following example creates the BaseSecurities.cs file that contains an abstract class definition for the base Web service: wsdl /server /out:BaseSecurities.cs http://msn.com/Securities.wsdl Once BaseSecurities.cs has been created and added to my project, I can derive the Web service as follows: using System; using System.Web.Services; using System.Web.Services.Protocols; namespace BrokerageFirm { [WebService(Description="This Web service provides services related to securities.")] [SoapRpcService] [WebServiceBinding("SecuritiesSoap", "http://msn.com/Securities", "http://msn.com/Securities.wsdl")] public class Securities : MSN.Securities { // Implementation... } } If the Securities class does not implement all the abstract methods defined within the MSN.Securities class, I will receive a compiler error. Managing State 155 HTTP is by nature a stateless protocol. Even with the introduction of the connection keep-alive protocol in HTTP 1.1, you cannot assume that all requests from a given client will be sent over a single connection. If the Web application needs to maintain state on behalf of the user, you often have to roll your own solutions. Furthermore, state is usually scoped to the application. Application configuration parameters such as database connection strings are an example. Defining a Web application and providing a mechanism to store state that is scoped to the application is an implementation detail of the Web development platform. The ASP development platform defines a Web application and provides a service for maintaining both session and application state. However, the ASP state management services have some serious limitations. ASP.NET provides a much-improved state management service. The service can be leveraged by Web Forms as well as Web services. Session State It is considered good practice to avoid having to maintain state between requests, when practical. For that reason, session state is disabled by default. You have to explicitly enable it for a particular Web method. Maintaining state on behalf of a user involves associating multiple HTTP requests with one user session. ASP.NET uses a unique identifier that is passed by the client to identify the session. This identifier can be saved in a cookie maintained by the client or embedded within the URL of the request. Even though Web Forms supports both, Web services support only cookies. If the proxy used by the client to access the Web service supports cookies, the session ID will automatically be sent with every request. ASP.NET uses a transient cookie to store the session ID. By definition, the cookie is intended to be maintained only for the life of the proxy used to access the Web service. Because cookies are HTTP-specific, the session state mechanism is bound to the HTTP protocol. A transport protocol–agnostic way of passing the session ID would be to place the session ID within the header of the SOAP message. But this is not supported by ASP.NET, so you would have to roll your own state management system to support this scenario. Once the session is identified, you need a repository to store the data associated with the session. The following three scenarios are supported, each with its advantages and disadvantages: ▪ In Process This is the fastest scenario because calls to read/write session state will be handled in process. However, this is also the least robust configuration. If the ASP.NET worker process (aspnet_wp.exe) is terminated for any reason, all session state being maintained for the application will be lost. This configuration is ideal for Web services hosted on a single machine that need the most performant way of accessing state. ▪ Out of Process In this configuration, session state is maintained in a separate process that can even reside on another machine. One advantage of this configuration is that if the ASP.NET worker process is terminated, the session state for the application will still be preserved. Because session state is maintained in memory, if the session state server (aspnet_state.exe) is terminated, all session state will be lost. Another advantage of this configuration is that state can be shared across multiple Web servers. All Web servers within the Web farm can be configured to point to the same state management process. This configuration is ideal for Web services hosted in a Web farm where the loss of state information should be avoided but is not critical. 156 ▪ SQL Server This is the most robust and scalable of the three configurations. Session state is maintained within a SQL Server database. The session state service maintains a set of tables in which the session state data is serialized into a binary blob. This is the ideal configuration for Web services hosted in a Web farm if you can afford to purchase and maintain SQL Server. This configuration is mandatory if you need to ensure that session state is never lost. Of the three configurations, In Process is the only one available via the .NET Framework. You must purchase either the Professional or Enterprise Edition of ASP.NET to obtain the Out of Process and SQL Server configuration options. To use the ASP.NET session state service, you must add the module named SessionStateModule to the application. The default machine-wide configuration file (C:\WINNT\Microsoft.NET\Framework\version\CONFIG\machine.config) adds this module. Once you add SessionStateModule, you can configure the session state service within the sessionState element of the machine.config or web.config configuration file. Table 6-6 lists the attributes that you can set within the sessionState element. Table 6-6: Attributes of the sessionState Element Attribute mode cookieless timeout stateConnectionString sqlConnectionString Description Specifies where ASP.NET will save session state. The possible values are OffSession state is disabled. InProcSession state is stored within the ASP.NET worker process. StateServerSession state is stored by the out-of-process session state server. SqlServerSession state is stored within SQL Server. The default is InProc. Specifies whether cookieless sessions should be enabled. The default is false. Specifies the number of minutes the session can be idle before the session is abandoned. The default is 20 minutes. Specifies the location of the session state server. The default value is tcpip=127.0.0.1:42424. Specifies the location of the SQL server. The default value is data source=127.0.0.1;user id=sa;password=. Once you have the session state service properly configured, session state is enabled on a per-Web-method basis. You can enable session state for a particular Web method by setting the EnableSession property of the WebMethod attribute to true. Regardless of which configuration you choose, the API for reading/writing session state is exactly the same. The class that contains the Web method should inherit from the WebService class. The WebService class exposes the Session property, which returns an instance of the HttpSessionState class, otherwise known as the session object. 157 The session object is used to maintain a collection of information related to the user’s session. Items can be added to and retrieved from the collection via an int or string indexer. The following example expands the Securities Web service to use session state. The SetCurrency Web method allows the client to select a particular currency. Future calls to InstantQuote will return the price of the security using the selected currency. using System; using System.Web.Services; namespace BrokerageFirm { [SoapRpcService] public class Securities : WebService { public Securities() { // Set the default value of the target currency. if(this.Session["TargetCurrency"] == null) { this.Session["TargetCurrency"] = CurrencyType.US_DOLLAR; } } public enum CurrencyType { US_DOLLAR, UK_POUND, GE_DEUTSCHMARK } [WebMethod(true)] public void SetCurrency(CurrencyType targetCurrency) { this.Session["TargetCurrency"] = targetCurrency; } [WebMethod(true)] public double InstantQuote(string symbol) { // Implementation... 158 ... - tailieumienphi.vn
nguon tai.lieu . vn