【问题标题】:web api 2 - Passing data from action filter to action as an argumentweb api 2 - 将数据从动作过滤器传递到动作作为参数
【发布时间】:2014-11-20 18:33:50
【问题描述】:

为了避免获取每个操作的用户数据,我创建了一个自定义操作过滤器,该过滤器通过用户 ID 获取用户,然后传递给操作。

public class UserDataAttribute : ActionFilterAttribute
{    
        public override void OnActionExecuting(HttpActionContext actionContext)
        {
            ...
            // getting the user and storing it in the request properties
            object user = userBLL.GetUserById(userId);
            actionContext.Request.Properties.Add("User", user);
        }
}

我可以像这样在 action 方法中获取用户对象:

[Authorize]
[UserData]
[HttpGet]
[Route("dosomething")]
public IHttpActionResult DoSomething()
{
      // retrieve the user
      object user;
      Request.Properties.TryGetValue("User", out user);
      User u = (User)user;

      return Ok();
}

但是,在 MVC 中,可以在过滤器中使用 ActionParameters 来存储操作方法将使用的内容,如下所示:

public override void OnActionExecuting(ActionExecutingContext filterContext)
{
     ...

     // Create object parameter.
     filterContext.ActionParameters["User"] = userBLL.GetUserById(userId);
 }

然后像原始请求的一部分一样使用 User 对象:

[AddActionParameter]
public ActionResult Index(User user)
{
    // Here I can access the user setted on the filter
    ...

    return View();
}

所以,我的问题是:Web API 2 中有一种方法可以将动作过滤器中的用户对象作为参数传递给动作,就像在 MVC 中一样?

【问题讨论】:

    标签: asp.net-mvc-5 asp.net-web-api2


    【解决方案1】:

    使用 ASP.NET Web API,您可以创建参数绑定来接收对象,在您的情况下为 User。您不必为此创建过滤器。因此,您将创建一个这样的绑定。

    public class UserParameterBinding : HttpParameterBinding
    {
        public UserParameterBinding(HttpParameterDescriptor descriptor) : 
                                                            base(descriptor) { }
    
        public override Task ExecuteBindingAsync(ModelMetadataProvider metadataProvider, 
                                                   HttpActionContext context,
                                                      CancellationToken cancellationToken)
        {
            SetValue(context, new User() { // set properties here });
    
            return Task.FromResult<object>(null);
        }
    }
    

    然后,要使用绑定,您将像这样配置它。

    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // snip
    
            config.ParameterBindingRules.Insert(0, d => 
                d.ParameterType == typeof(User) ? new UserParameterBinding(d) : null);
    
            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }
    

    这样,无论您将User 作为操作方法参数,它都会自动将您在UserParameterBinding 中创建的实例绑定到该参数。

    【讨论】:

    • 完美,非常感谢!仅作记录:为了在 ExecuteBindingAsync 方法中注入“userBLL”,我使用了 _userBLL = (IUserBLL) context.ControllerContext.Configuration.DependencyResolver.GetService(typeof(IUserBLL));
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-07
    • 1970-01-01
    相关资源
    最近更新 更多