2015-03-13 40 views
0

我創建了一個GlobalActionFilter來將登錄的用戶重定向到我網站上的指定頁面。這與我詢問有關全局重定向的前一個問題(Need recommendation for global, targeted redirects on ASP.NET MVC site for multiple differing conditionsGlobalActionFilter中的重定向失敗

此GlobalActionFilter中的代碼正在執行,但它並未重定向瀏覽器。我錯過了什麼?以下是Global.asax.cs中的代碼。 ForceExternalUserCompletion()是我的自定義全局操作過濾器。

protected void Application_Start() 
{ 
    AreaRegistration.RegisterAllAreas(); 

    WebApiConfig.Register(GlobalConfiguration.Configuration); 

    GlobalFilters.Filters.Add(new Filters.ForceExternalUserCompletion()); 
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 

    RouteConfig.RegisterRoutes(RouteTable.Routes); 
    BundleConfig.RegisterBundles(BundleTable.Bundles); 
    AuthConfig.RegisterAuth(); 
} 

這裏是我的GlobalActionFilter的代碼。

/// <summary> 
/// Direct a logged in ExternalUser to complete unfinished items. Hierarchy is as follows: 
/// 1. Security Questions 
/// 2. Password Reset 
/// </summary> 
public class ForceExternalUserCompletion : ActionFilterAttribute 
{ 
    public override void OnResultExecuting(ResultExecutingContext filterContext) 
    { 
     base.OnResultExecuting(filterContext); 

     HttpCookie externalUserCookie = filterContext.HttpContext.Request.Cookies["ExternalUser"]; 
     if (externalUserCookie != null) 
     { 
      // 1. Security Questions 
      if (externalUserCookie["ForceQA"] == "1") 
      { 
       filterContext.Result = new RedirectToRouteResult(
        new RouteValueDictionary 
        { 
         { "controller", "MyInfo" }, 
         { "action", "ChangeSecurityQuestions" } 
        }); 

       return; 
      } 

      // 2. Password Reset 
      if (externalUserCookie["ForcePass"] == "1") 
      { 
       filterContext.Result = new RedirectToRouteResult(
        new RouteValueDictionary 
        { 
         { "controller", "MyInfo" }, 
         { "action", "ChangePassword" } 
        }); 

       return; 
      } 
     } 
    } 
} 

通過調試器我可以看到此操作過濾器中的代碼正在執行。 externalUserCookie [「ForceQA」] ==「1」內部的代碼塊運行後,我期望重定向到MyInfo/ChangeSecurityQuestions視圖,但這不會發生。並沒有例外被拋出。

正在使用「filterContext.Result」正確的方法,如果有的話,是否需要添加一些額外的代碼行以便成功重定向瀏覽器?

感謝您的幫助。

===編輯2015年3月13日在10:33中央===

謝謝大家對您的幫助和想法。現在我懷疑RedirectToRouteResult的語法有問題。如果我用這行代碼替換它,瀏覽器會重定向到Yahoo。

filterContext.RequestContext.HttpContext.Response.Redirect("http://www.yahoo.com"); 

===編輯2015年3月13日上午11:00中央===

感謝安傑洛和夜鷹。以下是我最終申請的修復程序。

public class ForceExternalUserCompletion : ActionFilterAttribute 
{ 
    public override void OnResultExecuting(ResultExecutingContext filterContext) 
    { 
     base.OnResultExecuting(filterContext); 

     HttpCookie externalUserCookie = filterContext.HttpContext.Request.Cookies["ExternalUser"]; 
     if (externalUserCookie != null) 
     { 
      string controller = filterContext.RequestContext.RouteData.Values["controller"].ToString(); 
      string action = filterContext.RequestContext.RouteData.Values["action"].ToString(); 

      // 1. Security Questions 
      if (externalUserCookie["ForceQA"] == "1") 
      { 
       // Prevent a perpetual redirect. 
       if (controller != "MyInfo" && action != "ChangeSecurityQuestions") 
       { 
        filterContext.RequestContext.HttpContext.Response.RedirectToRoute(
         new RouteValueDictionary 
        { 
         { "controller", "MyInfo" }, 
         { "action", "ChangeSecurityQuestions" } 
        } 
        ); 
       } 

       return; 
      } 

      // 2. Password Reset 
      if (externalUserCookie["ForcePass"] == "1") 
      { 
       // Prevent a perpetual redirect. 
       if (controller != "MyInfo" && action != "ChangePassword") 
       { 
        filterContext.RequestContext.HttpContext.Response.RedirectToRoute(
         new RouteValueDictionary 
        { 
         { "controller", "MyInfo" }, 
         { "action", "ChangePassword" } 
        } 
        ); 
       } 

       return; 
      } 
     } 
    } 
} 

區別在於此固定代碼使用RedirectToRoute而不是RedirectToRouteResult。這也檢查當前的控制器和動作,以便當瀏覽器着陸在其中一個目標頁面上時,它不會通過重定向循環循環。我會清理一下,但基本上這是固定的。謝謝。

+0

當您返回一個RedirectToRouteResult時,它會向瀏覽器發送一個302(重定向)代碼,並且瀏覽器將在提供的計算爲該路由的鏈接上執行GET操作。這沒有發生? – 2015-03-13 14:32:22

+0

謝謝安傑洛。那是對的。根據Firefox中的「網絡」選項卡,不會向瀏覽器發送302。爲了排除一個特定於瀏覽器的問題,我嘗試過使用Chrome,IE和Firefox。但結果是一樣的。另外,我在這些檢查中添加了幾條評論,看看它們是否寫入瀏覽器,並且確實正在寫入。這是我在ForceQA cookie檢查後插入的一條評論:filterContext.RequestContext.HttpContext。Response.Write(「<! - ForceQA - >」); – 2015-03-13 14:49:10

+0

在你的代碼中是否有任何MVC區域,我唯一能想到的是控制器信息和操作沒有映射到有效的路由,你有一個MyInfoController方法ChangeSecurityQuestions,允許獲取? – 2015-03-13 15:09:51

回答

0

您撥打RedirectToRouteResult的電話是可疑的,因爲您沒有按名稱呼叫路由。我懷疑你沒有得到一個路線匹配。

如果您將參數傳遞給name參數,您將更有可能獲得匹配。

public override void OnResultExecuting(ResultExecutingContext filterContext) 
{ 
    HttpCookie externalUserCookie = filterContext.HttpContext.Request.Cookies["ExternalUser"]; 
    if (externalUserCookie != null) 
    { 
     // 1. Security Questions 
     if (externalUserCookie["ForceQA"] == "1") 
     { 
      filterContext.Result = new RedirectToRouteResult(
       "Default", 
       new RouteValueDictionary 
       { 
        { "controller", "MyInfo" }, 
        { "action", "ChangeSecurityQuestions" } 
       }); 

      return; 
     } 

     // 2. Password Reset 
     if (externalUserCookie["ForcePass"] == "1") 
     { 
      filterContext.Result = new RedirectToRouteResult(
       "Default", 
       new RouteValueDictionary 
       { 
        { "controller", "MyInfo" }, 
        { "action", "ChangePassword" } 
       }); 

      return; 
     } 
    } 

    // If we made it here, pass the call on to the action method 
    base.OnResultExecuting(filterContext); 
} 

如果您只是致電RedirectToAction,可能會更簡單。

filterContext.Result = new RedirectToAction(action: "ChangePassword", controller: "MyInfo"); 
+0

謝謝NightOwl888。我會閱讀該參考。我只是嘗試刪除base.OnResultExecuting(filterContext);總而言之,並且將它移動到支票下方。但這兩個改變都沒有解決重定向。 – 2015-03-13 15:29:56

+0

這是在黑暗中的一槍,但沒有證明是正確的。我已更新我的答案,因爲您的重定向看起來很可疑。 – NightOwl888 2015-03-13 15:38:21

+0

啊,讓我試試RedirectToAction。謝謝。 – 2015-03-13 15:40:38