How to Set Up a Web API Controller for Multipart/Form-Data

How to set up a Web API controller for multipart/form-data

I normally use the HttpPostedFileBase parameter only in Mvc Controllers. When dealing with ApiControllers try checking the HttpContext.Current.Request.Files property for incoming files instead:

[HttpPost]
public string UploadFile()
{
var file = HttpContext.Current.Request.Files.Count > 0 ?
HttpContext.Current.Request.Files[0] : null;

if (file != null && file.ContentLength > 0)
{
var fileName = Path.GetFileName(file.FileName);

var path = Path.Combine(
HttpContext.Current.Server.MapPath("~/uploads"),
fileName
);

file.SaveAs(path);
}

return file != null ? "/uploads/" + file.FileName : null;
}

API controller POST method multipart/form-data using boundary get message inside the body

There isn't built-in support of multi-part/form-data Media Type in .Net5 by default. So, the input formatter should be attached to the MvcBuilder.

Considering the fact that you can't manipulate client-side, ApiMultipartFormDataFormatter which enables this type of input formatting can be utilized.

  1. Add the Package:

Install-Package ApiMultipartFormDataFormatter -Version 3.0.0


  1. Configure the Formatter in Startup.cs

    public void ConfigureServices(IServiceCollection services)
    {
    services.AddControllers(options =>
    {
    options.InputFormatters.Add(new MultipartFormDataFormatter());
    });
    }
  2. Assuming the mentioned well formed json is something like below class:

    public class CustomContent
    {
    public string Name { get; set; }
    }

    So, we need to wrap it up into another class that contains this as a parameter.
    Note: The library doesn't support deserialization by this moment So, a getter-only property is added to the model which returns the deserialized object.

    public class ViewModel
    {
    // Equivalent to ZZZZZZZZZZ
    public string SerializedContent { get; set; }
    public CustomContent Content => !string.IsNullOrEmpty(SerializedContent)
    ? JsonConvert.DeserializeObject<CustomContent>(SerializedContent)
    : null;
    }
  3. Reform the Action to accept the wrapper model.

    [HttpPost]
    [Route("[action]")]
    public IActionResult Parse(ViewModel vm)
    {
    return Ok($"Received Name: {vm?.Content?.Name}");
    }

The working cURL request of the corresponding example is:

curl --location --request POST 'http://localhost:25599/api/MultiPart/Parse' 

\
--header 'Content-Type: multipart/form-data; boundary=boundary' \
--data-raw '--boundary
Content-Disposition: form-data; name="SerializedContent"
Content-Type: application/json
Content-Length: 100

{
"Name" : "Foo"
}
--boundary--'

The response should be equal to Received Name: Foo.

Web API Simplest way to pickup a multipart/form-data response

This is a routing issue. If the intention is to use attribute routing, then make sure that it is enabled

public static class WebApiConfig {
public static void Register(HttpConfiguration config) {
// Attribute routing.
config.MapHttpAttributeRoutes();

// Convention-based routing.
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}

And decorate the target controller accordingly

[RoutePrefix("api/Image")]
public class ImageController : ApiController {
[HttpPost]
[Route("Upload")] // Matches POST api/Image/Upload
public IHttpActionResult Upload()
{
return Ok("I am working");
}
}

From there you should be able to include your additional functionality.

If you want to read multipart data consider getting it from the request's content.

var content = await Request.Content.ReadAsMiltipartAsync();

only thing I care about is that it sends a OK 200 reply back.

I want to make the simplest method possible to get this to work I
will make it more complex later but currently just want the post
method to be hit
I don't even care if the code inside is working
currently.

This answer should address the above. Any further issues should be posted in other questions.

.Net MVC How to submit multipart/form-data to Web Api

ApiController expects your controllers to receive JSON implicitly, while Controller expects does the same with Form Data. To tell your methods in an apicontroller to expect form data you'll need a [FromForm]

[HttpPost]
[ResponseType(typeof(News))]
public IHttpActionResult PostNewsModel([FromForm] News newsModel)
{
//some code
}

How to send multipart/form-data to ASP.NET Core Web API?

Maybe you should try decorate controller input and model with [FromForm] attribute?
See more info here: web api parameters binding.

In given example your controller action should look like this:

[HttpPost("/api/account"), Authorize]
public void SaveUser([FromForm]UserModel info)

In model:

[FromForm(Name="avatar")]
public IFormFile Avatar { get; set; }

[FromForm(Name="name")]
public string Name { get; set; }

Receiving Multi-part form data in dotnet core web API

As CodeCaster says,add Content-Type:multipart/form-data; and change List<IFormCollection> to List<IFormFile>.It is not changing the whole model to List.So you can also retrieve other information which exists in your model with idobj.xxx.Change

public class InvoiceDetails
{


public int? po_id { get; set; }
public DateTime created_date { get; set; }
public string grn_status { get; set; }
public int utilization_amount { get; set; }
public int currency_id { get; set; }
public string currency_code { get; set; }
public string currency_symbol { get; set; }

[FromForm(Name = "invoice_file")]
public List<IFormCollection> invoice_file { get;set;}
[FromForm(Name = "other_files")]
public List<IFormCollection> other_files { get; set; }


}

to

public class InvoiceDetails
{

public int? po_id { get; set; }
public DateTime created_date { get; set; }
public string grn_status { get; set; }
public int utilization_amount { get; set; }
public int currency_id { get; set; }
public string currency_code { get; set; }
public string currency_symbol { get; set; }

[FromForm(Name = "invoice_file")]
public List<IFormFile> invoice_file { get; set; }
[FromForm(Name = "other_files")]
public List<IFormFile> other_files { get; set; }

}

result:
Sample Image
IFormCollection is used to retrieve all the values from posted form data.refer to the official document.

If you want to use c,you can try to use it,you can do like this

public IActionResult CreateInvoice([FromForm]IFormCollection idobj)

and you need to get the data you want to foreach keys of IFormCollection,so public List<IFormCollection> invoice_file { get;set;} is better than use IFormCollection.

ASP.NET How read a multipart form data in Web API?

This should help you get started:

 var uploadPath = HostingEnvironment.MapPath("/") + @"/Uploads";
Directory.CreateDirectory(uploadPath);
var provider = new MultipartFormDataStreamProvider(uploadPath);
await Request.Content.ReadAsMultipartAsync(provider);

// Files
//
foreach (MultipartFileData file in provider.FileData)
{
Debug.WriteLine(file.Headers.ContentDisposition.FileName);
Debug.WriteLine("File path: " + file.LocalFileName);
}

// Form data
//
foreach (var key in provider.FormData.AllKeys)
{
foreach (var val in provider.FormData.GetValues(key))
{
Debug.WriteLine(string.Format("{0}: {1}", key, val));
}
}


Related Topics



Leave a reply



Submit