Как получить фильтр для перенаправления на другое действие? - PullRequest
76 голосов
/ 15 февраля 2009

RedirectToAction защищен, и мы можем использовать его только внутри действий. Но если я хочу перенаправить в фильтр?

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

Ответы [ 5 ]

101 голосов
/ 15 февраля 2009

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" } 
                });
        }
    }
}
88 голосов
/ 02 июля 2010

Вот пример кода:

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);
    }
}
1 голос
/ 25 марта 2015

Я знаю, что немного опаздываю на вечеринку, но я использовал решение 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, так и метод расширения, который расширяет filterContext. Надеюсь, кто-то найдет это полезным.

ObjectDictionary - это класс, который использует отражение для создания словаря из свойств объекта, из которого он построен. Я не включил этот код, потому что я считаю, что есть лучший способ сделать это где-нибудь в рамках. Я еще не нашел его, но я не хочу, чтобы другие унаследовали мои потенциальные ошибки.

0 голосов
/ 12 июля 2017

Использование: filterContext.RedirectToAction("Login", "Account");

Вот вспомогательный класс, который я написал с некоторыми методами расширения, написанными для обеспечения функциональности RedirectToAction в других местах. Это слишком поздно для ОП, но, надеюсь, кому-то это поможет!

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;
    }
}

Существует больше ControllerContexts, которые не включены, но добавить свои собственные, исходя из ваших потребностей, должно быть довольно легко.

0 голосов
/ 08 февраля 2015

Фильтры безопасности / авторизации / аутентификации должны использовать AuthorizeAttribute и IAuthorizationFilter .

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" } 
                });
        }
    }
}
...