Need to get .NET application developed?

Nancy is a lightweight Web framework for .Net that provides an interesting alternative to ASP.Net MVC. One issue that I’ve come across while working with it, is that although it currently (v 0.21.1) does support model binding, it all falls apart when you want both files and a JSON body in your POST or PUT HTTP request. Luckily there’s a quick and easy way around this issue.

Case study

Let’s assume that we want to process an HTTP POST request, with a standard JSON body, and one or more files attached to it. Such a request should contain the “content-type” header set to multipart/… (in this article I’ll assume its multipart/form-data ) as the request payload does indeed contain multiple parts (the files as binary data and the JSON body as text). Currently, Nancy model binding only supports binding to requests with content-type set to application/json or application/xml out of the box, so binding any model to such a request will fail. However, it does provide the HttpMultipart class which neatly handles splitting the request body into different parts and detecting their respective content-types. Since all that logic is already in place I’ve decided to skip model binding alltogether, and extract the JSON body (and the model from that) manually.

First a regex is used to determine whether the request content-type is indeed multipart/form-data. This is to handle the case where no files were uploaded in the request, and so the content-type is just application/json, since there are no “multiple parts”)

￼￼￼Once you have that you can use your favourite JSON parser (e.g. Json.Net) to bind your model into an object. Also note that while you can use HttpMultipart to extract the files attached to your request, Nancy actually does that for you with the Request.Files property:

Nancy is all what I need

Although not supported out of the box, parsing multipart requests with NancyFX is pretty straightforward. With a little more work this solution could easily be refactored into a custom modelbinder, but since I use it in only one spot I’m happy with what I have for now.