Я потратил довольно много времени на изучение подобных вопросов и не нашел ни одного ответа на мой вопрос - извинения, если это дубликат, но я уверен, что это не так.
У меня есть веб-сайт, на котором посетители должны заполнить форму. Я заинтересован в тестировании различных типов форм, чтобы выяснить, какие из них заполняются более последовательно. Моя идея состоит в том, что у каждой формы есть свой собственный контроллер, и когда пользователь впервые запрашивает 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)