How to get filter to redirect to another action?

烂漫一生 提交于 2019-12-29 03:11:20

问题


RedirectToAction is protected, and we can use it only inside actions. But if I want to redirect in a filter?

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

回答1:


RedirectToAction is just a helper method to construct a RedirectToRouteResult(), so what you do is simply create a new RedirectToRouteResult() passing along a RouteValueDictionary() with values for your action.

Complete sample based on code from @Domenic in the comment below:

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



回答2:


Here's a code example:

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



回答3:


I know that I'm a little bit late to the party, but I used veggerby's solution and built a helper class that may be useful to some people, so I wanted to provide it here:

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

I provided both a static method that returns a redirect ActionResult and an extension method that extends filterContext. Hope someone finds this useful.

ObjectDictionary is a class that uses reflection to create a dictionary from the properties of the object from which it is constructed. I didn't include that code because I believe there is a better way to do that somewhere in the framework. I haven't found it yet, but I don't want others to inherit my potential bugs.




回答4:


Security/Authorization/Authentication Filters should use the AuthorizeAttribute and 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" } 
                });
        }
    }
}



回答5:


Usage: filterContext.RedirectToAction("Login", "Account");

Here's a helper class I wrote with some extension methods written to provide RedirectToAction functionality in more places. This is far too late for the OP but hopefully it helps someone!

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

There are more ControllerContexts that are not included but it should be fairly easy to add your own based on your needs.



来源:https://stackoverflow.com/questions/550995/how-to-get-filter-to-redirect-to-another-action

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!