打印本文 打印本文 关闭窗口 关闭窗口
Using ASP.NET Session State in a Web Service
作者:武汉SEO闵涛  文章来源:敏韬网  点击数3062  更新时间:2009/4/23 10:43:17  文章录入:mintao  责任编辑:mintao

Quick Overview of ASP.NET Sessions

ASP.NET session state is maintained by using one of two underlying mechanisms. The first is by using HTTP cookies. The idea behind HTTP cookies is that when the client sends a request, the server sends back a response with an HTTP Set-Cookie header that has a name/value pair in it. For all subsequent requests to the same server, the client sends the name/value pair in an HTTP Cookie header. The server then can use the value to associate the subsequent requests with the initial request. ASP.NET uses a cookie that holds a session ID to maintain session state. Then that ID is used to find the corresponding instance of the HttpSessionState class for that particular user. The HttpSessionState class provides just a generic collection in which you can store any data that you want.

The other mechanism that ASP.NET uses for maintaining session state works without cookies. Some browsers do not support cookies or are not configured to keep and send cookies. ASP.NET provides a mechanism for getting around this problem by redirecting a request to a URL that has the ASP.NET session ID embedded in it. When a request is received, the embedded session ID is simply stripped out of the URL and is used to find the appropriate instance of the session object. This works great for browsers that are doing HTTP GET requests, but creates issues when writing Microsoft® .NET code that consumes an XML Web service.

It should be noted that sometimes it makes sense to store state information in cookies themselves instead of in the ASP.NET session object. By avoiding the session object, you use fewer resources on the server, and you do not have to worry about issues like locating a specific instance of the session object across a Web farm, instances of the session object being cleaned up because of a long delays between requests, or session instances lingering around for no reason until their timeout period expires. However, if you have data that includes implementation information that you do not want to share with the consumers of your service, or is private data that you do not want to send across an unencrypted channel, or if the data would be impractical to serialize into an HTTP header, then it may make sense to take advantage of the HttpSessionState class in ASP.NET. The HttpSessionState class returns an index key that is used to map a particular user to an instance of the HttpSessionState class that holds information stored for that user. Both the ASP.NET HttpSessionState class and HTTP cookies are available to users writing ASP.NET Web services.

Why Use an HTTP Mechanism for Maintaining State in an XML Web Service?

There are many ways to maintain state between SOAP requests. Certainly one feasible option would be to include something like the ASP session ID in the SOAP header of your SOAP message. The problem is that you have to: 1) still write the server side code yourself, and 2) make sure your clients treat your session ID header like an HTTP cookie and send it back to you with each request. There are certainly cases where using the SOAP header approach makes a lot of sense, but there are situations where using the HTTP approach can make sense as well.

ASP.NET session state is already done for you. The HttpSessionState class is available for easily storing your session objects. Most HTTP clients already understand that they must return the cookies that are set by the server and HttpSessionState happens to support the underlying transport most frequently used for SOAP communications—HTTP. Thus it makes sense that using ASP.NET session support could be a smart decision to meet many state management requirements.

Enabling Session Support on the Server

By default, ASP.NET session support for each Web method is turned off. You must explicitly enable session support for each Web method that wants to use session state. This is done by adding the EnableSession property to the WebMethod attribute of your function. The code for a Web method with the EnableSession property set to true, and which accesses the HttpSessionState object, is shown below.

    <WebMethod(EnableSession:=True)> _
Public Function IncrementSessionCounterX() As Integer
Dim counter As Integer
If Context.Session("Counter") Is Nothing Then
counter = 1
Else
counter = Context.Session("Counter") + 1
End If
Context.Session("Counter") = counter
Return counter
End Function

As you might expect, if you enable session support for one Web method, that does not imply that it is enabled for another Web method. In fact, the Context.Session property will be null if EnableSession is not explicitly set to True for a particular Web method.

Be aware that it is possible to disable sessions by way of a web.config setting, so that even if you use the EnableSession property in your WebMethod attribute, Context.Session will always be null. The /configuration/system.web/sessionState element has a mode attribute that is used to configure how session state is maintained for your ASP.NET application. By default the mode is set to "InProc," which means that the HttpSessionState objects will simply be held in the ASP.NET process'''' memory. If the mode is set to "Off," then there will be no session state support in the ASP.NET application.

From the HTTP server standpoint, the scope of an ASP.NET session is that it lives within a given ASP.NET application. This means that the same instance of the HttpSessionState class will be used for all session-enabled ASP.NET requests within a single virtual directory for a particular user. A request to a different virtual directory with the same session ID cookie will result in ASP.NET being unable to find the corresponding session object—because the session ID was set for a different ASP.NET application. ASP.NET does not differentiate between ASPX and ASMX requests as far as sessions are concerned, so you could theoretically share session state between a Web method call and a normal ASPX file. However, there are client-side issues that we will look at in a little bit that might make this tricky.

When setting an HTTP cookie, you can associate an optional expiration time with it. The expiration time indicates how long the client should continue sending the cookie back to the server. If a cookie is set without the optional expiration, it will only be returned for the life of the process making the requests. For instance, Microsoft® Internet Explorer will return the cookie until you close that particular instance of your browser. The session ID cookies used by ASP.NET do not have expiration times. Therefore, if multiple processes on a client machine are making HTTP requests to your server, then they will not share the same HttpSessionState object. This is true even if the two processes are running at the same time.

If you are making simultaneous Web service calls from the same process, the requests will be serialized at the server so that only one will execute at any one time. Unlike .ASPX pages that have support for read-only access to the HttpSessionState object, which allows for simultaneous processing of multiple requests, there is no such capability with ASP.NET Web services. All Web method calls with sessions enabled have read/write access and will be serialized within each session.

Client-Side Issues

Successfully using the HttpSessionState capabilities in your Web service does rely upon some assumptions about the consumers of your Web service. First and foremost, if you are using the default HTTP cookie mode of maintaining session state, then your clients must support HTTP cookies. If you are using the cookieless mechanism for supporting sessions, then your clients must be able and willing to redirect their requests to the modified URLs with the session IDs in them. As it turns out, this is not a trivial assumption, even with a .NET client application.

Everything Works from the Browser

If you develop an ASP.NET Web service in Microsoft® Visual Studio® .NET, the default debugging behavior is to launch Internet Explorer and browse to your .ASMX file. This usually will result in a friendly HTML interface for invoking your Web methods. This turns out to be a nice way to debug your Web service code, and if you have set the EnableSession property to True for your Web method, it tends to work out beautifully. Even if you turn on cookieless session support, the browser client will work perfectly, and your session will work in the manner that you expect it to.

However, most Web service requests do not come from a browser. What happens when you create a client application that uses the "Add Web Reference" feature of the .NET Framework? Let''''s take a look at the results.

Problems Using Add Web Reference

I created a simple XML Web service using the code snippet that we saw earlier. If you recall, the Web method is called IncrementSessionCounter and simply stores an integer in the HttpSessionState object, increments it with each call, and returns the current value. From the browser client, we see that the number increases by one with each invocation as we expect.

Next, I created a simple Microsoft® Windows Form application and added a Web reference for my Web service. The code for invoking my Web service looks like this:

[1] [2] [3]  下一页

打印本文 打印本文 关闭窗口 关闭窗口