6

直观地查看将在 WebAPI 的 HttpResponseMessage / HttpRequestMessage 类型中实际发送或接收的 Http 标头的原始列表可能非常有益。我的意思只是一个普通的旧字符串,每个标题都在一个新行上,正是生成或接收的内容。

但不幸的是,看起来这些类型中的任何一种都不允许您查看实际生成的内容。取而代之的是,到处都是属性。一些在原始 HttpResponseMessage / HttpRequestMessage 类型本身中,一些在 response/request.Content.Headers 中(两者不重复,后者用于尚未作为属性涵盖的那些,通常用于自定义标头),......也许还有 Cookie某处获得了自己的标题。并且在视觉上看到这些 Header 集合列表也是一种痛苦,即你最终会为每个这样的集合提供一堆迭代代码......更混乱。

但是在实际发送/接收的响应/请求中,并没有这样的划分,简单的看到所有的Http headers。所以我在某个地方想念它吗?在这些地方实际上是否有一个简单直观的属性可以简单地返回原始标题字符串?当然,响应已经收到了标头并刚刚解析了它们……那个原始字符串隐藏在某个地方吗?

(顺便说一句,我知道 Fiddler ......这完全不能令人满意。如果我必须处理 Http 标头的低级混乱,那么能够使用我正在使用的编程类型查看它们是很有意义的生成并接收它们。但更糟糕的是,我仍然无法让 localhost 与 Fiddler 一起工作(在 Win8 上),这使得它在许多调试场景中的使用无效,在这些场景中我只想看到将生成的臭头。 )

4

3 回答 3

3

我没有找到获取请求标头原始值的方法,但是此代码似乎返回了所有标头值(不是按原始顺序):

request.Headers.ToString() + request.Content.Headers.ToString()
于 2016-09-21T13:22:27.957 回答
0

似乎 HttpRequestMessage.ToString 确实返回了原始值(好吧,从技术上讲,它们不是原始值,但非常接近一个,因为它一直在使用解析器分隔符将它们连接回来)。不幸的是,用于构造 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));
}
于 2017-06-28T14:12:51.663 回答
-1

这是我用来捕获请求和响应标头的代码:

*这是从 Windows 窗体应用程序中获取的:txtReceived 和 txtSent 是 WindowsForms 窗体上的简单多行文本框。光标是窗体的光标。*

    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);
    }
于 2013-02-24T12:39:59.567 回答