在 asp 核心网络 api 中混合文件上传和原始 json 是不可能的吗?

Is it impossible to mix fileupload and raw json in asp core web api?

几周来我一直在努力让我的 API 接受文件上传,以及 json 中的其他原始数据。 API 非常大,专为能够创建 claim/request 的用户而构建。一方面是他们应该能够在需要时上传文件。我用邮递员来测试API。但是,正如我发现的那样,不可能混合使用发送原始 json 请求和表单数据来上传文件的方法。我试过模型绑定等来尝试解决这个问题,但我没有取得任何成功。我唯一的成功是当我在控制器中创建一个单独的文件上传方法时。但这并不是最佳选择,因为用户应该在上传其他文件的同一请求中上传文件 information/data。

如果有人知道如何解决这个问题,我将不胜感激。

我的控制器如下所示:

 [HttpPost]
 public async Task < IActionResult > AddRequest(Request model) {

   if (!ModelState.IsValid) {
     return BadRequest(ModelState);
   }

   try {
     await _request.AddRequest(model);
   } catch (Exception ex) {

     return BadRequest(ex.Message);
   }

   return Ok();
 }

控制器只处理 HttpPost 和请求。实际方法等在视图模型中 class 如下:

     public async Task < bool > AddRequest(Request model) {
    
         bool CreateRequest = true;
         int requestID = 0;
         int claimID = 0;
    
         //First Create the Request
         foreach(Service item in model.Service) {
             //First Create the Request
             if (CreateRequest) {
    
               var parameters = new DynamicParameters();
    
               parameters.Add("WorkshopEmail", model.WorkshopEmail);
               parameters.Add("WorkshopContactperson", model.WorkshopContactperson);
               parameters.Add("WorkshopCellphone", model.WorkshopCellphone);
               parameters.Add("IncVat", model.IncVat); /
               parameters.Add("ExlVat", model.ExlVat);
    
               try {
                           var requestIDenum = await _sqlconnection.QueryAsync<int> 
                           ($ @ "INSERT INTO [dbo].[Request]

                           ([WorkshopEmail], [WorkshopContactperson], [WorkshopCellphone], [IncVat],
                           [ExlVat]) VALUES(@WorkshopEmail, @WorkshopContactperson, @WorkshopCellphone, 
                           @IncVat, @ExlVat); SELECT SCOPE_IDENTITY();
                           ",parameters);
                           requestID = requestIDenum.First(); CreateRequest = false;
    
                 }
                 catch (Exception ex) {
    
                   int hej = 0;
                 }
               }

AddRequest 方法持续了很长一段时间,有不同的选项。这个想法是文件上传可能类似于:

  if (item.fileuploadresults != null)
  {
  // add files to database here
  }

在邮递员中发送请求时,json 看起来像:

{
   "workshopEmail":"workshopemail",
   "workshopContactperson":"workshopcontactperson",
   "workshopCellphone":"workshopcellphone",
   "incVat":"7",
   "exlVat":"3",
   "Service":[
      // add service data
   ]

这是api的一部分,因为整体会有很多代码。但是例如在“服务”中可以添加更多信息。

现在,是不是不能在api中添加文件上传,并在邮递员中测试将文件存储在数据库中?或者有没有一种方法可以在不在控制器中创建单独的方法的情况下继续对请求进行 bilding api?

我遇到了类似的问题,我做了一些修改,我不知道它是否适合你,但你可以在这里做些什么。

您的控制器方法需要处理 multipart/form-data 请求,然后在此表单数据请求中您需要指定一个 data 字段,它将包含您的原始 JSON。之后将一些具有唯一键的文件放入您的表单数据请求中,并将此键放入图像字段的 JSON 中。最终你会得到这样的请求

然后你可以创建一些中间件,你需要修改你的请求数据,将文件数据放入 JSON 并将其映射到某个请求 class

如果您想 post 在一个请求中包含其他附加数据的文件,您可以尝试:

方法 1: 在您的 Request 模型 class 中定义一个字符串类型 属性,然后包含并传递 base64 编码的文件在您发出 http 请求时在您的 json 数据中。

方法二:在模型class中定义一个IFormFile类型属性,然后通过FormData传递数据而不是在 json 数据中传递它。

public class Request
{
    public string workshopEmail { get; set; }
    public string workshopContactperson { get; set; }

    //...
    //other properties
    //...

    public IFormFile fileupload { get; set; }
}

[FromForm] 属性应用于操作参数

public async Task<IActionResult> AddRequest([FromForm]Request model)
{
    //...

要在 ASP.NET Core 中上传文件,请查看此文档:https://docs.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads?view=aspnetcore-5.0

如果有人仍然想知道这个问题,我听从了@IhorKostrov 的建议并创建了一个 multipart/form-data 请求。可以找到解决方案:.