19
votes

I have this ASP.NET Web API method, and I want to post an object and in the same time, a file!

    public async Task<IHttpActionResult> Post(Facility facility)
    {
        if (!ModelState.IsValid)
            return BadRequest();

        // Check if the request contains multipart/form-data.
        if (!Request.Content.IsMimeMultipartContent())
        {
            throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
        }

        string root = HttpContext.Current.Server.MapPath("~/App_Data");
        var provider = new MultipartFormDataStreamProvider(root);

            // Read the form data.
            await Request.Content.ReadAsMultipartAsync(provider);

            // This illustrates how to get the file names.
            foreach (MultipartFileData file in provider.FileData)
            {
                Trace.WriteLine(file.Headers.ContentDisposition.FileName);
                Trace.WriteLine("Server file path: " + file.LocalFileName);
            }
            // Logic
            // Login

        return Ok(facilityManager.Insert(facility));
    }

And I want to call it, so I send this http request with fiddler:

Header:

Content-Type: multipart/form-data; boundary=-------------------------acebdf13572468
User-Agent: Fiddler
Host: localhost:44301
Content-Length: 3279

Body:

---------------------------acebdf13572468
Content-Disposition: form-data; name="fieldNameHere"; filename="credits.txt"
Content-Type: text/plain

<@INCLUDE *C:\Program Files (x86)\Fiddler2\credits.txt*@>
---------------------------acebdf13572468
Content-Disposition: form-data; name="facility"
Content-Type: application/json
{
    "FacilityTypeId":"1"
}
---------------------------acebdf13572468--

I get an 415 error code with response text:

{"message":"The request entity's media type 'multipart/form-data' is not supported for this resource.","exceptionMessage":"No MediaTypeFormatter is available to read an object of type 'Facility' from content with media type 'multipart/form-data'.","exceptionType":"System.Net.Http.UnsupportedMediaTypeException","stackTrace":" at System.Net.Http.HttpContentExtensions.ReadAsAsync[T](HttpContent content, Type type, IEnumerable1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)\r\n at System.Net.Http.HttpContentExtensions.ReadAsAsync(HttpContent content, Type type, IEnumerable1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)\r\n at System.Web.Http.ModelBinding.FormatterParameterBinding.ReadContentAsync(HttpRequestMessage request, Type type, IEnumerable`1 formatters, IFormatterLogger formatterLogger, CancellationToken cancellationToken)"}

I searched a lot before asking but couldn't find any solution. Thnaks for helping.

EDIT:

A note: If I remove the "facility" parameter, and let the method only for uploading the file, it works perfect, but I want to post JSON and a file together.

2
Hello, do you have solution to this problem? I am having the same problem.codegrid
@uikrosoft, Don't set arguments (parameters) in the api function (Make it without parameters). And get your parameters values inside that function from the post body. That worked for me.Hashem
Here is a complete tutorial: asp.net/web-api/overview/advanced/…Hashem Aboonajmi

2 Answers

6
votes

I had the same problem. Solved by MultipartDataMediaFormatter for ASP.NET WebApi. How to use:

  1. Find and install from Nuget packages MultipartDataMediaFormatter.
  2. Add current formatter to WebApi formatters collection:

    • if WebApi hosted on IIS (on Application Start). :
      • GlobalConfiguration.Configuration.Formatters.Add(new FormMultipartEncodedMediaTypeFormatter());
    • if WebApi is self-hosted:

      • new HttpSelfHostConfiguration(<url>).Formatters.Add(new FormMultipartEncodedMediaTypeFormatter());

After that you can post objec with file together in one model.

Note: In Nuget packages version 1.1.0 is not the last. They are not updated yet. Maybe possible to install latest version manually.

3
votes

"mulitpart/form-data" so we register the UploadMultipartMediaTypeFormatter

public class UploadMultipartMediaTypeFormatter : MediaTypeFormatter
{
    UploadMultipartMediaTypeFormatter()
    {
        SupportedMediaTypes.Add(new MediaTypeHeaderValue("multipart/form-data"));
    }
}

* register in global.asax or (see sandbox code)

config.Formatters.Add(new UploadMultipartMediaTypeFormatter());

The WebApi will now call MediaTypeFormatter.ReadFromStreamAsync and we can call the HttpContent.ReadAsMultipartAsync extension from there.