GlobalActionFilter中的重定向失败

时间:2015-03-13 14:29:15

标签: c# asp.net-mvc redirect

我创建了一个GlobalActionFilter,用于将登录用户重定向到我网站上的指定页面。这与我之前提出的有关全局重定向(Need recommendation for global, targeted redirects on ASP.NET MVC site for multiple differing conditions

的问题有关

此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内部的代码块之后[&#34; ForceQA&#34;] ==&#34; 1&#34;运行,我希望被重定向到MyInfo / ChangeSecurityQuestions视图,但是没有发生。并且没有例外被抛出。

正在使用&#34; filterContext.Result&#34;正确的方法,如果是这样,我需要添加一些额外的代码行,以便成功重定向浏览器?

感谢您的帮助。

===编辑2015年3月13日上午10:33中央===

感谢大家的帮助和想法。现在我怀疑我的RedirectToRouteResult语法有问题。如果我用这行代码替换它,浏览器会重定向到Yahoo。

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

=== 2015年3月13日上午11:00编辑===

感谢Angelo和NightOwl。以下是我最终申请的修复方法。

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。这也检查当前的控制器和动作,以便当浏览器落在其中一个目标页面上时,它不会循环通过重定向循环。我会稍微清理一下,但基本上这是固定的。感谢。

1 个答案:

答案 0 :(得分: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");