Is there a way to be able to get model binding (or whatever) to give out the model from a multipart form data request in ASP.NET MVC Web API?
I see various blog posts but either things have changed between the post and actual release or they don't show model binding working.
This is an outdated post: Sending HTML Form Data
and so is this: Asynchronous File Upload using ASP.NET Web API
I found this code (and modified a bit) somewhere which reads the values manually:
Model:
public class TestModel
{
[Required]
public byte[] Stream { get; set; }
[Required]
public string MimeType { get; set; }
}
Controller:
public HttpResponseMessage Post()
{
if (!Request.Content.IsMimeMultipartContent("form-data"))
{
throw new HttpResponseException(HttpStatusCode.UnsupportedMediaType);
}
IEnumerable<HttpContent> parts = Request.Content.ReadAsMultipartAsync().Result.Contents;
string mimeType;
if (!parts.TryGetFormFieldValue("mimeType", out mimeType))
{
return Request.CreateResponse(HttpStatusCode.BadRequest);
}
var media = parts.ToArray()[1].ReadAsByteArrayAsync().Result;
// create the model here
var model = new TestModel()
{
MimeType = mimeType,
Stream = media
};
// save the model or do something with it
// repository.Save(model)
return Request.CreateResponse(HttpStatusCode.OK);
}
Test:
[DeploymentItem("test_sound.aac")]
[TestMethod]
public void CanPostMultiPartData()
{
var content = new MultipartFormDataContent { { new StringContent("audio/aac"), "mimeType"}, new ByteArrayContent(File.ReadAllBytes("test_sound.aac")) };
this.controller.Request = new HttpRequestMessage {Content = content};
var response = this.controller.Post();
Assert.AreEqual(response.StatusCode, HttpStatusCode.OK);
}
This code is basically fragile, un-maintainable and further, doesn't enforce the model binding or data annotation constraints.
Is there a better way to do this?
Update: I've seen this post and this makes me think - do I have to write a new formatter for every single model that I want to support?
See Question&Answers more detail:os