简体   繁体   English

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

[英]How to pass a parameter from action filter to a controller method

I want to make a custom authentication filter. 我想做一个自定义的认证过滤器。 If everything succeeds, it should return the user. 如果一切成功,它将返回用户。 But, in the controller, I need it again to find the user, but this would be inefficient to search for him once again in the database. 但是,在控制器中,我再次需要它来查找用户,但这在数据库中再次搜索他的效率很低。 I want to reuse the information gained in the ActionFilter . 我想重用在ActionFilter获得的信息。 This is the pseudocode that shows exactly what I am trying to achieve: 这是伪代码,确切显示了我要实现的目标:

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

Is there a way to do this? 有没有办法做到这一点? I would like then to access it in the controller method, no matter how. 我想无论如何都可以通过controller方法访问它。 For example like this: 例如这样:

parameters["userFound"]

Thanks! 谢谢!

In ActionExecutingContext you have full access to controller and request then you have many places you can put your parameter, just to mention few: ActionExecutingContext您具有对控制器和请求的完全访问权限,然后您可以在许多地方放置参数,这里仅ActionExecutingContext几个:

  • context.Controller.ViewBag , it's also accessible in your view. context.Controller.ViewBag ,它也可以在您的视图中访问。
  • context.Controller.ViewData, it's also accessible in your view. context.Controller.ViewData,也可以在您的视图中访问它。
  • context.HttpContext.Session , if you're using session. context.HttpContext.Session ,如果您正在使用会话。

Remember that ActionExecutingContext derives from ControllerContext and ControllerContext is accessible everywhere in your controller. 请记住, ActionExecutingContextControllerContext派生的,并且ControllerContext可以在控制器中的任何位置访问。

However I'd avoid this because it's (at least to me) little bit strange. 但是我会避免这种情况,因为(至少对我而言)这有点奇怪。 Your controller will take a different action according to that parameter (not much different than a check on User.IsAuthenticated ) then what I would really do is to redirect to a differenct action method, in your action filter: 您的控制器将根据该参数执行不同的操作(与对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" } 
    });
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM