2012-01-10 25 views
2

我花了相當長的一段時間,通過類似的問題會在這裏並沒有發現任何回答我的問題 - 道歉,如果這是一個重複的,但是我敢肯定它不是..會議是RouteHandler

我有一個網站,其目的是讓參觀者填寫表格。我有興趣測試不同類型的表格,以確定哪些表格更加一致。我的想法是,每個表單都有它自己的控制器,當用戶第一次請求URL時,它會被一個自定義路由處理程序拾取,該處理程序隨機選擇1個窗體並在RouteData中設置相關的控制器。然後選擇的formid被存儲在Session中,所以在後面的請求中,而不是隨機挑選的表單,它將只使用會話中的一個。

probem是我似乎無法訪問路由處理程序中的會話數據 - requestContext.Httpcontext.Session始終爲空。這是因爲現在太早了嗎?如果是的話,我怎麼能實現這個方法?

我嘗試的第一個代碼是這樣的:

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是空

我有那麼一個自定義routehandler假冒的自定義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

這就是現在的工作原理是在HttpHandler的覆蓋都ProcessRequest(HttpContext httpContext)BeginProcessRequest(HttpContext httpContext) - 不使用異步控制器BeginProcessRequest由框架(V3)稱爲

+0

你可以發佈你的自定義路由處理程序/你現在在哪裏? – Tommy 2012-01-16 17:55:18

回答

2

在你的RouteHandler中你有一個函數Ge​​tHttpHandler,它返回一個IHttpHandler。該自定義HttpHandler必須使用IRequiresSessionState,然後才能在HttpHandler的ProcessRequest函數中訪問Session。

0

看看這個帖子甚至當:

IRequiresSessionState - how do I use it?

我認爲你需要使用IRequiresSessionState接口

+0

我試過這個,它沒有區別 - 從我所瞭解的IRequiresSessionState被設計爲在HttpHandler上使用,而不是RouteHandler – Macros 2012-01-11 09:03:46

+0

在您的RouteHandler中,您有一個函數Ge​​tHttpHandler,它返回一個IHttpHandler。該自定義HttpHandler必須使用IRequiresSessionState,然後才能在HttpHandler的ProcessRequest函數中訪問Session。 – Wim 2012-01-16 15:56:11

+0

我試過這種方法並更新了我的問題 – Macros 2012-01-18 08:21:34

0

在路由器hander中使用Session還爲時尚早。

你可以使用動作過濾器實現你想要的。

創建一個名爲FormController的控制器,一個名爲FormPickerAttribute的動作。在ActionExecuting屬性中,您可以檢查cookie或會話,您設置的表單ID。假設表單ID是「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

我確實嘗試了這樣的方法,但我不希望URL更改 – Macros 2012-01-19 08:16:49