Search code examples
c#asp.netangularjsasp.net-web-aping-file-upload

Angular Upload File and Additional Data ASP WebAPI


I'm trying to upload a form with some text fields and a file to my WebAPI. Currently I always get a 415 error (a breakpoint in the ASP controller doesn't gets hit). My code looks like this:

Angular Service

// 'Upload' is from ng-file-upload
function applicationService(settings, $http, Upload) {
  var createCustomApplication = function(application) {
    var url = settings.baseUrl + '/api/applications/custom';

    var data = new FormData();
    angular.forEach(application, function (value, key) {
      data.append(key, value);
    });

    return Upload.upload({
      url: url,
      data: data,
      method: 'POST'
    });
  };

  return {
    createCustomApplication: createCustomApplication
  }
}

WebAPI controller

[ResponseType(typeof(ApplicationModel))]
[HttpPost, Route("api/applications/custom")]
public IHttpActionResult CreateCustomApplication([FromBody]ApplicationModel application)
{
   var file = HttpContext.Current.Request.Files[0];
   return Ok();
}

Solution

  • If you want to include a form with files as parameter to an action it is necessary to add a custom media formatter. Fortunately someone already created a Nuget-package for this. Configuration is easy. Install the package and add a line to your WebApiConfig-file.

    This package allows you to use a HttpFile-object which captures your file either directly as a parameter or inside a model. From the docs:

    [HttpPost]
    public void PostFileBindRawFormData(MultipartDataMediaFormatter.Infrastructure.FormData formData)
    {
        HttpFile file;
        formData.TryGetValue(<key>, out file);
    }
    

    or

    public class PersonModel
    {
        public string FirstName {get; set;}
        public string LastName {get; set;}
        public DateTime? BirthDate {get; set;}
        public HttpFile AvatarImage {get; set;}
        public List<HttpFile> Attachments {get; set;}
        public List<PersonModel> ConnectedPersons {get; set;}
    }
    
    //api controller example
    [HttpPost]
    public void PostPerson(PersonModel model)
    {
        //do something with the model
    }