我试图在 IRouteHandler 类的 GettHttpHandler 方法中启用会话,但会话始终为空。有人可以告诉我我做错了什么吗?
在 global.asax 我有
RouteTable.Routes.Add("All", new Route("{*page}", new MyRouteHandler()));
Session 为 null 的 MyRouteHandler 类如下所示:
public class MyRouteHandler : IRouteHandler, IRequiresSessionState
{
public System.Web.IHttpHandler GetHttpHandler(RequestContext requestContext)
{
string test = HttpContext.Current.Session["test"].ToString();
return BuildManager.CreateInstanceFromVirtualPath("~/Page.aspx", typeof(Page)) as Page;
}
}
我做了一个小test app这说明了问题所在。
有人可以告诉我我做错了什么吗?
Edited to add:
是的,我确实需要路由处理程序中的会话数据。原因有很多,但一个很容易解释的原因是用户可以切换到以预览模式浏览网站。
该站点由数据库中的动态页面(/page1/page2...)层次结构组成,可以正常发布或预览。浏览网站的内容制作者可以选择仅查看普通页面或发布预览的页面。浏览模式存储在用户的会话中,因此路由处理程序需要知道浏览模式才能解决所请求的页面。
所以我真的需要在那个阶段就进行会议。
我已经解释了这个问题背后的原因这个答案。现在我已经找到了解决问题的方法!
-
您创建一个自定义HttpHandler class:
class MyHttpHandler : IHttpHandler, IRequiresSessionState
{
public MyRequestHandler RequestHandler;
public RequestContext Context;
public MyHttpHandler(MyRequestHandler routeHandler, RequestContext context)
{
RequestHandler = routeHandler;
Context = context;
}
public void ProcessRequest(HttpContext context)
{
throw new NotImplementedException();
}
public bool IsReusable
{
get { throw new NotImplementedException(); }
}
}
重要的是要添加IRequiresSessionState接口,否则 IIS 不会为此请求加载会话。我们不需要实现以下逻辑ProcessRequest
and IsReusable
,但类必须实现 IHttpHandler 接口。
-
您更改 RouteHandler 实现:
public class MyRequestHandler : IRouteHandler
{
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
return new MyHttpHandler(this, requestContext);
}
public IHttpHandler DelayedGetHttpHandler(RequestContext requestContext)
{
// your custom routing logic comes here...
}
}
您只需将原始的、依赖于会话的逻辑移至DelayedGetHttpHandler
函数并且在GetHttphandler
函数返回一个有帮助的 MyHttpHandler 类的实例。
-
然后,将处理逻辑挂接到HttpApplication.PostAcquireRequestState
事件,例如在 Global.asax 中:
public class Global : HttpApplication
{
public override void Init()
{
base.Init();
PostAcquireRequestState += Global_PostAcquireRequestState;
}
}
如需更多参考,请查看此页面:https://msdn.microsoft.com/en-us/library/bb470252(v=vs.140).aspx。它解释了请求生命周期以及为什么我使用PostAcquireRequestState
event.
-
在事件处理程序中,您调用自定义 RouteHandling 函数:
void Global_PostAcquireRequestState(object sender, EventArgs e)
{
if (HttpContext.Current.Handler is MyHttpHandler) {
var handler = HttpContext.Current.Handler as MyHttpHandler;
HttpContext.Current.Handler = handler.RouteHandler.DelayedGetHttpHandler(handler.Context);
}
}
就是这样。对我有用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)