Сессия пуста в RouteHandler - PullRequest
       1

Сессия пуста в RouteHandler

2 голосов
/ 11 января 2012

Я потратил довольно много времени на изучение подобных вопросов и не нашел ни одного ответа на мой вопрос - извинения, если это дубликат, но я уверен, что это не так.

У меня есть веб-сайт, на котором посетители должны заполнить форму. Я заинтересован в тестировании различных типов форм, чтобы выяснить, какие из них заполняются более последовательно. Моя идея состоит в том, что у каждой формы есть свой собственный контроллер, и когда пользователь впервые запрашивает URL-адрес, он выбирается пользовательским обработчиком маршрута, который выбирает 1 форму случайным образом и устанавливает соответствующий контроллер в RouteData. Выбранный формид затем сохраняется в сеансе, поэтому при последующих запросах вместо произвольно выбираемой формы он просто использует форму из сеанса.

Проблема в том, что я не могу получить доступ к данным 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, он все еще нулевой. Я попытался установить точку останова в ProcessRequest, однако она никогда не срабатывает.

Редактировать 2

Теперь это работает, переопределяя ProcessRequest(HttpContext httpContext) и BeginProcessRequest(HttpContext httpContext) в HttpHandler - даже если не используется асинхронный контроллер, BeginProcessRequest вызывается платформой (v3)

Ответы [ 3 ]

2 голосов
/ 19 января 2012

В вашем RouteHandler у вас есть функция GetHttpHandler, которая возвращает IHttpHandler. Этот пользовательский HttpHandler должен использовать IRequiresSessionState, а затем вы можете получить доступ к сеансу в функции ProcessRequest в HttpHandler.

0 голосов
/ 18 января 2012

Слишком рано использовать Session в маршрутизаторе.

Вы можете достичь желаемого с помощью фильтра действий.

Создайте контроллер с именем FormController, действие с именем FormPickerAttribute.В ActionExecuting атрибута вы можете проверить cookie или сеанс, где установлен ваш идентификатор формы.допустим, идентификатор формы равен «Form1» (создайте его, если он равен нулю), затем вы измените методы действия на «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"}

на правильный.

0 голосов
/ 11 января 2012

Загляните в этот пост:

IRequiresSessionState - как мне его использовать?

Я думаю, вам нужно использовать интерфейс IRequiresSessionState

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...