在ActionFilterAttribute中读取表单数据

时间:2012-05-20 13:04:45

标签: c# asp.net-mvc asp.net-mvc-3 c#-4.0 asp.net-web-api

我为我的web api创建了一个ActionFilterAttribute,以便授权人员。通过RequestUri获取accessToken是可以的,但我想在表单数据中发送它。在ActionFilterAttribute的onActionExecuting方法中读取Request.Content时,服务器始终具有空结果。我怎么解决这个问题?代码如下所示:

    public class RequireAuthorization : ActionFilterAttribute
{

    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        actionContext.Request.Content.ReadAsStringAsync().ContinueWith((t) =>
        {
            try
            {
                //query will result in empty string
                string query = t.Result;

                string UserID = HttpUtility.ParseQueryString(query).Get("UserID");
                string accessToken = HttpUtility.ParseQueryString(query).Get("AccessToken");

                UserRepository repository = new UserRepository();
                repository.IsTokenValid(Convert.ToInt32(UserID), accessToken);
            }
            catch (Exception ex)
            {
                var response = new HttpResponseMessage
                {
                    Content =
                        new StringContent("This token is not valid, please refresh token or obtain valid token!"),
                    StatusCode = HttpStatusCode.Unauthorized
                };

                throw new HttpResponseException(response);
            }
        });


        base.OnActionExecuting(actionContext);
    }
}

1 个答案:

答案 0 :(得分:5)

这是因为在ActionFilter之前,格式化程序已经读取了HttpContent。 Web API仅允许读取一次内容。所以你无法再读它。

这是一个可能的解决方案。首先,将您的action参数设置为FormDataCollection:

    [RequireAuthorization]
    public HttpResponseMessage PostTodo(FormDataCollection formData)
    {
        Todo todo = formData.ReadAs<Todo>();
        // ...

然后,通过代码在ActionFilter中获取它:

    public override void OnActionExecuting(System.Web.Http.Controllers.HttpActionContext actionContext)
    {
        var formData = actionContext.ActionArguments["formData"] as FormDataCollection;
        if (formData != null)
        {
            var userID = formData.Get("UserID");
            var accessToken = formData.Get("AccessToken");
            // authorize
        }

        base.OnActionExecuting(actionContext);
    }