web api 2 - 将动作过滤器中的数据作为参数传递给action

时间:2014-11-19 21:33:52

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

为了避免在每次操作中获取用户数据,我创建了一个自定义操作过滤器,该过滤器通过其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);
        }
}

我可以在动作方法中获取用户对象,如下所示:

[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中有一种方法可以将User对象从动作过滤器传递给作为参数的动作,就像在MVC中一样?

1 个答案:

答案 0 :(得分:4)

使用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内创建的实例绑定到该参数。