如何将参数从操作筛选器传递到控制器方法

本文关键字:控制器 方法 筛选 参数 操作 | 更新日期: 2023-09-27 18:00:52

我想制作一个自定义身份验证过滤器。如果一切成功,它应该返回用户。但是,在控制器中,我需要它再次找到用户,但在数据库中再次搜索用户是低效的。我想重用在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"]

谢谢!

如何将参数从操作筛选器传递到控制器方法

ActionExecutingContext中,您可以完全访问控制器和请求,然后您可以在许多地方放置参数,仅举几例:

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

请记住,ActionExecutingContext源自ControllerContextControllerContext在控制器中的任何位置都可以访问。

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

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" } 
    });
}