How to get filter to redirect to another action?

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");
}
}
48108 次浏览

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

下面是一个代码示例:

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

安全/授权/认证过滤器应使用 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" }
});
}
}
}

我知道我有点迟到了,但是我使用了 veggerby 的解决方案,并且构建了一个可能对某些人有用的 helper 类,所以我想在这里提供它:

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是一个使用反射从构造它的对象的属性创建字典的类。我没有包含这些代码,因为我相信在框架的某个地方有更好的方法来实现这一点。我还没找到,但我不想让别人继承我的潜在病毒。

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

下面是我用一些扩展方法编写的一个 helper 类,它在更多地方提供了 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 没有包括在内,但是根据您的需要添加您自己的控制器应该相当容易。