• Using ASP.NET Sessions from WCF


    This is not a new topic. But interestingly I could not find a good example on the web while I wanted to find one for some other investigation. So I decided to create a sample here to show the following scenario:

    • A WCF service has the access to a ASP.NET session. Different WCF client proxies can connect to the per-call WCF service and share the same ASP.NET session state.

    Here I will show a simple example on how to achieve this.

    ASP.NET Sessions vs WCF Sessions

    WCF sessions are very different from ASP.NET Sessions. In short,

    • WCF sessions are represented as service instances (as CLR objects) and the states are part of each service instance. The sessions are initiated by the calling WCF client. WCF relies on special context to provide correlation for the sessions: sessionful channels, secure conversations, reliable-messaging, etc.
    • ASP.NET sessions are like shared data storage across different requests. The sessions are always initiated by the server. ASP.NET relies on cookies or special Uri goo to provide correlation for the sessions.

    You can find more details for the comparisons of the two from the MSDN article “Using Sessions”.

    While these two concepts are quite different and the usages are also drastically different, the WCF sample “HttpCookieSession” tried to use the similar idea as cookie-based ASP.NET sessions to provide WCF session support. The sample is a little bit complex and it does not use real ASP.NET sessions though.

    There are many samples on how to use WCF sessions, for example, “How to: Create a Service That Requires Sessions” is a good one.

    So I will only show how to use ASP.NET sessions from WCF below. It uses PerCall service to handle this. So different service instances have access to the same ASP.NET session state.

    Using ASP.NET Session States

    Storing Session States

    It is known that ASP.NET session states can be stored in different places: 1) In-Memory (thus In-process), 2) Out-of-proc state service, 3) SQL server, 4) a custom session-state store provider, etc. More details can be found in “ASP.NET Session State Overview”.

    For simplicity, I will just show the in-memory case. Here is a very simple session state:

    class MySessionState

    {

        int counter;

        public MySessionState() {}

        public int Counter { get { return this.counter; } }

        public int Touch() { return Interlocked.Increment(ref this.counter); }

    }

    The state just contains a single counter. This state is stored in the session object as following:

    MySessionState state = (MySessionState)HttpContext.Current.Session["MySessionState"];

    if (state == null) {

        state = new MySessionState();

        HttpContext.Current.Session["MySessionState"] = state;

    }

    When the service receives a request, the sample increments the counter to demonstrate the sharing effect:

    int counter = state.Touch();

    Enabling Session States

    It is very straightforward to enable the ASP.NET session states. You only need to run WCF service in the ASP.NET Compatibility mode as being specified in the web.config:

    <serviceHostingEnvironment aspNetCompatibilityEnabled="true"/>

    Retrieving Session Id on the Client

    Once the session states are enabled and there is session data populated as above, we can retrieve the Session Id from the cookie on the client side:

    using (new OperationContextScope((IContextChannel)proxy))

    {

        Console.WriteLine(proxy.Greet("Hello"));

        HttpResponseMessageProperty responseProperty =OperationContext.Current.IncomingMessageProperties[HttpResponseMessageProperty.Name]

            as HttpResponseMessageProperty;

        helper =HttpSessionCookieHelper.Create((string)responseProperty.Headers[HttpResponseHeader.SetCookie]);

    }

    Here the type “HttpSessionCookieHelper” is just a helper class that is used to retrieve the ASP.NET Session Id from the cookie string (with the cookie name “ASP.NET_SessionId”) and append the Session Id to the request. It is defined as following:

    class HttpSessionCookieHelper

    {

        const string AspNetSessionIdCookieName = "ASP.NET_SessionId";

        string aspNetSessionId;

        public static HttpSessionCookieHelper Create(string cookieString);

        public static HttpSessionCookieHelper CreateFromSessionId(string sessionId);

        public void AddSessionIdToRequest(HttpRequestMessageProperty requestProperty);

        public string AspNetSessionId { get { return this.aspNetSessionId; }

    }

    Sending Session Id

    Once we get the Session Id retrieved from the response of the first request, we can share it for the subsequent client calls. Here is the example:

    using (new OperationContextScope((IContextChannel)proxy))

    {

        HttpRequestMessageProperty requestProperty = new HttpRequestMessageProperty();

        helper.AddSessionIdToRequest(requestProperty);

       OperationContext.Current.OutgoingMessageProperties[HttpRequestMessageProperty.Name] = requestProperty;

        Console.WriteLine(proxy.Greet("Howdy"));

    }

    The implementation of the HttpSessionCookieHelper.AddSessionIdToRequest does nothing but the following:

    requestProperty.Headers[HttpRequestHeader.Cookie] = string.Format("{0}={1}", AspNetSessionIdCookieName, this.aspNetSessionId);

     http://blogs.msdn.com/b/wenlong/archive/2010/02/21/using-asp-net-sessions-from-wcf.aspx

    With this logic, the second request would share the same ASP.NET Session State on the server side.

    Sample Setup

    Here are the steps on how to use it:

    1)     Unzip the attachment locally.

    2)     Create a virtual application with name “WCFAspNetSession” and the physical path points to the “WCFAspNetSession” directory.

    3)     Compile the client code and run it.

    Here is the output of the sample:

    [Session '1vgfq255e1lpe255whwprf55'] You said: Hello (counter: 1)

    [Session '1vgfq255e1lpe255whwprf55'] You said: Howdy (counter: 2)

    As you can see, the Session Ids for the two requests are the same and the counter for the shared state has increased.

  • 相关阅读:
    droid开发:如何打开一个.dcm文件作为位图?
    AndroidStudio3.0 Canary 8注解报错Annotation processors must be explicitly declared now.
    Android 异步加载神器Loader全解析
    Android实现RecyclerView的下拉刷新和上拉加载更多
    Android之ViewFlipper的简单使用
    云计算之路-阿里云上:2014年6月11日17点遇到的CPU 100%状况团队
    云计算之路-阿里云上:黑色1秒,微软的问题还是阿里云的问题?团队
    [网站公告]18:07-18:20阿里云SLB故障造成网站不能正常访问团队
    上周热点回顾(6.2-6.8)团队
    云计算之路-阿里云上:受够了OCS,改用ECS+Couchbase跑缓存团队
  • 原文地址:https://www.cnblogs.com/wucg/p/2359392.html
Copyright © 2020-2023  润新知