在WebAPI的HttpResponseMessage / HttpRequestMessage类型中直观地查看将实际发送或接收的Http Headers的原始列表非常有用。我的意思是只是一个普通的旧字符串,每个标题都在一个新行上,正是生成或接收的字符串。
但不幸的是,看起来这些类型中的任何一种都不允许您只看到实际生成的内容。相反,到处都有物业。原始HttpResponseMessage / HttpRequestMessage中的一些类型本身,一些在response / request.Content.Headers中(两个不重复,后者是那些尚未作为属性覆盖的,通常用于自定义标题),...也许Cookie某处获得了自己的标题藏匿处。并且在视觉上看到那些Header集合列表也很痛苦,即你最终会为每个这样的集合添加一堆迭代代码...更多的混乱。
但是在发送/接收的实际响应/请求中,没有这样的划分,并且很容易看到所有Http头。 所以我在某个地方错过了吗?实际上是否有一个简单直观的属性,只是返回原始标题字符串?当然响应已经收到标题并只是解析它们...是隐藏在某处的原始字符串?
(顺便说一句,我知道Fiddler ......这完全不能令人满意。如果我不得不处理Http标题的低级别混乱,那么能够用程序化类型I来查看它们是很有意义的我用它来生成和接收它们。但更糟糕的是,我仍然无法让localhost与Fiddler一起工作(在Win8上),这使得它在许多调试场景中的使用无效,我想做的就是看到会发出臭的标题生成。)
答案 0 :(得分:1)
我没有找到获取请求标头的原始值的方法,但此代码似乎返回所有标头值(不按原始顺序):
request.Headers.ToString() + request.Content.Headers.ToString()
答案 1 :(得分:0)
似乎HttpRequestMessage.ToString确实返回了原始值(嗯,从技术上来说,它们不是原始的,但非常接近于1,因为它一直使用解析器分隔符来加入它们)。不幸的是,用于构造ToString结果的方法是私有的。因此,要解决相同的任务,我必须解析ToString的结果:
var values = new JObject();
foreach (var raw_header in request.Headers
.ToString()
.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries))
{
var index = raw_header.IndexOf(':');
if (index <= 0)
continue;
var key = raw_header.Substring(0, index);
var value = index + 1 >= raw_header.Length ? string.Empty : raw_header.Substring(index + 1).TrimStart(' ');
values.Add(new JProperty(key, value));
}
答案 2 :(得分:-1)
以下是我使用的代码,以便能够捕获请求和响应标头:
*这是从Windows窗体应用程序中获取的:txtReceived和txtSent是WindowsForms表单上的简单多行TextBox。并且光标是Form的光标。 *
private HttpClient PrepareHttpClient()
{
var client = new HttpClient();
client.DefaultRequestHeaders.Accept.Add(
new MediaTypeWithQualityHeaderValue("application/xml"));
return client;
}
private string SendGetRequest(string url)
{
//Please be patient ...
this.Cursor = Cursors.WaitCursor;
var client = PrepareHttpClient();
txtSent.Text = url;
var taskReult = client.GetAsync(new Uri(url));
HttpResponseMessage httpResponse = taskReult.Result;
Stream st = httpResponse.Content.ReadAsStreamAsync().Result;
StreamReader reader = new StreamReader(st);
string content = reader.ReadToEnd();
//Reset the cursor shape
this.Cursor = Cursors.Default;
txtReceived.Text = FormatResponse(httpResponse, content);
//For GET we expect a response of 200 OK
if (httpResponse.StatusCode == HttpStatusCode.OK)
{
return content;
}
throw new ApplicationException(content);
}
/// <summary>
/// Post to the server using JSON
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url">The server uri</param>
/// <param name="e">The object to POST</param>
/// <returns></returns>
private string SendPostRequest<T>(string url, T e)
{
this.Cursor = Cursors.WaitCursor;
HttpClient client = new HttpClient();
// Create the JSON formatter.
MediaTypeFormatter jsonFormatter = new JsonMediaTypeFormatter();
// Use the JSON formatter to create the content of the request body.
HttpContent content = new ObjectContent<T>(e, jsonFormatter);
Stream st = content.ReadAsStreamAsync().Result;
StreamReader reader = new StreamReader(st);
string s = reader.ReadToEnd();
// Send the request.
var taskResult = client.PostAsync(url, content);
//Note: We could simply perform the following line and save some time
//but then we will not have access to the post content:
//var taskResult = client.PostAsJsonAsync<T>(url, e);
HttpResponseMessage httpResponse = taskResult.Result;
this.Cursor = Cursors.Default;
txtSent.Text = FormatRequest(httpResponse.RequestMessage, s);
st = httpResponse.Content.ReadAsStreamAsync().Result;
reader = new StreamReader(st);
string responseContent = reader.ReadToEnd();
txtReceived.Text = FormatResponse(httpResponse, responseContent);
//For POST we expect a response of 201 Created
if (httpResponse.StatusCode == HttpStatusCode.Created)
{
return responseContent;
}
throw new ApplicationException(responseContent);
}
/// <summary>
/// PUT to the server using JSON
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="url"></param>
/// <param name="e"></param>
/// <returns></returns>
private string SendPutRequest<T>(string url, T e)
{
this.Cursor = Cursors.WaitCursor;
HttpClient client = new HttpClient();
// Create the JSON formatter.
MediaTypeFormatter jsonFormatter = new JsonMediaTypeFormatter();
// Use the JSON formatter to create the content of the request body.
HttpContent content = new ObjectContent<T>(e, jsonFormatter);
Stream st = content.ReadAsStreamAsync().Result;
StreamReader reader = new StreamReader(st);
string s = reader.ReadToEnd();
// Send the request.
var taskResult = client.PutAsync(url, content);
//Note: We could simply perform the following line and save some time
//but then we will not have access to the post content:
//var taskResult = client.PutAsJsonAsync<T>(url, e);
HttpResponseMessage httpResponse = taskResult.Result;
txtSent.Text = FormatRequest(httpResponse.RequestMessage, s);
st = httpResponse.Content.ReadAsStreamAsync().Result;
reader = new StreamReader(st);
string responseContent = reader.ReadToEnd();
this.Cursor = Cursors.Default;
txtReceived.Text = FormatResponse(httpResponse, responseContent);
//For PUT we expect a response of 200 OK
if (httpResponse.StatusCode == HttpStatusCode.OK)
{
return responseContent;
}
throw new ApplicationException(responseContent);
}
private string FormatRequest(HttpRequestMessage request, string content)
{
return
string.Format("{0} {1} HTTP/{2}\r\n{3}\r\n{4}",
request.Method,
request.RequestUri,
request.Version,
request.Headers,
content);
}
private string FormatResponse(HttpResponseMessage result, string content)
{
return
string.Format("HTTP/{0} {1} {2}\r\n{3}\r\n{4}",
result.Version,
(int)result.StatusCode,
result.ReasonPhrase,
result.Headers,
content);
}