Web API action filter content can't be read

血红的双手。 提交于 2020-02-19 03:58:25

问题


Related question: Web API action parameter is intermittently null and http://social.msdn.microsoft.com/Forums/vstudio/en-US/25753b53-95b3-4252-b034-7e086341ad20/web-api-action-parameter-is-intermittently-null

Hi!

I'm creating a ActionFilterAttribute in ASP.Net MVC WebAPI 4 so I can apply the attribute in action methods at the controller that we need validation of a token before execute it as the following code:

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
    }
}

I'm trying to read the content as string. Tried the 3 ways as stated in this code, and all of them return empty. I know that in WebApi I can read only once the body content of the request, so I'm commenting everything else in the code, and trying to get it run to see if I'm getting a result. The point is, the client and even the Fiddler, reports the 315 of the content length of the request. The same size is getting on the server content header as well but, when we try read the content, it is empty.

If I remove the attribute and make the same request, the controller is called well, and the deserialization of Json happens flawless. If I put the attribute, all I get is a empty string from the content. It happens ALWAYS. Not intermittent as the related questions state.

What am I doing wrong? Keep in mind that I'm using ActionFilter instead of DelegatingHandler because only selected actions requires the token validation prior to execution.

Thanks for help! I really appreciate it.

Regards...

Gutemberg


回答1:


By default the buffer policy for Web Host(IIS) scenarios is that the incoming request's stream is always buffered. You can take a look at System.Web.Http.WebHost.WebHostBufferPolicySelector. Now as you have figured, Web Api's formatters will consume the stream and will not try to rewind it back. This is on purpose because one could change the buffer policy to make the incoming request's stream to be non-buffered in which case the rewinding would fail.

So in your case, since you know that the request is going to be always buffered, you could get hold of the incoming stream like below and rewind it.

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();


来源:https://stackoverflow.com/questions/18340487/web-api-action-filter-content-cant-be-read

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!