我正在调用一个 API,该 API 需要请求标头中请求正文的 MD5 哈希值。
我正在使用 RestSharp 发送请求。通常我可以在调用 Execute 之前检查 Request.Parameters 中的 Body 参数并哈希该参数的值。
尽管在调用 AddFile 后,body 参数为空,并且在发送请求之前准备好内容之前,该 body 参数似乎一直为空。 (因为文件是分开存储的)
是否有办法在生成多部分字符串之后但在发送请求之前读取 RestRequest 的正文内容,以便我可以将 MD5 哈希添加到请求的标头中?
我意识到这是一个老问题,但我认为图书馆可以通过允许您在发送请求之前访问
Http
对象来为您处理这个问题。
var client = new RestSharp.RestClient();
var request = new RestRequest();
request.OnBeforeRequest = (http) => {
http.Headers.Add(new HttpHeader {
Name = "CONTENT_MD5",
Value = GenerateMd5Hash(x.RequestBody)
});
}
根据我所做的其他研究,目前似乎没有办法使用默认 API 来实现我想要的功能。
我最终下载了源代码,并向 Http 类添加了一个事件处理程序,该事件处理程序现在在发送 HttpWebRequest 之前触发。我在事件处理程序的参数中发送 HttpWebRequest,然后将其一直冒泡到 RestClient。
然后,我可以在顶级代码中拦截请求,并在发送请求之前根据需要添加到标头中。
这可能不是最有效的修改,但对于单元测试来说它已经足够好了。
不幸的是,如果您向 RestSharp 传递一个对象,它不会自然地公开序列化的请求主体。例如:
restRequest.AddXmlBody(myObject);
但基本上可以通过重新创建 RestSharp 使用的相同序列化器然后自行序列化来获取原始请求。举个例子,假设您正在使用
restClient.UseDotNetXmlSerializer()
,您可以:
var dotNetXmlSerializer = new DotNetXmlSerializer();
var requestSerializer = new XmlRestSerializer().WithXmlSerializer(dotNetXmlSerializer);
这只是 RestSharp 源代码中
UseDotNetXmlSerializer()
的精简版本。然后你只需调用它即可获取原始请求正文:
var xmlRequestBody = requestSerializer.Serialize(myObject);
此代码可以放置在可以访问
myObject
的任何位置,并且独立于您的 restClient
。基本上,您正在做的是利用 RestSharp 命名空间来进行独立的序列化。
现在到了 2024 年,这对我有用,通过单元测试证明:
[Fact]
public async Task ()
{
// Arrange
var restClient = new RestClient();
var request = new RestRequest("http://my-nice.url/my-nice-resoure", Method.Post);
var bodyContents = string.Empty;
request.OnBeforeRequest = async (http) =>
{
bodyContents = await http.Content.ReadAsStringAsync();
};
var body = new MyBodyWithEnumValueClass()
{
Gender = Gender.Female,
Name = "Baby Peach"
};
request.AddBody(body);
// Act
var response = await restClient.ExecuteAsync(request, CancellationToken.None);
// Assert
bodyContents.Should().Be("{\"Name\":\"Baby Peach\",\"Gender\":\"Female\"}");
}