【问题标题】:Web API action filter content can't be read无法读取 Web API 操作过滤器内容
【发布时间】:2013-08-22 19:48:12
【问题描述】:

相关问题:Web API action parameter is intermittently nullhttp://social.msdn.microsoft.com/Forums/vstudio/en-US/25753b53-95b3-4252-b034-7e086341ad20/web-api-action-parameter-is-intermittently-null

嗨!

我在 ASP.Net MVC WebAPI 4 中创建了一个 ActionFilterAttribute,因此我可以在控制器的操作方法中应用该属性,我们需要在执行之前验证令牌,如下代码所示:

public class TokenValidationAttribute : ActionFilterAttribute
{
        public override void OnActionExecuting(HttpActionContext filterContext)
        {
        //Tried this way
        var result = string.Empty;
        filterContext.Request.Content.ReadAsStringAsync().ContinueWith((r)=> content = r.Result);

        //And this
        var result = filterContext.Request.Content.ReadAsStringAsync().Result;

        //And this
        var bytes = await request.Content.ReadAsByteArrayAsync().Result;
        var str = System.Text.Encoding.UTF8.GetString(bytes);

        //omit the other code that use this string below here for simplicity
    }
}

我正在尝试将内容读取为字符串。尝试了此代码中所述的 3 种方法,它们都返回空。我知道在 WebApi 中我只能读取一次请求的正文内容,所以我在代码中评论其他所有内容,并尝试让它运行以查看是否得到结果。关键是,客户端甚至Fiddler,都会报告请求内容长度的315。服务器内容头也有相同的大小,但是当我们尝试读取内容时,它是空的。

如果我删除该属性并发出相同的请求,控制器就会被很好地调用,并且 Json 的反序列化会完美无缺。如果我放置属性,我得到的只是内容中的一个空字符串。它总是发生。如相关问题所述,不是断断续续的。

我做错了什么?请记住,我使用的是 ActionFilter 而不是 DelegatingHandler,因为只有选定的操作需要在执行之前进行令牌验证。

感谢您的帮助!我真的很感激。

问候...

古腾堡

【问题讨论】:

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


    【解决方案1】:

    默认情况下,Web 主机 (IIS) 方案的缓冲策略是始终缓冲传入请求的流。你可以看看System.Web.Http.WebHost.WebHostBufferPolicySelector。现在正如您所想的那样,Web Api 的格式化程序将使用流并且不会尝试将其倒回。这是故意的,因为可以更改缓冲策略以使传入请求的流不缓冲,在这种情况下,倒带将失败。

    因此,在您的情况下,由于您知道请求将始终被缓冲,因此您可以像下面那样获取传入流并倒回它。

    Stream reqStream = await request.Content.ReadAsStreamAsync();
    
    if(reqStream.CanSeek)
    {
         reqStream.Position = 0;
    }
    
    //now try to read the content as string
    string data = await request.Content.ReadAsStringAsync();
    

    【讨论】:

    • 感谢您的回答。现在它就像你告诉基兰的那样有效。关键是,我仍然不完全确定为什么会发生这种情况......我在另一个项目中运行相同的代码,现在我遇到了这个问题......
    • 好吧,但现在我遇到了另一个问题。我不能让它异步。因为框架没有调用它异步并且执行流程在 OnActionExecuting() 完成之前调用控制器操作......
    • 我的错!我总是可以在 Async() 方法之后使用 .Result ,因此线程将一直保持到完成该方法的执行。现在一切都很好。再次感谢!
    • 谢谢!神圣的一天,我在那一天用了几个小时。
    • reqStream.CanSeek 对我来说是错误的......我猜运气不好?
    猜你喜欢
    • 2014-02-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多