Answers:
设置filterContext.Result
带有路线名称:
filterContext.Result = new RedirectToRouteResult("SystemLogin", routeValues);
您还可以执行以下操作:
filterContext.Result = new ViewResult
{
ViewName = SharedViews.SessionLost,
ViewData = filterContext.Controller.ViewData
};
如果要使用RedirectToAction
:
您可以RedirectToAction
在控制器(最好在其基本控制器)上创建一个公共方法,该方法只需调用protected RedirectToAction
from System.Web.Mvc.Controller
。添加此方法可允许您 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");
}
protected
这样您就无法从过滤器访问它。
protected
必须有一些合理的解释?重新定义这种可访问性的过程让我感到非常肮脏,RedirectToAction
但却没有理解为什么首先将其封装。
作为重定向的替代方法,如果它正在调用您自己的代码,则可以使用以下命令:
actionContext.Result = new RedirectToRouteResult(
new RouteValueDictionary(new { controller = "Home", action = "Error" })
);
actionContext.Result.ExecuteResult(actionContext.Controller.ControllerContext);
它不是纯粹的重定向,但会产生类似的结果而没有不必要的开销。
actionContext.Result.ExecuteResult
从操作过滤器中进行调用-MVC将在操作过滤器运行后自动执行此操作(提供的actionContext.Result
值不为null)。
我正在使用MVC4,我使用以下方法在违反授权时重定向自定义html屏幕。
扩展AuthorizeAttribute
说CutomAuthorizer
覆盖OnAuthorization
和HandleUnauthorizedRequest
在CustomAuthorizer
中注册RegisterGlobalFilters
。
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" }
});
}
}
听起来您想重新实现或可能扩展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);
}
}
如果您使用的是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();
}
您可以继承控制器,然后在动作过滤器中使用它
在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”类