如何接收发布到ASP.net核心2.1 Web-API端点的文件和数据

问题描述 投票:2回答:2

我正在尝试将文件和一些数据(对象列表)上传到ASP.net核心2.1 web-api端点。

下面的代码正确生成并发送预期的有效负载:

const formData = new FormData()
formData.append('file', this.file)
formData.append('data', JSON.stringify(this.mappings))

axios.post('upload', formData)
// {headers: {'content-type': 'multipart/form-data'}} optional ???

有效负载如下所示:(如chrome dev-tools,network tab中所示)

------WebKitFormBoundarydAP5tYG5GcFa4ivU
Content-Disposition: form-data; name="file"; filename="Master-List.xls"
Content-Type: application/vnd.ms-excel


------WebKitFormBoundarydAP5tYG5GcFa4ivU
Content-Disposition: form-data; name="data"

[{"required":true,"type":"field","value":"code","col":1,"text":"Item Code"},{"required":true,"type":"field","value":"name","col":2,"text":"Description"},{"required":true,"type":"field","value":"barcode","col":3,"text":"Barcode"},{"type":"field","value":"category","col":null,"text":"Category"},{"type":"field","value":"unit","col":null,"text":"Unit"},{"type":"location","value":1,"col":6,"text":"Store 1"}]
------WebKitFormBoundarydAP5tYG5GcFa4ivU--

Web-api端点如下所示:

[HttpPost]
[Route("upload")]
//[Consumes("multipart/form-data")]
public Task<ActionResult> _upload([FromForm] Upload obj)
{
    // do something
    return Ok();
}

public class Upload
{
    public Field[] data { get; set; }
    public IFormFile file { get; set; }
}

public class Field
{
    public int col { get; set; }
    public string type { get; set; }
    public string value { get; set; }
}

我能够收到file,但data总是空的。

请问我错过了什么?

c# file-upload asp.net-core asp.net-core-2.1
2个回答
1
投票

虽然似乎没有用于将JSON数据发送到ASP.NET Core MVC端点的开箱即用解决方案,但可以将数据格式化为一组键值对,这些键值对将被解析为Fields[]正如所料。看起来有点像这样(name = value):

data[<index>][<key>] = value

这是使用显式属性键构建FormData的代码示例:

for (let i = 0; i < this.mappings.length; i++) {
    formData.append(`data[${i}][col]`, this.mappings[i].col);
    formData.append(`data[${i}][type]`, this.mappings[i].type);
    formData.append(`data[${i}][value]`, this.mappings[i].value);
}

这构建了一些看起来像这样的东西:

data[0][col] = value
data[0][type] = value
data[0][value] = value

这是一个扩展代码示例,它迭代属性,而不是使用显式键:

for (let i = 0; i < this.mappings.length; i++) {
    for (let k in this.mappings[i]) {
        formData.append(`data[${i}][${k}]`, this.mappings[i][k]);
    }
}

最后一个示例假设您需要每个映射的所有可迭代属性 - 在JavaScript中有许多不同的方法可以执行此操作,我在此不会列举。如果您的映射是一个简单的对象,我提供的代码应该足够了。

总的来说,这在代码和发送到ASP.NET Core MVC端点的部件数量上都更加冗长。好处是端点可以只接收强类型模型,而无需执行任何额外的JSON解析等。


0
投票

不理想,但这种修改有效

  public class Upload
  {
    public string data { get; set; }
    public IFormFile file { get; set; }
  }

[HttpPost]
[Route("upload")]
[Consumes("multipart/form-data")]
public async Task<ActionResult> _upload([FromForm] Upload o)
{
  List<Field> x = JsonConvert.DeserializeObject<List<Field>>(o.data);

  return Ok();
}
© www.soinside.com 2019 - 2024. All rights reserved.