从 HttpWebRequest 对象获取正文?

Get body text from an HttpWebRequest object?

我的代码库中有一个(遗留)方法,它生成并 returns 准备发送的 HTTP POST 消息作为 System.Net.HttpWebRequest 对象:

public HttpWebRequest GetHttpWebRequest(string body, string url, string contentType)
{
    HttpWebRequest request = HttpWebRequest.CreateHttp(url);
    request.Method = "POST";
    // (More setup stuff here...)

    using (var writer = new StreamWriter(request.GetRequestStream()))
    {
        writer.Write(body);
    }

    return request;
}

我想编写一个单元测试来验证此方法返回的 HttpWebRequest 实例确实具有在 body 参数中传递给该方法的消息正文文本.

问题:如何获取 HttpWebRequest 对象的正文(无需实际发送 HTTP 请求)?

到目前为止我尝试过的东西:

我会编写一个 http 侦听器并发出真正的 http 请求。

这是一个使用 WCF + 客户端代码的示例服务器。只需调用 await TestClient.Test();(您也可以使用 http://localhost:8088/TestServer/Dummy 之类的浏览器测试服务器)

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Web;
using System.Text;
using System.Threading.Tasks;

namespace SO
{
    [ServiceContract]
    public class TestServer
    {
        static WebServiceHost _host = null;
        public static Task Start()
        {
            var tcs = new TaskCompletionSource<object>();

            try
            {
                _host = new WebServiceHost(typeof(TestServer), new Uri("http://0.0.0.0:8088/TestServer"));
                _host.Opened += (s, e) => { tcs.TrySetResult(null); };
                _host.Open();

            }
            catch(Exception ex)
            {
                tcs.TrySetException(ex);
            }

            return tcs.Task;
        }

        //A method that accepts anything :)
        [OperationContract, WebInvoke(Method = "*", UriTemplate ="*")]
        public Message TestMethod(Stream stream )
        {
            var ctx = WebOperationContext.Current;

            var request  = ctx.IncomingRequest.UriTemplateMatch.RequestUri.ToString();

            var body = new StreamReader(stream).ReadToEnd();

            Console.WriteLine($"{ctx.IncomingRequest.Method} {request}{Environment.NewLine}{ctx.IncomingRequest.Headers.ToString()}BODY:{Environment.NewLine}{body}");

            return ctx.CreateTextResponse( JsonConvert.SerializeObject( new { status = "OK", data= "anything" }), "application/json", Encoding.UTF8);
        }
    }

    public class TestClient
    {
        public static async Task Test()
        {
            await TestServer.Start();

            var client = new HttpClient();
            var objToSend = new { name = "L", surname = "B" };
            var content = new StringContent( JsonConvert.SerializeObject(objToSend) );
            var response = await client.PostAsync("http://localhost:8088/TestServer/TestMethod?aaa=1&bbb=2", content);
            Console.WriteLine(response.StatusCode);
            Console.WriteLine(await response.Content.ReadAsStringAsync());

        }
    }
}