使用ActionFilter或Custom Model Binder将值添加到Web API模型?

时间:2016-05-05 03:27:12

标签: asp.net-web-api2

我正在使用WebAPI 2,我发现我的大多数API POST端点都要求将相同的两个值添加到模型中:来自HttpContext.Current.User.Identity的 UserId 。来自自定义请求标头的GetUserId()和 SignalR_ConnectionId 。我想将这两个值添加到模型中,而不是在每个请求处理程序中重复相同的代码。

我喜欢使用ActionFilter的想法,因为我可以使用注释轻松地修饰需要此功能的端点。到目前为止,我的ActionFilter如下所示:

public class AddUserIdActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        var headerValues = actionContext.Request.Headers.GetValues("SignalRId");

        if (HttpContext.Current.User.Identity != null)
        {
            Guid userId = Guid.Parse(HttpContext.Current.User.Identity.GetUserId());
        }
        else
        {
            throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Unauthorized));
        }

        //Modify the model??
    }
}

如何修改ActionFilter中的模型? (我假设用该属性修饰的每个模型都将从具有userId和SignalRId属性的基类下降。)

如果我无法将值添加到模型中,我将不得不考虑自定义模型绑定器。我不想更改默认的模型绑定,只需将我的两个属性添加到已发生的内容中。我如何在Web API 2中处理此问题?

1 个答案:

答案 0 :(得分:0)

以下工作正常。

public class AddUserIdActionFilter : ActionFilterAttribute
{
    public override void OnActionExecuting(HttpActionContext actionContext)
    {
        IEnumerable<string> headers;
        string connectionId;
        Guid userId;

        if(actionContext.Request.Headers.TryGetValues("SignalR_Id", out headers))
        {
            connectionId = headers.First();
        }
        else
        {
            throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.BadRequest));
        }

        if (HttpContext.Current.User.Identity != null)
        {
            userId = Guid.Parse(HttpContext.Current.User.Identity.GetUserId());
        }
        else
        {
            throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.Unauthorized));
        }

        try
        {
            var model = (BaseCommand)actionContext.ActionArguments.Values.First();
            model.UserId = userId;
            model.ConnectionId = connectionId;
        }
        catch 
        {
            throw new HttpResponseException(new HttpResponseMessage(HttpStatusCode.InternalServerError));
        }
    }

}