如何获取过滤器以重定向到其他操作?


77

RedirectToAction受保护,我们只能在动作内部使用它。但是,如果我想在过滤器中重定向?

public class IsGuestAttribute: ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!Ctx.User.IsGuest) 
            filterContext.Result = (filterContext.Controller as Controller)
                .RedirectToAction("Index", "Home");
    }
}

Answers:


104

RedirectToAction只是用来构造的辅助方法RedirectToRouteResult(),因此您要做的就是简单地创建一个新的RedirectToRouteResult()传递以及RouteValueDictionary()带有操作值的。

在以下注释中基于来自@Domenic的代码的完整示例:

public class IsGuestAttribute: ActionFilterAttribute
{
    public override void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!Ctx.User.IsGuest) 
        {
            filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary 
                { 
                    { "controller", "Home" }, 
                    { "action", "Index" } 
                });
        }
    }
}

1
OnException只要您进行设置,您也可以将此代码放入方法中filterContext.ExceptionHandled = true;
demoncodemonkey 2015年

88

这是一个代码示例:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{

    if (!Ctx.User.IsGuest)
    {
        RouteValueDictionary redirectTargetDictionary = new RouteValueDictionary();
        redirectTargetDictionary.Add("action", "Index");
        redirectTargetDictionary.Add("controller", "Home");

        filterContext.Result = new RedirectToRouteResult(redirectTargetDictionary);
    }
}

16
或者只是new RedirectToRouteResult(new RouteValueDictionary { { "controller", "Home" }, {"action", "HomePage" } })
Domenic 2010年

13
如果您只可以说带有绿色
尖锐

1
OnException只要您进行设置,您也可以将此代码放入方法中filterContext.ExceptionHandled = true;
demoncodemonkey 2015年

1

我知道我参加聚会有点晚了,但是我使用了veggerby的解决方案并建立了一个对某些人可能有用的帮助程序类,因此我想在这里提供它:

public static class ActionFilterHelpers
{
    public static void Redirect(this ActionExecutingContext filterContext, String controller, String action, object routeValues)
    {
        filterContext.Result = Redirect(controller, action, routeValues);
    }

    public static ActionResult Redirect(String controller, String action, object routeValues)
    {
        var routeValues = new RouteValueDictionary();

        routeValues["controller"] = controller;
        routeValues["action"] = action;

        foreach (var keyValue in new ObjectDictionary(routeValues))
            routeValues.Add(keyValue.Key, keyValue.Value);

        return new RedirectToRouteResult(routeValues);
    }
}

我提供了返回重定向的静态方法ActionResult和扩展了extension的扩展方法filterContext。希望有人觉得这有用。

ObjectDictionary是一个类,使用反射根据从其构造对象的属性创建字典。我之所以没有包含该代码,是因为我相信在框架中的某个地方有更好的方法可以做到这一点。我还没有找到它,但是我不希望其他人继承我的潜在错误。


0

安全性/授权/身份验证过滤器应使用AuthorizeAttributeIAuthorizationFilter

public class IsGuestAttribute: AuthorizeAttribute, IAuthorizationFilter
{
    public void OnResultExecuted(ResultExecutedContext filterContext)
    {
    }
    public void OnActionExecuting(ActionExecutingContext filterContext)
    {
        if (!Ctx.User.IsGuest) 
        {
            filterContext.Result = new RedirectToRouteResult(
                new RouteValueDictionary 
                { 
                    { "controller", "Home" }, 
                    { "action", "Index" } 
                });
        }
    }
}

0

用法: filterContext.RedirectToAction("Login", "Account");

这是我编写的帮助程序类,其中编写了一些扩展方法,以在更多地方提供RedirectToAction功能。这对于OP来说为时已晚,但希望它能对某人有所帮助!

public static class RedirectHelper
{
    // RedirectToAction Extension Methods
    public static void RedirectToAction(this HttpResponseBase response, String action, String controller, object routeValues = null, bool endResponse = false)
    {
        response.RedirectToRoute(CreateRoute(action, controller, routeValues));
        if (endResponse) response.End();
    }
    public static void RedirectToAction(this HttpResponse response, String action, String controller, object routeValues = null, bool endResponse = false)
    {
        response.RedirectToRoute(CreateRoute(action, controller, routeValues));
        if (endResponse) response.End();
    }
    public static void RedirectToAction(this ActionExecutingContext filterContext, String action, String controller, object routeValues = null, bool endResponse = false)
    {
        if (endResponse) filterContext.HttpContext.Response.RedirectToAction(action, controller, routeValues, true);
        else filterContext.Result = new RedirectToRouteResult(CreateRoute(action, controller, routeValues));
    }
    public static void RedirectToAction(this ExceptionContext filterContext, String action, String controller, object routeValues = null, bool endResponse = false)
    {
        if (endResponse) filterContext.HttpContext.Response.RedirectToAction(action, controller, routeValues, true);
        else {
            filterContext.ExceptionHandled = true;
            filterContext.Result = new RedirectToRouteResult(CreateRoute(action, controller, routeValues));
        }
    }
    // Route Value Derivation
    public static RouteValueDictionary CreateRoute(String action, String controller, object routeValues = null)
    {
        RouteValueDictionary result = routeValues != null ? 
            HtmlHelper.AnonymousObjectToHtmlAttributes(routeValues) : 
            new RouteValueDictionary();
        result["controller"] = controller;
        result["action"] = action;
        return result;
    }
}

还有更多的ControllerContext未包括在内,但是根据需要添加自己的控制器应该很容易。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.