51

I'm making an HTTP call. My response contains a session code X-BB-SESSION in the header section of the HttpResponseMessage object. How do I get that specific header value?

I am using a foreach statement to iterate through all the headers (MSDN link). However the compiler keeps saying that it cannot be done:

foreach statement cannot operate on variables of type
  System.net.http.headers.cachecontrolheadervalue because
  'System.net.http.headers.cachecontrolheadervalue' doesn't contain
  a public definition for 'GetEnumerator'

This is the code I'm trying:

//Connection code to BaasBox

HttpResponseMessage response = await client.SendAsync(requestMessage, HttpCompletionOption.ResponseHeadersRead);
if (response.IsSuccessStatusCode)
{
    //get the headers
    HttpResponseHeaders responseHeadersCollection = response.Headers;
    foreach (var value in responseHeadersCollection.CacheControl)  --> HERE
    {
        string sTemp = String.Format("CacheControl {0}={1}", value.Name, value.Value);
    } else
{
    Console.WriteLine("X-BB-SESSION: NOT Found");
}

The header content from where I'm trying to get the value (X-BB-SESSION value) is something like:

Access-Control-Allow-Origin: *    
Access-Control-Allow-Headers: X-Requested-With    
X-BB-SESSION: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
gunr2171
  • 10,315
  • 25
  • 52
  • 75
MikePR
  • 2,104
  • 4
  • 22
  • 52

6 Answers6

92

You should be able to use the TryGetValues method.

HttpHeaders headers = response.Headers;
IEnumerable<string> values;
if (headers.TryGetValues("X-BB-SESSION", out values))
{
  string session = values.First();
}
Sam Harwell
  • 92,171
  • 18
  • 189
  • 263
16

Using Linq aswell, this is how I solved it.

string operationLocation = response.Headers.GetValues("Operation-Location").FirstOrDefault();

I think it's clean and not too long.

Max_Thom
  • 613
  • 6
  • 13
  • Note that this will throw an exception if the header is not found. If that's what you want, you may as well use First() instead of FirstOrDefault(). – Sergey Slepov Apr 25 '19 at 10:30
10

Though Sam's answer is correct. It can be somewhat simplified, and avoid the unneeded variable.

IEnumerable<string> values;
string session = string.Empty;
if (response.Headers.TryGetValues("X-BB-SESSION", out values))
{
    session = values.FirstOrDefault();
}

Or, using a single statement with a ternary operator (as commented by @SergeySlepov):

string session = response.Headers.TryGetValues("X-BB-SESSION", out var values) ? values.FirstOrDefault() : null;
pim
  • 10,145
  • 4
  • 59
  • 61
  • 2
    If you go that route, then you can remove 1 more variable: `response.Headers.TryGetValues("X-BB-SESSION", out var values)` – Guillaume Perrot Sep 19 '17 at 00:35
  • 1
    @GuillaumePerrot you are correct. But this was added in c# 7, so I used the "old" way for compatibility. – pim Feb 27 '18 at 12:12
  • 3
    To go all the way, use: `string session = response.Headers.TryGetValues("X-BB-SESSION", out var values) ? values.FirstOrDefault() : null;` – Sergey Slepov Apr 25 '19 at 10:21
3

You are trying to enumerate one header (CacheControl) instead of all the headers, which is strange. To see all the headers, use

foreach (var value in responseHeadersCollection)
{
    Debug.WriteLine("CacheControl {0}={1}", value.Name, value.Value);
}

to get one specific header, convert the Headers to a dictionary and then get then one you want

Debug.WriteLine(response.Headers.ToDictionary(l=>l.Key,k=>k.Value)["X-BB-SESSION"]);

This will throw an exception if the header is not in the dictionary so you better check it using ContainsKey first

Igor Kulman
  • 15,893
  • 10
  • 51
  • 114
  • Hi Igor. I tested your code as well and it works. I justbfigured out another alternative to get the same value. thanks! – MikePR Aug 23 '14 at 00:05
  • 1
    Perhaps something like Debug.WriteLine(response.Headers.FirstOrDefault(k=>k.Key == "X-BB-SESSION")?.Value.FirstOrDefault()); – Sean Aug 25 '16 at 11:33
  • "...convert the Headers to a Dictionary..." see https://dotnetcodr.com/2014/03/13/extension-methods-in-net-part-3-mixture-of-useful-methods/ – sscheider Mar 02 '17 at 16:46
3

If someone like method-based queries then you can try:

    var responseValue = response.Headers.FirstOrDefault(i=>i.Key=="X-BB-SESSION").Value.FirstOrDefault();
Izi
  • 31
  • 2
0

Below Code Block Gives A formatted view of Response Headers

WebRequest request = WebRequest.Create("https://-------.com"); WebResponse response = request.GetResponse();

        foreach (var headerItem in response.Headers)
        {

            IEnumerable<string> values;
            string HeaderItemValue="";
            values = response.Headers.GetValues(headerItem.ToString());

            foreach (var valueItem in values)
            {
                HeaderItemValue = HeaderItemValue + valueItem + ";";                    
            }

            Console.WriteLine(headerItem + " : " + HeaderItemValue);
        }
rajquest
  • 204
  • 2
  • 5