从动作过滤器重定向属性

ActionFilterAttribute中执行重定向的最佳方法是什么。我有一个名为 IsAuthenticatedAttributeFilterActionFilterAttribute,它检查会话变量的值。如果变量为 false,我希望应用程序重定向到登录页面。我更喜欢使用路由名称 SystemLogin进行重定向,但此时任何重定向方法都可以。

146258 次浏览

设置 filterContext. Result

路线名称:

filterContext.Result = new RedirectToRouteResult("SystemLogin", routeValues);

你也可以这样做:

filterContext.Result = new ViewResult
{
ViewName = SharedViews.SessionLost,
ViewData = filterContext.Controller.ViewData
};

如果你想使用 RedirectToAction:

您可以在控制器(最好是在它的基础控制器上)上创建一个公共 RedirectToAction方法,它只从 System.Web.Mvc.Controller调用受保护的 RedirectToAction。添加此方法允许从过滤器对 你的RedirectToAction进行公共调用。

public new RedirectToRouteResult RedirectToAction(string action, string controller)
{
return base.RedirectToAction(action, controller);
}

然后你的过滤器看起来像这样:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
var controller = (SomeControllerBase) filterContext.Controller;
filterContext.Result = controller.RedirectToAction("index", "home");
}

听起来您想要重新实现或者可能扩展 AuthorizeAttribute。如果是这样,那么您应该确保继承了这个特性,而不是 ActionFilterAttribute,以便让 ASP.NET MVC 为您做更多的工作。

此外,您还需要确保授权 之前执行操作方法中的任何实际工作——否则,登录与不登录之间的唯一区别将是完成工作后看到的页面。

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 屏幕。

扩展 AuthorizeAttributeCutomAuthorizer 重写 OnAuthorizationHandleUnauthorizedRequest

RegisterGlobalFilters中注册 CustomAuthorizer

public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{


filters.Add(new CustomAuthorizer());
}

在识别 unAuthorized访问调用 HandleUnauthorizedRequest并重定向到相关的控制器操作时,如下所示。


public class CustomAuthorizer : AuthorizeAttribute
{


public override void OnAuthorization(AuthorizationContext filterContext)
{
bool isAuthorized = IsAuthorized(filterContext); // check authorization
base.OnAuthorization(filterContext);
if (!isAuthorized && !filterContext.ActionDescriptor.ActionName.Equals("Unauthorized", StringComparison.InvariantCultureIgnoreCase)
&& !filterContext.ActionDescriptor.ControllerDescriptor.ControllerName.Equals("LogOn", StringComparison.InvariantCultureIgnoreCase))
{


HandleUnauthorizedRequest(filterContext);


}
}


protected override void HandleUnauthorizedRequest(AuthorizationContext filterContext)
{
filterContext.Result =
new RedirectToRouteResult(
new RouteValueDictionary\{\{ "controller", "LogOn" },
{ "action", "Unauthorized" }


});


}
}

下面的解决方案还考虑了使用 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);
}
}
}

这对我很有用(asp.net core 2.1)

using JustRide.Web.Controllers;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;


namespace MyProject.Web.Filters
{
public class IsAuthenticatedAttribute : ActionFilterAttribute
{
public override void OnActionExecuting(ActionExecutingContext context)
{
if (context.HttpContext.User.Identity.IsAuthenticated)
context.Result = new RedirectToActionResult(nameof(AccountController.Index), "Account", null);
}
}
}






[AllowAnonymous, IsAuthenticated]
public IActionResult Index()
{
return View();
}