ASP.NET Core Web API文件上传和“form-data”多参数传递到方法

16

我创建了一个接口,可以将文件作为参数传递:

    [HttpPost("[action]")]
    [Consumes("multipart/form-data")]
    public ActionResult UploadImage(IFormFile  Files, string param)
    {

        long size = Files.Length;            
        var tempPath = Path.GetTempFileName();
        string file_Extension = Path.GetExtension(Files.FileName);                   
        var isValidFile = FileValidation.FileUploadValidation(Files);
        if (isValidFile.data)
        {
            string filename = Guid.NewGuid() + "" + file_Extension;
            return null;

        }
        else
        {
            return null;
        }
    }

我无法正常获取文件。如何在同一方法中添加更多的文本参数?

Debug View param parameter is null

Postmen call


1
你能让我们看一下你是如何发布数据的吗? - Anton Toshik
我添加了一些截图以便更清楚地说明。 - Dinuka Wanasinghe
4个回答

23
[HttpPost("[action]")]
[Consumes("multipart/form-data")]
public IActionResult UploadImage([FromForm] FileInputModel Files)
{

    return Ok();
}

public class FileInputModel 
{
    public IFormFile File { get; set; }
    public string Param { get; set; }
}

在我添加了[FromForm]代码之后,在参数模型前面需要加上[FromForm],这样代码就能完美运行。


2
实际上,我需要发送FileInputModel列表。明确一点,每个文件都有自己独特的参数。当我尝试发送“List<FileInputModel> model”时,操作会堵塞,我无法得到任何响应。你有什么想法吗? - MSK

16

它可以百分百地工作。已经测试过了。请按以下步骤进行:

您应该为模型创建一个自定义类,如下所示:

public class FileInputModel
{
    public string Name { get; set; }
    public IFormFile FileToUpload { get; set; }
}

并且形式像

<form method="post" enctype="multipart/form-data" asp-controller="Home" asp-action="UploadFileViaModel" >
    <input name="Name" class="form-control" />
    <input name="FileToUpload" type="file" class="form-control" />
    <input type="submit" value="Create" class="btn btn-default" />
</form>

并且控制器方法如下

[HttpPost]
public async Task<IActionResult> UploadFileViaModel([FromForm] FileInputModel model)
{
    if (model == null || model.FileToUpload == null || model.FileToUpload.Length == 0)
        return Content("file not selected");

    var path = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", model.FileToUpload.FileName);

    using (var stream = new FileStream(path, FileMode.Create))
    {
        await model.FileToUpload.CopyToAsync(stream);
    }

    return RedirectToAction("Files");
}

5

我用以下代码进行了测试,它可以正常工作:

public class TestController : Controller
{
    [HttpPost("[controller]/[action]")]
    public IActionResult Upload(Model model)
    {
        return Ok();
    }

    public class Model
    {
        public IFormFile File { get; set; }
        public string Param { get; set; }
    }
}

请注意,您需要使用一个模型。
下面是具有相同属性的Postman截图。

Postman screenshot below

多个文件的更新:

将模型更改为:

public class Model
{
    public List<IFormFile> Files { get; set; }
    public string Param { get; set; }
}

Postman截图: 多部分表单内容

更新2

内容类型标头为multipart/form-data

这是它正常工作的截图:

Working Code


仍然无法工作,头部内容类型是什么? - Dinuka Wanasinghe
@DinukaWanasinghe 更新了,请确保您将 [Consumes] 属性从您的端口移除。 - Anton Toshik
这只有在我使用[Consumes][FromForm]提示时才有效。不知道为什么。 - GotDibbs
这将可以工作而不需要内容类型,请尝试从头部删除内容类型。 - Shelly

0

C# .NET Core

[HttpPost("someId/{someId}/someString/{someString}")]
[ProducesResponseType(typeof(List<SomeResponse>), StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
[ProducesResponseType(StatusCodes.Status403Forbidden)]
[ProducesResponseType(typeof(Dictionary<string, string[]>), StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Post(int someId, string someString, [FromForm] IList<IFormFile> files)
{
...
}

Typescript:

create(someId: number, someString: string, files: File[]) {
    var url = `${this.getBaseUrl()}/someId/${someId}/someString/${someString}`;

    const form = new FormData();
    for (let file of files) {
        form.append("files", file);
    }

    return this.http.post<SomeResponse>(url, form, {
        reportProgress: true,
    });
}

如果实现是 Angular,则设置标题 'Content-Type': 'application/json'。 - Dinuka Wanasinghe

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接