在 Framework 和 Standard 上发送带有文件和 JSON (Restsharp) 的 Rest 请求
Sending Rest request with file(s) and JSON (Restsharp) on Framework and Standard
我目前有一个正在构建的包装器,它使用函数 (SendEmail) 将 JSON 有效负载和一些文件发送到 Http 端点上的 Azure 函数。但是,当我使用 Restsharp 106.2.2 发送我的请求时,似乎没有提供任何边界信息。当我的 Azure 函数收到调用并尝试设置 MultipartMemoryStreamProvider 时,它无法设置,因为它看不到任何边界。
控制台测试应用程序
private static void Main(string[] args)
{
var emailService = new EmailService();
var email = new MicroserviceMailMessage("from@test.com", "to@test.com",
"Test Subject from Framework App", "Test Body from Framework App", true, DateTime.Now);
email.Attachments.Add(new Attachment(@"c:\Temp\soccor5.jpg"));
emailService.SendEmail(email);
}
包装库
public void SendEmail(MicroserviceMailMessage email)
{
var client = new RestClient("http://localhost:7071/api");
var request = new RestRequest("SendEmail", Method.POST);
var transformedEmail = TransformEmail(email);
request.AlwaysMultipartFormData = true;
request.AddHeader("Content-Type", $"multipart/form-data");
foreach (var attachment in email.Attachments)
{
var inline = attachment.ContentDisposition.Inline ? "inline." : "";
request.Files.Add(new FileParameter
{
Name = $"attachments.{inline}{attachment.Name}",
Writer = (s) =>
{
attachment.ContentStream.CopyTo(s);
attachment.ContentStream.Dispose();
},
ContentType = attachment.ContentType.ToString(),
ContentLength = attachment.ContentStream.Length,
FileName = attachment.Name
});
}
request.AddParameter("email", $"{JsonConvert.SerializeObject(transformedEmail)}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
}
Azure 接收函数
[FunctionName("EmailReceiver")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req, ...)
{
...
var provider = new MultipartMemoryStreamProvider();
await req.Content.ReadAsMultipartAsync(provider) // Fails on this line
...
}
样本数据比较
使用 RestSharp 106.2.2
使用 RestSharp 105.2.3(与 Postman 的结果相似)
错误
Invalid 'HttpContent' instance provided. It does not have a
'multipart' content-type header with a 'boundary'
parameter.\r\nParameter name: content
目前我尝试过的:
将 Restsharp 恢复到 105.2.3 会恢复 Rest 请求中的边界信息,这对 .Net Framework 非常有用,但我需要包装器在 Framework 和 .Net Standard 之间交叉兼容,所以这不会完全解决我的问题。
想法?我一直在思考是否有某种方法可以让我在 Restsharp 106.2.2 中手动输入边界,但我找不到关于它的大量文档。
这不是直接的答案,而只是我想出的解决问题的解决方案。
我切换到 Flurl.Http,最新版本与标准和框架兼容。这就是我重写 SendEmail 函数的方式,
public void SendEmail(MicroserviceMailMessage email)
{
var url = _azureEndpoint;
var transformedEmail = TransformEmail(email);
var content = new CapturedMultipartContent();
content.AddJson("email", transformedEmail);
foreach (var attachment in email.Attachments)
{
var inline = attachment.ContentDisposition.Inline ? "inline." : "";
content.AddFile($"attachments.{inline}{attachment.Name}", attachment.ContentStream, attachment.Name);
}
url.PostAsync(content).Wait();
}
它成功发布了我需要的所有内容、文件和 JSON。
我目前有一个正在构建的包装器,它使用函数 (SendEmail) 将 JSON 有效负载和一些文件发送到 Http 端点上的 Azure 函数。但是,当我使用 Restsharp 106.2.2 发送我的请求时,似乎没有提供任何边界信息。当我的 Azure 函数收到调用并尝试设置 MultipartMemoryStreamProvider 时,它无法设置,因为它看不到任何边界。
控制台测试应用程序
private static void Main(string[] args)
{
var emailService = new EmailService();
var email = new MicroserviceMailMessage("from@test.com", "to@test.com",
"Test Subject from Framework App", "Test Body from Framework App", true, DateTime.Now);
email.Attachments.Add(new Attachment(@"c:\Temp\soccor5.jpg"));
emailService.SendEmail(email);
}
包装库
public void SendEmail(MicroserviceMailMessage email)
{
var client = new RestClient("http://localhost:7071/api");
var request = new RestRequest("SendEmail", Method.POST);
var transformedEmail = TransformEmail(email);
request.AlwaysMultipartFormData = true;
request.AddHeader("Content-Type", $"multipart/form-data");
foreach (var attachment in email.Attachments)
{
var inline = attachment.ContentDisposition.Inline ? "inline." : "";
request.Files.Add(new FileParameter
{
Name = $"attachments.{inline}{attachment.Name}",
Writer = (s) =>
{
attachment.ContentStream.CopyTo(s);
attachment.ContentStream.Dispose();
},
ContentType = attachment.ContentType.ToString(),
ContentLength = attachment.ContentStream.Length,
FileName = attachment.Name
});
}
request.AddParameter("email", $"{JsonConvert.SerializeObject(transformedEmail)}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
}
Azure 接收函数
[FunctionName("EmailReceiver")]
public static async Task<HttpResponseMessage> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)]HttpRequestMessage req, ...)
{
...
var provider = new MultipartMemoryStreamProvider();
await req.Content.ReadAsMultipartAsync(provider) // Fails on this line
...
}
样本数据比较
使用 RestSharp 106.2.2
使用 RestSharp 105.2.3(与 Postman 的结果相似)
错误
Invalid 'HttpContent' instance provided. It does not have a 'multipart' content-type header with a 'boundary' parameter.\r\nParameter name: content
目前我尝试过的:
将 Restsharp 恢复到 105.2.3 会恢复 Rest 请求中的边界信息,这对 .Net Framework 非常有用,但我需要包装器在 Framework 和 .Net Standard 之间交叉兼容,所以这不会完全解决我的问题。
想法?我一直在思考是否有某种方法可以让我在 Restsharp 106.2.2 中手动输入边界,但我找不到关于它的大量文档。
这不是直接的答案,而只是我想出的解决问题的解决方案。
我切换到 Flurl.Http,最新版本与标准和框架兼容。这就是我重写 SendEmail 函数的方式,
public void SendEmail(MicroserviceMailMessage email)
{
var url = _azureEndpoint;
var transformedEmail = TransformEmail(email);
var content = new CapturedMultipartContent();
content.AddJson("email", transformedEmail);
foreach (var attachment in email.Attachments)
{
var inline = attachment.ContentDisposition.Inline ? "inline." : "";
content.AddFile($"attachments.{inline}{attachment.Name}", attachment.ContentStream, attachment.Name);
}
url.PostAsync(content).Wait();
}
它成功发布了我需要的所有内容、文件和 JSON。