从HttpWebRequest对象获取正文文本?

时间:2017-09-01 16:30:12

标签: c# .net system.net.httpwebrequest

我的代码库中有一个(遗留)方法,它生成并返回一个准备发送的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请求)?

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

  • new StreamReader(myHttpWebRequest.GetRequestStream()).ReadToEnd() - 在运行时因ArgumentException: Stream was not readable.
  • 而失败
  • HttpWebRequest类似乎没有任何允许获取/读取HTTP消息体的属性,例如BodyMessageText等。

1 个答案:

答案 0 :(得分:1)

我会写一个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());

        }
    }
}