如何将参数从动作过滤器传递到控制器方法

时间:2015-07-03 07:46:15

标签: c# asp.net asp.net-core-mvc

我想制作自定义身份验证过滤器。如果一切顺利,它应该返回用户。但是,在控制器中,我再次需要它来找到用户,但是在数据库中再次搜索他将是低效的。我想重用ActionFilter中获得的信息。这是伪代码,它显示了我想要实现的目标:

public class AuthenticateAttribute : ActionFilterAttribute
{
    public async override void OnActionExecuting(ActionExecutingContext context)
    {
        // some code here...
        var user = // some code...

        if (user == null)
        {
            // error, not authenticated
        }

        // yes! authentication succeeded! now we have found the user, it would be clever to pass
        // it to the controller method so that it does not have to look it up once again in the database
        parameters.Add("userFound", user);
    }
}

有办法做到这一点吗?我想在控制器方法中访问它,无论如何。例如:

parameters["userFound"]

谢谢!

1 个答案:

答案 0 :(得分:0)

ActionExecutingContext中,您拥有对控制器和请求的完全访问权限,那么您可以在很多地方放置参数,仅举几例:

  • context.Controller.ViewBag,您也可以在自己的视图中访问它。
  • context.Controller.ViewData,它也可以在您的视图中访问。
  • context.HttpContext.Session,如果您正在使用会话。

请记住,ActionExecutingContext来自ControllerContext,而ControllerContext可在控制器的任何位置访问。

但是我要避免这种情况,因为它(至少对我来说)有点奇怪。您的控制器将根据该参数采取不同的操作(与User.IsAuthenticated上的检查没有太大区别)然后我真正要做的是重定向到差异操作方法,在您的操作中过滤器:

if (user == null) // not authenticated
{
    var data = context.HttpContext.Request.RequestContext.RouteData;
    var currentAction = data.GetRequiredString("action");
    var currentController = data.GetRequiredString("controller");

    context.Result = new RedirectToRouteResult(
        new RouteValueDictionary 
        { 
            { "controller", currentController }, 
            { "action", currentAction + "_NotAuthenticated" } 
    });
}