asp.net-mvc 如何让过滤器重定向到另一个动作?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/550995/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get filter to redirect to another action?
提问by appqui-platform
RedirectToActionis protected, and we can use it only inside actions. But if I want to redirect in a filter?
RedirectToAction是受保护的,我们只能在动作中使用它。但是如果我想在过滤器中重定向?
public class IsGuestAttribute: ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (!Ctx.User.IsGuest)
filterContext.Result = (filterContext.Controller as Controller)
.RedirectToAction("Index", "Home");
}
}
回答by veggerby
RedirectToActionis 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.
RedirectToAction只是构造 a 的辅助方法RedirectToRouteResult(),因此您所做的只是为您的操作创建RedirectToRouteResult()一个RouteValueDictionary()带有值的新传递。
Complete sample based on code from @Domenic in the comment below:
基于@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" }
});
}
}
}
回答by StuperUser
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);
}
}
回答by Jordan
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:
我知道我参加聚会有点晚了,但是我使用了 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);
}
}
I provided both a static method that returns a redirect ActionResultand an extension method that extends filterContext. Hope someone finds this useful.
我提供了一个返回重定向的静态方法ActionResult和一个扩展方法filterContext。希望有人觉得这很有用。
ObjectDictionaryis 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.
ObjectDictionary是一个使用反射从构造它的对象的属性创建字典的类。我没有包含该代码,因为我相信在框架中的某个地方有更好的方法来做到这一点。我还没有找到它,但我不希望其他人继承我的潜在错误。
回答by Austin Hummel
Usage:filterContext.RedirectToAction("Login", "Account");
用法: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!
这是我编写的一个辅助类,其中包含一些扩展方法,用于在更多地方提供 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;
}
}
There are more ControllerContexts that are not included but it should be fairly easy to add your own based on your needs.
还有更多的 ControllerContexts 未包含在内,但根据您的需要添加您自己的应该相当容易。
回答by Erik Philips
Security/Authorization/Authentication Filters should use the AuthorizeAttributeand IAuthorizationFilter.
安全/授权/身份验证过滤器应使用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" }
});
}
}
}

