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
say
CutomAuthorizer
覆盖
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
不为空)。