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.
- Add the Package:
Install-Package ApiMultipartFormDataFormatter -Version 3.0.0
Configure the Formatter in
Startup.cs
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers(options =>
{
options.InputFormatters.Add(new MultipartFormDataFormatter());
});
}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;
}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:
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
Upload File Through C# Using JSON Request and Restsharp
How Does Hashset Compare Elements for Equality
How to Tell JSON.Net Globally to Apply the Stringenumconverter to All Enums
How to Bind List to Datagridview
Why Is the Iteration Variable in a C# Foreach Statement Read-Only
How to Sort a List of Objects by a Specific Field in C#
What's the Hardest or Most Misunderstood Aspect of Linq
How to Test If Type Is Primitive
Produce a Random Number in a Range Using C#
What Is an Algorithm to Diff the Two Strings in the Same Way That So Does on the Version Page
Making a Private Method Public to Unit Test It...Good Idea
Disable JavaScript Error in Webbrowser Control
JSON.Net Serialize Object with Root Name
How to Sort a Two-Dimensional (Rectangular) Array in C#
Main Method Code Entirely Inside Try/Catch: Is It Bad Practice