zoukankan      html  css  js  c++  java
  • 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.

  • 相关阅读:
    ESXI | ESXI6.7如何在网页端添加用户并且赋予不同的权限 风行天下
    网页前端 风行天下
    Zabbix远程命令权限不足问题解决方法 风行天下
    CentOS 8时间同步 风行天下
    linux之mv命令排除某个文件或文件夹 风行天下
    zabbix已是运行状态但zabbix server is not running解决办法 风行天下
    centos7进入救援模式,修复错误配置 风行天下
    Centos7 rsync 实现文件同步 风行天下
    python基础之socket与socketserver 风行天下
    linux中命令cp复制拷贝访问权限和修改时间 风行天下
  • 原文地址:https://www.cnblogs.com/wucg/p/2359392.html
Copyright © 2011-2022 走看看