I have spent quite some time going through similar questions here and have not found any that answer my question - apologies if this is a duplicate however I'm pretty sure it's not..
I have an website where the aim is for visitors to complete a form. I am interested in testing different type of forms to ascertain which get filled out more consistently. My idea is that each form has it's own controller and when the user first requests the url it is picked up by a custom route handler which picks 1 form at random and set the relevant controller in RouteData. The chosen formid is then stored in the Session so on subsequnt requests instead of a form being picked at random it will just use the one from the session.
The probem is that I cannot seem to access the Session data in the routehandler - requestContext.Httpcontext.Session is always null. Is this because it is too early in the pipeline? if so how could I achieve this approach?
The first code I tried looked like this:
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);
This always errored as requestContext.HttpContext.Session
is null
I have tried with a custom routehandler then passing off to a custom http handler as follows:
Routehandler
requestContext.HttpContext.SetSessionStateBehavior(GetSessionStateBehavior(requestContext));
IHttpHandler handler = new FormMvcHandler(requestContext); return handler;
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);
}
}
In this second approach changing the controller name has no effect. I have tried changing the controller name in the constructor of the HTTPHandler which does have an effect however If I try and access the session from there using RequestContext.HttpContext.Session it is still null. I have tried setting a breakpoint in ProcessRequest however it is never hit.
Edit 2
This now works by overriding both ProcessRequest(HttpContext httpContext)
and BeginProcessRequest(HttpContext httpContext)
in the HttpHandler - even when not using an async controller BeginProcessRequest is called by the framework (v3)