16

I have created an endpoint that takes files as parameters:

    [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;
        }
    }

I cant retrieve the file with out a issue. How to add more text parameters to the same method ?

Debug View param parameter is null

Postmen call

Dinuka Wanasinghe
  • 755
  • 2
  • 7
  • 22

4 Answers4

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; }
}

Need to add [FromForm] before the parameter model after I add [FromForm] code works perfectly.

Rick Strahl
  • 17,302
  • 14
  • 89
  • 134
Dinuka Wanasinghe
  • 755
  • 2
  • 7
  • 22
  • 2
    Actually I need to send list of FileInputModel. To be clear every file has its own unique param. When I try to send "List model" action is stacks and I could not get any response. Do you have any idea? – MSK May 13 '20 at 09:28
16

It works 100%. Tested. Please do the below steps:

You should create a custom class for the model as

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

and the form like

<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>

and the controller method like

[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");
}
Prabhu Manoharan
  • 311
  • 2
  • 10
5

I tested with the following code and it works:

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; }
    }
}

Note that you need to use a model.

Here is the postman screen shot below with the same attributes.

Postman screenshot below

UPDATE for multiple files:

Change the model to:

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

Postman screenshot: Multipart form content

Update 2

The content type header is multipart/form-data

Here is a screenshot of it working:

Working Code

Anton Toshik
  • 2,621
  • 2
  • 19
  • 42
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,
    });
}
sully
  • 9
  • 1