API POST调用以上传包含IFormFile的对象的列表

时间:2018-10-22 18:52:33

标签: c# asp.net asp.net-core

我正在使用ASP.NET Core 2.2中的IFormFile来建立文件上传Web服务调用。因为我需要与每个文件上传相关联的特定数据,所以我创建了一个自定义模型类来包含具有IFormFile属性的数据。

public class Document
{
    public string FileId { get; set; }
    public string FileTitle { get; set; }
    public string CategoryId { get; set; }

    public IFormFile Content { get; set; }
}

仅上传一个文档时,下面的方法可以正常工作。

[HttpPost]
[Route("UploadDoc")]
public async Task<IActionResult> DocumentUpload ([FromForm] Document document) { }

但是,我希望接受一次要上传的文档列表。当我将POST配置为接受列表时,它将不再起作用。我知道IList<IFormFile>可以正常工作,但是问题是我需要每个文件都有其他数据。

[HttpPost]
[Route("UploadDoc")]
public async Task<IActionResult> DocumentUpload ([FromForm] IList<Document> document) { }

我正在使用Postman测试我的API,并且提供了表单数据调用的屏幕截图。执行后,我的邮递员将挂起。奇怪的是,当我从Document类中删除IFormFile属性时,该调用将起作用。我可以做这项工作还是有解决方法?

Postman call

4 个答案:

答案 0 :(得分:1)

这是已知的bug

作为一种解决方法,您可以将IFormFile包装在另一个类中,它将起作用

    public class Company
    {
        public IList<Person> Employees { get; set; } = new List<Person>();
    }

    public class Person
    {
        public FormFileWrapper IdImage { get; set; }
    }

    public class FormFileWrapper
    {
        public IFormFile File { get; set; }
    }

然后您不必在html中添加索引

<form action="http://localhost:5000/api/Values" method="post" enctype="multipart/form-data">
    <p><input type="file" name="Employees[0].IdImage.File"></p>
    <p><input type="file" name="Employees[1].IdImage.File"></p>
    <p><button type="submit">Submit</button></p>
</form>

答案 1 :(得分:0)

要将列表对象从邮递员传递到api,可以尝试使用parameterName[index].fieldName之类的结构。

这是一个适合您的演示。

enter image description here

答案 2 :(得分:0)

为什么不能尝试IFormFile的具体实现。并使用该具体类型作为列表参数。

public class Document : IFormFile
{
    public string ContentType => throw new NotImplementedException();

    public string ContentDisposition => throw new NotImplementedException();

    public IHeaderDictionary Headers => throw new NotImplementedException();

    public long Length => throw new NotImplementedException();

    public string Name => throw new NotImplementedException();

    public string FileName => throw new NotImplementedException();

    public void CopyTo(Stream target)
    {
        throw new NotImplementedException();
    }

    public Task CopyToAsync(Stream target, CancellationToken cancellationToken = default(CancellationToken))
    {
        throw new NotImplementedException();
    }

    public Stream OpenReadStream()
    {
        throw new NotImplementedException();
    }
}

您还可以通过添加必需的属性来自定义类。 值得尝试。试试看,让我知道你过的怎么样。

答案 3 :(得分:0)

这实际上是a bug in ASP.NET Core 2.2,但是有一种解决方法。

将项目的索引添加到您的表单帖子中,如下所示:

HTML格式

<input type="hidden" name="document.Index" value="0" />
<input type="file" name="document.Content[0]" />

<input type="hidden" name="document.Index" value="1" />
<input type="file" name="document.Content[1]" />

API调用

key                    value
document.Index         0
document.Content[0]    (binary)
document.Index         1
document.Content[1]    (binary)

我创建了一个reproduction of the bug,并包含了the work-around