如何从WebSocket请求获取ASP.NET Session对象?

时间:2013-12-16 18:06:18

标签: asp.net websocket session-state

我在现有的ASP.NET项目中实现了一个自定义Web处理程序(ashx)页面,该页面使用Session对象来了解哪些用户是请求页面。 Web处理程序的工作除了一个主要的退回。 Session对象不适用于我的Websocket处理程序任务。

我尝试调用HttpContext.Current.Session,但它为空。

有什么建议吗?

更新

感谢Karl Anderson的回应,我能够取得一些进展,但问题仍然存在。我在处理程序中的代码如下:

public class WSHandler : IHttpHandler, IRequiresSessionState
{
    public void ProcessRequest(HttpContext context)
    {
        if (context.IsWebSocketRequest)
        {
            string s = context.Session["UserName"]; // This works now!
            context.AcceptWebSocketRequest(ProcessWebSocket);
        }
    }

    public bool IsReusable { get { return false; } }

    private async Task ProcessWebSocket(AspNetWebSocketContext context)
    {
        string s = HttpContext.Current.Session["UserName"]; // This still doesn't.  The Session property is null
        ...
    }
}

3 个答案:

答案 0 :(得分:1)

如果您只需要阅读Session对象,那么您需要在HTTP Handler代码中实现IReadOnlySessionState,如下所示:

public class YourHandler : IHttpHandler, IReadOnlySessionState
{
    public void ProcessRequest(HttpContext theContext)
    {
        theContext.Response.Write(theContext.Session["YOUR_VALUE_HERE"]);
    }

    public bool IsReusable { get { return true; } }
}

如果您希望能够读取和写入Session对象,则需要在HTTP处理程序代码中实现IRequiresSessionState

答案 1 :(得分:1)

会话故意不能用于WebSocket处理循环,因为Session有一个默认的两分钟超时,理论上WebSocket连接可以永远持续。

如果您需要从Session中读取数据,请提前读取各个对象(在主ProcessRequest方法中)并将其松散到某个地方,就像在私有字段中一样。如果需要将数据写回Session,则需要使用不同的机制(例如实际的数据库表),而不是使用Session本身。

答案 2 :(得分:0)

我能想到的最好的方法是创建一个调用Web表单来获取/设置会话数据的方法。我知道这不是很有效,但我没有看到任何其他方法。

修改 为此,您需要在Web.Config文件中启用无Cookie会话。对于大多数站点来说,这可能是一个很大的安全风险,因此请记住实施逻辑以防止会话劫持!我目前正在使用IP验证以及浏览器指纹检查。

我创建了一个我在WebSocket处理程序(WSHandler.ashx)中使用的类:

public class SessionData
{
    AspNetWebSocketContext _WebSocketContext = null;

    public SessionData(AspNetWebSocketContext WebSocketContext)
    {
        _WebSocketContext = WebSocketContext;
    }

    public string GetSessionValue(string name)
    {
        string value = "";

        using (WebClient wc = new WebClient())
        {
            string Url = _WebSocketContext.Origin + _WebSocketContext.RawUrl.Replace("WSHandler.ashx", "UpdateSession.aspx");
            Url += "?a=1";
            Url += "&n=" + name;
            value = wc.DownloadString(Url);
        }

        return value;
    }

    public void PutSessionValue(string name, string value)
    {
        using (WebClient wc = new WebClient())
        {
            string Url = _WebSocketContext.Origin + _WebSocketContext.RawUrl.Replace("WSHandler.ashx", "UpdateSession.aspx");
            Url += "?a=2";
            Url += "&n=" + name;
            Url += "&v=" + value;
            wc.DownloadString(Url);
        }
    }

}

以下是Web表单UpdateSession.aspx的表单:

public partial class UpdateSession : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        string action = Page.Request.QueryString["a"];
        string name = Page.Request.QueryString["n"];
        string value = Page.Request.QueryString["v"];

        Page.Response.Clear();

        if (string.IsNullOrEmpty(name) == true)
        {
            return;
        }

        switch (action)
        {
            case "1":
                if (Session[name] != null)
                {
                    Page.Response.Write(Session[name].ToString());
                }
                break;

            case "2":
                Session[name] = value;
                break;
        }

        Page.Response.End();

    }
}