HttpResponseMessage.Content.Headers.ToString() does not include Content-Length

Topics: ASP.NET Web API, General
Jul 24, 2012 at 10:24 PM
Edited Jul 24, 2012 at 10:26 PM

Hi,

This is something I noticed while doing unit tests on serialising/deserialising HttpResponseMessage which thanks to Henrik, is solved now. http://aspnetwebstack.codeplex.com/discussions/387945

However, I noticed that .ToString() does not include Content-Length:

 

var httpClient = new HttpClient();
var httpResponseMessage = httpClient.GetAsync("http://google.com").Result;
Console.WriteLine(httpResponseMessage.Content.Headers.ToString());
Console.WriteLine(httpResponseMessage.Content.Headers.ContentLength);

 

Which prints out:

 

Content-Type: text/html; charset=ISO-8859-1
Expires: -1

44711

So the header does have a value but simply is not included in the .ToString(). This value would have had been part of the original response from Google too.

While if I use my serialisation/deserialisation and rehydrate the HttpResponseMessage from my stream (according to http://aspnetwebstack.codeplex.com/discussions/387945) it will output the Content-Length.

 

This is causing problem since my unit test for comparing the result of the test fails, but I am wondering could cause other issues too. Would you please advise?

Thanks

Jul 25, 2012 at 1:13 PM

I think you're running into the situation that HttpContentHeaders.ContentLength is lazily evaluated and is not actually part of the headers until you ask for it.  I've run into the same situation and solved it by calling Content.Headers.ContentLength *before* working with the headers, as ToString() does.   In other words, as soon as you ask for the ContentLength property, it is computed and then written into the headers.  In the event the Content implementation cannot compute the length, no value is set into the headers.

This would explain why serialization works, because it is fetching the property and forces the lazy eval.   I'll snoop around to ask the authors why they chose that approach, because it causes issues like yours.  It appears to be the only HttpContentHeaders property with this lazy compute behavior.

Be aware it can also cause problems if you copy headers from one place to another without first having called ContentLength.  Any content header copying algorithm should first call ContentLength to ensure the source headers are really set.

Jul 25, 2012 at 1:23 PM

Thanks. As a work around for now, I will get the value first. The problem is with so many headers, it will be cumbersome to ensure I call all of them before serialize. Yet, there is a workaround and that is good.

Please let me know if you want me to open an issue.