I have the following action signature
[ValidateInput(false)]
public HttpResponseMessage PostParam(Param param)
With Param looking something like this:
public class Param {
public int Id { get; set;}
public string Name { get; set; }
public string Choices { get; set; }
}
Here's the hitch - what comes over the wire is something like this
{
Id: 2,
Name: "blah",
Choices: [
{
foo: "bar"
},
{
blah: "blo"
something: 123
}
]
}
I don't want "Choices" to deserialize - I want it stored as a string (yes, I understand the security implications). Understandably, I get an error because since the default binder does not know this.
Now with Asp Mvc creating a specific ModelBinder would be fairly simple. I'd
- inherit DefaultModelBinder
- override the property deserialization with my own
- set the binder in my
Application_Start
usingBinders.Add
Seems like with Web Api this is a different process - the System.Web.DefaultModelBinder doesn't have anything to override and that I can't hook things up using Binders.Add
. I've tried looking around but couldn't find much on how to actually do what I want. This is further complicated since apparently the ModelBinders api changed quite a bit over Beta and RTM so there's a lot of outdated information out there.
In Web API you have to distinguish three concepts -
ModelBinding
,Formatters
andParameterBinding
. That is quite confusing to people moving from/used to MVC, where we only talk aboutModelBinding
.ModelBinding
, contrary to MVC, is responsible only for pulling data out of URI. Formatters deal with reading the body, andParameterBinding
(HttpParameterBinding
) encompasses both of the former concepts.ParameterBinding
is really only useful when you want to revolutionize the whole mechanism (i.e. allow two objects to be bound from body, implement MVC-style binding and so on) - for simpler tasks modifying binders (for URI specific data) or formatters (for body data) is almost always more than enough.Anyway, to the point - what you want to achieve can very easily be done with a custom
JSON.NET
converter (JSON.NET is the default serialization library behind Web API JSON formatting engine).All you need to do is:
And then add the converter:
In this case we are telling JSON.NET in the converter to store
Choices
asstring
(in the read method), and when you return theParam
object with theChoices
property to the client (in the write method) we take thestring
and serialize to anarray
so that the output JSON looks identical to the input one.You can test it now like this:
And verify that the data coming in is like you wished, and the data coming out is identical to the original JSON.