16

How to do Multipart-form-data file upload in asp.net core web api? Is it possible to POST both JSON and the image at the same time in a single POST?

1 Answer 1

18

Update- .net core 2.0 +

With .net core you can leverage the new IFormFile interface to upload both the image and properties in the same post. For example:

[HttpPost("content/upload-image")]
public async Task<IActionResult> UploadImage(MyFile upload)

The MyFile class can look like:

public class MyFile
{
    public string userId { get; set; }        
    public IFormFile File { get; set; }
    // Other properties
}

You can access the properties and the file as follows:

var file = upload.File // This is the IFormFile file
var param = upload.userId // param

To persist/save the file to disk you can do the following:

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

.NET Framework

Yes it is. Depending on the client Framework you're using, you can configure your Web API for Content Type-Multipart, then do something like:

[HttpPost]
[Route("content/upload-image")]       
public async Task<HttpResponseMessage> Post()
{
    if (!Request.Content.IsMimeMultipartContent())
    {
        throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
    }           
    // enter code here
}

Define and setup the directory where your image will be saved.

var root = HttpContext.Current.Server.MapPath("~/Content/Images/");
if (!Directory.Exists(root))
{
    Directory.CreateDirectory(root);
}  

Setup the StreamProvider and attempt to get the model data, which is the JSON you mentioned.

var streamProvider = new MultipartFormDataStreamProvider(root);
var result =
    await Request.Content.ReadAsMultipartAsync(streamProvider);
if (result.FormData["model"] == null)
{
    throw new HttpResponseException(HttpStatusCode.BadRequest);
}

Now access the files in the request.

try
{
    // Deserialize model data to your own DTO
    var model = result.FormData["model"];
    var formDto = JsonConvert
        .DeserializeObject<MyDto>(model, new IsoDateTimeConverter());
    var files = result.FileData.ToList();                
    if (files != null)
    {
        foreach (var file in files)
        {
            // Do anything with the file(s)
        }
    }
}
Sign up to request clarification or add additional context in comments.

8 Comments

Thanks. Will try out the solution.
I am not able to access Request.Content in .net core 2.0 preview. Any idea on that?
IFormFile interface was introduce in .net core. Have a look at it here: learn.microsoft.com/en-us/aspnet/core/mvc/models/file-uploads.
I think you need [FromForm] attribute also
For me on .NET Core 3.1 it only worked after adding [FromForm] in the method argument list as @ManuMohanThekkedath suggested.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.