添加文件后发送前如何获取RestRequest正文内容

问题描述 投票:0回答:4

我正在调用一个 API,该 API 需要请求标头中请求正文的 MD5 哈希值。

我正在使用 RestSharp 发送请求。通常我可以在调用 Execute 之前检查 Request.Parameters 中的 Body 参数并哈希该参数的值。

尽管在调用 AddFile 后,body 参数为空,并且在发送请求之前准备好内容之前,该 body 参数似乎一直为空。 (因为文件是分开存储的)

是否有办法在生成多部分字符串之后但在发送请求之前读取 RestRequest 的正文内容,以便我可以将 MD5 哈希添加到请求的标头中?

c# asp.net asp.net-web-api restsharp
4个回答
3
投票

我意识到这是一个老问题,但我认为图书馆可以通过允许您在发送请求之前访问

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)
    });
}

0
投票

根据我所做的其他研究,目前似乎没有办法使用默认 API 来实现我想要的功能。

我最终下载了源代码,并向 Http 类添加了一个事件处理程序,该事件处理程序现在在发送 HttpWebRequest 之前触发。我在事件处理程序的参数中发送 HttpWebRequest,然后将其一直冒泡到 RestClient。

然后,我可以在顶级代码中拦截请求,并在发送请求之前根据需要添加到标头中。

这可能不是最有效的修改,但对于单元测试来说它已经足够好了。


0
投票

不幸的是,如果您向 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 命名空间来进行独立的序列化。


0
投票

现在到了 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\"}");
 }
© www.soinside.com 2019 - 2024. All rights reserved.