RouteHandler中的Session为null

时间:2012-01-10 21:32:32

标签: asp.net-mvc

我花了很多时间在这里遇到类似的问题,并没有找到任何回答我的问题 - 道歉,如果这是一个重复,但我很确定它不是..

我有一个网站,目的是让访问者填写表格。我有兴趣测试不同类型的表格,以确定哪些表格更加一致。我的想法是每个表单都有自己的控制器,当用户第一次请求url时,它会被自定义路由处理程序选中,该处理程序随机选择1个表单并在RouteData中设置相关的控制器。然后将选定的formid存储在Session中,这样对于子句点请求而不是随机选择的表单,它只会使用会话中的那个。

探测器是我似乎无法访问routehandler中的Session数据 - requestContext.Httpcontext.Session始终为null。这是因为它还处于早期阶段吗?如果是这样我怎么能实现这种方法?

我试过的第一个代码看起来像这样:

int FormID = 0;
string FormName = "";
RepositoryManager mgr = new RepositoryManager();

if (requestContext.HttpContext.Session["Form_ID"] != null && requestContext.HttpContext.Session["Form_Name"] != null)
{
    int.TryParse(requestContext.HttpContext.Session["Form_ID"].ToString(), out FormID);
    FormName = requestContext.HttpContext.Session["Form_Name"].ToString();
}

if (FormID == 0)
{
    List<Form> forms = mgr.FormRepository.Get(f => f.FormType.Code == "").ToList();
    int rnd = new Random().Next(0, forms.Count - 1);
    FormID = forms[rnd].ID;
    FormName = forms[rnd].FormName;
    requestContext.HttpContext.Session["Form_ID"] = FormID;
    requestContext.HttpContext.Session["Form_Name"].ToString();
}

requestContext.RouteData.Values["controller"] = FormName;
return new MvcHandler(requestContext);

这始终是错误的,因为requestContext.HttpContext.Session为空

我尝试使用自定义路由处理程序,然后传递给自定义http处理程序,如下所示:

Routehandler

requestContext.HttpContext.SetSessionStateBehavior(GetSessionStateBehavior(requestContext));

IHttpHandler handler = new FormMvcHandler(requestContext); 返回处理程序;

FormMVCHandler

    public class FormMvcHandler : MvcHandler, IRequiresSessionState
{
    public FormMvcHandler(RequestContext requestContext)
        : base(requestContext)
    {

    }

    protected override void ProcessRequest(HttpContext httpContext)
    {
        //for testing setting form manually - session will be used here as in original routehandler
        RequestContext.RouteData.Values["controller"] = "1Stage";
        base.ProcessRequest(httpContext);
    }
}

在第二种方法中,更改控制器名称无效。我已经尝试在HTTPHandler的构造函数中更改控制器名称,这确实有效果但是如果我尝试使用RequestContext.HttpContext.Session从那里访问会话它仍然是null。我已经尝试在ProcessRequest中设置断点,但它永远不会被击中。

修改2

现在可以通过覆盖HttpHandler中的ProcessRequest(HttpContext httpContext)BeginProcessRequest(HttpContext httpContext)来工作 - 即使不使用异步控制器,框架也会调用BeginProcessRequest(v3)

3 个答案:

答案 0 :(得分:2)

在你的RouteHandler中你有一个函数Ge​​tHttpHandler,它返回一个IHttpHandler。该自定义HttpHandler必须使用IRequiresSessionState,然后您可以在HttpHandler中的ProcessRequest函数中访问Session。

答案 1 :(得分:0)

看看这篇文章:

IRequiresSessionState - how do I use it?

我认为你需要使用IRequiresSessionState接口

答案 2 :(得分:0)

在路由器处理中使用Session还为时过早。

您可以使用动作过滤器实现您想要的效果。

创建一个名为FormController的Controller,一个名为FormPickerAttribute的动作。在ActionExecuting of属性中,您可以检查cookie或会话,您的设置表单ID。假设表单id为“Form1”(如果为null则创建一个),然后将操作方法​​更改为“Form1”。

filterContext.Result = new RedirectToRouteResult(
              new RouteValueDictionary{
                  { "controller", "Form" },
                  { "action", "Form1" },
                  { "area", ""}, #your area name
                  { "parameter", "parameter value"} #passing any parameter to the action 
              }
);

您还可以为每个表单创建一个控制器,只需更新

{"controller", "FormIdController"}

到正确的。