C# 从操作筛选器属性重定向
在C# 从操作筛选器属性重定向,c#,asp.net-mvc,asp.net-mvc-3,redirect,routes,C#,Asp.net Mvc,Asp.net Mvc 3,Redirect,Routes,在ActionFilterAttribute中执行重定向的最佳方式是什么。我有一个名为IsAuthenticatedAttributeFilter的ActionFilterAttribute检查会话变量的值。如果变量为false,我希望应用程序重定向到登录页面。我更愿意使用路由名称SystemLogin进行重定向,但是此时任何重定向方法都可以。设置filterContext.Result 使用路由名称: filterContext.Result = new RedirectToRouteResu
ActionFilterAttribute
中执行重定向的最佳方式是什么。我有一个名为IsAuthenticatedAttributeFilter
的ActionFilterAttribute
检查会话变量的值。如果变量为false,我希望应用程序重定向到登录页面。我更愿意使用路由名称SystemLogin
进行重定向,但是此时任何重定向方法都可以。设置filterContext.Result
使用路由名称:
filterContext.Result = new RedirectToRouteResult("SystemLogin", routeValues);
您还可以执行以下操作:
filterContext.Result = new ViewResult
{
ViewName = SharedViews.SessionLost,
ViewData = filterContext.Controller.ViewData
};
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var controller = (SomeControllerBase) filterContext.Controller;
filterContext.Result = controller.RedirectToAction("index", "home");
}
如果要使用
重定向到操作
:
您可以在控制器上(最好是在其基本控制器上)公开RedirectToAction
方法,该方法只需从System.Web.Mvc.controller
调用受保护的RedirectToAction
。添加此方法允许从筛选器对您的RedirectToAction
进行公共调用
public new RedirectToRouteResult RedirectToAction(string action, string controller)
{
return base.RedirectToAction(action, controller);
}
然后,您的过滤器将类似于:
filterContext.Result = new ViewResult
{
ViewName = SharedViews.SessionLost,
ViewData = filterContext.Controller.ViewData
};
public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var controller = (SomeControllerBase) filterContext.Controller;
filterContext.Result = controller.RedirectToAction("index", "home");
}
听起来您想重新实现或可能扩展,
AuthorizeAttribute
。如果是这样,您应该确保继承了它,而不是ActionFilterAttribute
,以便让ASP.NET MVC为您做更多的工作
此外,您希望确保在执行action方法中的任何实际工作之前进行授权-否则,登录和不登录之间的唯一区别将是完成工作时看到的页面
public class CustomAuthorizeAttribute : AuthorizeAttribute
{
public override void OnAuthorization(AuthorizationContext filterContext)
{
// Do whatever checking you need here
// If you want the base check as well (against users/roles) call
base.OnAuthorization(filterContext);
}
}
这里有一个关于详细信息的好例子。试试下面的片段,应该很清楚:
public class AuthorizeActionFilterAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(FilterExecutingContext filterContext)
{
HttpSessionStateBase session = filterContext.HttpContext.Session;
Controller controller = filterContext.Controller as Controller;
if (controller != null)
{
if (session["Login"] == null)
{
filterContext.Cancel = true;
controller.HttpContext.Response.Redirect("./Login");
}
}
base.OnActionExecuting(filterContext);
}
}
您可以继承控制器,然后在操作筛选器中使用它 在ActionFilterAttribute类中:
if( filterContext.Controller is MyController )
if(filterContext.HttpContext.Session["login"] == null)
(filterContext.Controller as MyController).RedirectToAction("Login");
在您的基本控制器内:
public class MyController : Controller
{
public void RedirectToAction(string actionName) {
base.RedirectToAction(actionName);
}
}
犯人。其中之一是将所有控制器更改为从“MyController”类继承,或者更改为重定向,如果它正在调用您自己的代码,您可以使用以下方法:
actionContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(new { controller = "Home", action = "Error" })
);
actionContext.Result.ExecuteResult(actionContext.Controller.ControllerContext);
这不是一个纯粹的重定向,但在没有不必要的开销的情况下给出了类似的结果。我正在使用MVC4,我使用以下方法在违反授权时重定向自定义html屏幕 扩展
AuthorizeAttribute
sayCutomAuthorizer
覆盖OnAuthorization
和HandleUnauthorizedRequest
在注册表全局过滤器
中注册客户授权人
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new CustomAuthorizer());
}
识别未经授权
访问调用HandleUnauthorizedRequest
并重定向至相关控制器操作,如下所示
如果您使用的是Ajax请求,这里有一个解决方案也会考虑到这一点
using System;
using System.Web.Mvc;
using System.Web.Routing;
namespace YourNamespace{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class AuthorizeCustom : ActionFilterAttribute {
public override void OnActionExecuting(ActionExecutingContext context) {
if (YourAuthorizationCheckGoesHere) {
string area = "";// leave empty if not using area's
string controller = "ControllerName";
string action = "ActionName";
var urlHelper = new UrlHelper(context.RequestContext);
if (context.HttpContext.Request.IsAjaxRequest()){ // Check if Ajax
if(area == string.Empty)
context.HttpContext.Response.Write($"<script>window.location.reload('{urlHelper.Content(System.IO.Path.Combine(controller, action))}');</script>");
else
context.HttpContext.Response.Write($"<script>window.location.reload('{urlHelper.Content(System.IO.Path.Combine(area, controller, action))}');</script>");
} else // Non Ajax Request
context.Result = new RedirectToRouteResult(new RouteValueDictionary( new{ area, controller, action }));
}
base.OnActionExecuting(context);
}
}
}
使用系统;
使用System.Web.Mvc;
使用System.Web.Routing;
名称空间名称空间{
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,Inherited=true,AllowMultiple=true)]
公共类授权自定义:ActionFilterAttribute{
公共重写无效OnActionExecuting(ActionExecutingContext上下文){
如果(您的授权检查Goesher){
string area=”“;//如果不使用区域的
字符串控制器=“控制器名称”;
string action=“ActionName”;
var urlHelper=新的urlHelper(context.RequestContext);
if(context.HttpContext.Request.IsAjaxRequest()){//检查Ajax
if(区域==字符串.空)
Write($“window.location.reload('{urlHelper.Content(System.IO.Path.Combine(controller,action))}');”;
其他的
Write($“window.location.reload({urlHelper.Content(System.IO.Path.Combine(area、controller、action))));”;
}else//非Ajax请求
context.Result=新的RedirectToRouteResult(新的RouteValueDictionary(新的{area,controller,action}));
}
base.OnActionExecuting(上下文);
}
}
}
这对我很有用(asp.net core 2.1)
这是可行的,但是不应该有一个RedirectToAction方法吗?@BenMills有,但是,它是受保护的,所以你不能从过滤器访问它。我现在的问题是,为什么微软决定让这个过滤器受保护?必须有一些合理的解释?重新定义
RedirectToAction
的这种可访问性时,我感到非常不愉快,因为我不理解它最初被封装的原因。@MatthewMarlin-有关重定向到某个操作的正确答案,请参阅Syakur的答案。您不应该直接从操作筛选器调用控制器,这是紧耦合的定义,这是正确的。@Akbari您是否尝试过设置属性的Order属性?此外,FilterScope将影响执行顺序。这对我来说很有效,如果任何用户试图更改查询字符串值并尝试访问未经授权的数据,我必须检查查询字符串值,而我使用ActionFilterAttribute将其重定向到未经授权的消息页。你确实帮了我。谢谢请注意,您不应该从操作筛选器中调用actionContext.Result.ExecuteResult
,MVC将在操作筛选器运行后自动执行该操作(前提是actionContext.Result
不为空)。