我正在try 建立一个.Net 6.0 C#rest webservice,接收一个字符串和三个文件,其中一个是二进制图像.

curl 看起来是这样的:

curl -X POST -H "Content-Type: multipart/form-data; boundary=------------------------d74496d66958873e" \
--data-binary "@KeyValue.json" \
--data-binary "@Text.txt" \
--data-binary "@Image.tif" \
http://localhost:5000/check/CheckType01

我try 了一种从Visual Studio 2022项目"ASP.NET核心Web Api"开始的方法

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapPost("/check/{checkType}", (string checkType, HttpContext ctx) =>
{
    ctx.Request.EnableBuffering();
    ctx.Request.Body.Position = 0;
    var reader = new StreamReader(ctx.Request.Body);
    var body = Task.Run(async () => await reader.ReadToEndAsync().ConfigureAwait(false));

    Console.WriteLine("Parameter:  " + checkType);
    Console.WriteLine("MultiPart:  " + body.Result);

    return new { check = "Ok", confidence = 100 }; ;
});

app.Run();

对于包含"KeyValueContent"、"TextContent"和"ImageContent"的三个文件,此代码部分工作:

Output:
Parameter:  CheckType01
MultiPart:  KeyValueContent&TextContent&ImageContent
Return:
{"check":"Ok","confidence":100}

但我认为这不是解决这个问题的正确方法.

  • 文件之间用"&分隔"而不是通过标题的边界,因此无法将它们分开.
  • 框架应该以某种方式进行分离.
  • 多部分正文是字符串,而不是字节array.
  • webservice在正文读取期间被阻止.

我读了很多关于如何在ASP中上传文件的书.Net核心,关于webapi控制器、模型视图控制器、注释、是否使用最小API等,

我想知道:

  • 我应该使用哪种Visual Studio 2022启动项目类型?
  • 使用什么框架(最小api、带控制器的api、[ApiController]属性?
  • 后二进制多部分/表单数据的必要属性?

推荐答案

除了修复curl请求以读取多个文件外,还可以使用HttpRequest.Form.Files返回的IFormFileCollection(将HttpRequest作为处理程序参数注入,或使用ctx.Request访问它).

还要注意,Task.Run在这里不仅毫无意义,而且有害,只需将lambda处理程序标记为async:

app.MapPost("/check/{checkType}", async (string checkType, HttpRequest request) =>
{
    var formFileCollection = request.Form.Files;
    foreach (var formFile in request.Form.Files)
    {
        using var openReadStream = new StreamReader(formFile.OpenReadStream());
        var readToEndAsync = await openReadStream.ReadToEndAsync();
        // do something here
    }

    ...

    return new { check = "Ok", confidence = 100 };
});

Csharp相关问答推荐

如何使用C#中的图形API更新用户配置文件图像

应该使用哪一个?"_counter += 1 OR互锁增量(ref_counter)"""

更新产品但丢失产品ASP.NET Core的形象

Azure DEVOPS找不到定制的Nuget包

为什么EventInfo.EventHandlerType返回可为空的Type值?

C#-VS2022:全局使用和保存时的代码清理

异步实体框架核心查询引发InvalidOperation异常

持有者安全定义未显示在Swagger.NET 8中

我如何让我的秒表保持运行场景而不重置

在.NET 7.0 API控制器项目中通过继承和显式调用基类使用依赖项注入

WPF DataGrid文件名列,允许直接输入文本或通过对话框按键浏览

Celler ArgumentExpression是否期望在所有情况下都捕获允许空值的运算符?

使用Blazor WebAssembly提高初始页面加载时间的性能

在平行内使用跨度.用于循环

如何使用IHostedService添加数据种子方法

Xamarin.Forms中具有类似AspectFill的图像zoom 的水平滚动视图

如何阻止可传递依赖项出现在项目中

用于分钟和秒验证的MudTextfield的正则表达式掩码

使用Try-Catch-Finally为API端点处理代码--有什么缺点?

自定义ConsoleForMatter中的DI/Http上下文