Reputation: 5954
I would like to write all Request and Response Headers to the console.
Inside a console application (created via dotnet new console --framework net5.0
) i have basically this code
using System;
using System.Collections.Specialized;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
....
var client = new HttpClient();
var request = new HttpRequestMessage();
request.Method = HttpMethod.Get;
// add uri and header and so on ...
HttpResponseMessage response = await client.SendAsync(request);
PrintHeaders(response);
My first PrintHeaders()
looks like this
public static void PrintHeaders(HttpResponseMessage response)
{
// cast from HttpRequestHeaders
// and from HttpResponseHeaders
PrintHeaders((HttpHeaders)response.RequestMessage.Headers);
PrintHeaders((HttpHeaders)response.Headers);
}
And the other PrintHeaders()
like this
public static void PrintHeaders(HttpHeaders headers)
{
Console.WriteLine( " Printing Headers " );
Console.WriteLine( " KEY VALUE" );
var headersEnumerator = headers.GetEnumerator();
while (headersEnumerator.MoveNext())
{
Console.WriteLine( " {0,-25} {1}"
, headersEnumerator.Current.Key
, String.Join(" ",headersEnumerator.Current.Value.GetEnumerator()) );
}
Console.WriteLine();
}
The code works in so far that it receives a response from the server. And writes headers to the console.
Printing Headers
KEY VALUE
Authorization System.String[]
Printing Headers
KEY VALUE
Date System.String[]
Date System.SZGenericArrayEnumerator`1[System.String]
Connection System.String[]
As you can see above System.String[]
or System.SZGenericArrayEnumerator 1[System.String]
is written instead of the acutal value.
// System.String[] for
headersEnumerator.Current.Value.ToString()
// System.SZGenericArrayEnumerator`1[System.String] for
String.Join(" ",headersEnumerator.Current.Value.GetEnumerator())
Not working is to get the header.value as plain string for example for the header-field date
something like Wed, 07 Sep 2022 10:45:04 GMT
Instead i only get System.String[]
or something similar.
What can i do to output all header-keys and its values as plain text to the console?
Upvotes: -1
Views: 2415
Reputation: 5954
The rfc2616 section Response mentions
HTTP/1.1 200 OK
)Cache-Control
, Connection
, Date
, ...),Accept-Ranges
, Age
, Location
, ...) and alsoContent-Type
)After receiving and interpreting a request message, a server responds with an HTTP response message.
Response = Status-Line ; Section 6.1 *(( general-header ; Section 4.5 | response-header ; Section 6.2 | entity-header ) CRLF) ; Section 7.1 CRLF [ message-body ] ; Section 7.2
This makes it clear that the first lines of a response are not all of the same kind.
It seems to me that the pairing of classes in System.Net.Http
is not a perfect match to rfc2616. So afaik there is no easy way to write code like this
printStatusLine(); // print headers rfc2616 section 6.1
printGeneralHeader() // print section 4.5
printResponseHeader() // print section 6.2
printEntityHeader() // print section 7.1
To my knowledge .net only differentiates between
httpResponseMessage.Headers
httpResponseMessage.Content.Headers
andSo far i got this
public static string GetStatusLine(HttpResponseMessage message)
{
// HTTP-Version SP Status-Code SP Reason-Phrase CRLF
// string statusLine = ${"{0} {1} {2}", respMsg.Version)
string version = message.Version.ToString();
string code = ((int)message.StatusCode).ToString();
string phrase = message.ReasonPhrase;
string statusLine = $"{version} {code} {phrase} {Environment.NewLine}";
return statusLine;
}
The code above returns this 1.1 200 OK
. I assume that this is according to the status-line specs (HTTP-Version SP Status-Code SP Reason-Phrase CRLF
). Nonetheless vscode-restcode returns a status-line that looks like this
HTTP/1.1 200 OK
Since "dotnet-headers" and "rfc2616-headers" do not seem to match the easiest way is to use these members. But be aware that these methods likely do not return the same fields as you would expect according to rfc2616
public static string GetOtherHeaders(HttpResponseMessage message)
{
string headerLines = "";
foreach (var header in message.Headers)
{
foreach (var value in header.Value)
{
headerLines += ($"{header.Key} : {value} {Environment.NewLine}");
}
}
return headerLines;
}
and
public static string GetContentHeaders(HttpResponseMessage message)
{
string contentHeaderLines = "";
foreach (var header in message.Content.Headers)
{
foreach (var value in header.Value)
{
contentHeaderLines += $"{header.Key} : {value} {Environment.NewLine}";
}
}
return contentHeaderLines;
}
The page predic8.de (German) offers a basic demo-api https://api.predic8.de/shop/products/
. The method GetContentHeaders()
contain these fields
Content-Type : application/json; charset=utf-8
Content-Length : 1178
Hope that helps
Upvotes: 2
Reputation: 384
As a header key value is an enumerable of string, you could do something like this:
foreach (var header in response.Headers){
foreach (var value in header.Value)
{
Console.WriteLine($"{header.Key} : {value}");
}
}
Upvotes: 2
Reputation: 206
Quick fix is to change:
Console.WriteLine( " {0,-25} {1}"
, headersEnumerator.Current.Key
, String.Join(" ",headersEnumerator.Current.Value.GetEnumerator()) );
To
Console.WriteLine( " {0,-25} {1}"
, headersEnumerator.Current.Key
, String.Join(" ",headersEnumerator.Current.Value) ); //removing GetEnumerator()
Upvotes: 1