从 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 请求)?
到目前为止我尝试过的东西:
new StreamReader(myHttpWebRequest.GetRequestStream()).ReadToEnd()
- 在运行时失败 ArgumentException: Stream was not readable.
- HttpWebRequest class 似乎没有任何 属性 允许 getting/reading HTTP 消息正文,例如
Body
、Message
、 Text
,等等
我会编写一个 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());
}
}
}
我的代码库中有一个(遗留)方法,它生成并 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 请求)?
到目前为止我尝试过的东西:
new StreamReader(myHttpWebRequest.GetRequestStream()).ReadToEnd()
- 在运行时失败ArgumentException: Stream was not readable.
- HttpWebRequest class 似乎没有任何 属性 允许 getting/reading HTTP 消息正文,例如
Body
、Message
、Text
,等等
我会编写一个 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());
}
}
}