How to get filter to redirect to another action?

后端 未结 5 922
伪装坚强ぢ
伪装坚强ぢ 2020-12-13 07:52

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

public class IsGuestAttribute: Acti         


        
相关标签:
5条回答
  • 2020-12-13 08:38

    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.

    0 讨论(0)
  • 2020-12-13 08:39

    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.

    0 讨论(0)
  • 2020-12-13 08:41

    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" } 
                    });
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-13 08:42

    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" } 
                    });
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-13 08:46

    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);
        }
    }
    
    0 讨论(0)
提交回复
热议问题