我在现有的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
...
}
}
答案 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();
}
}