.NET Serializable attribute Pitfall with AspNet WebApi 2

A few days ago I was working on an enhancement to our product and needed to add a new REST API server controller to consume some messages. That is quite easy to implement once you have a framework ready. I ended up with a code similar to this:

[Serializable]
public class Message
{
    public string Content { get; set; }
}

[RoutePrefix("api/foo")]
public class MessageController : ApiController
{
    [HttpPost]
    [Route("message")]
    public void Publish(Message message)
    {
        log.Debug($"Content: {message.Content}");
    }
}

That’s pretty straighforward implementation which should allow me to send a json message with Content field to api/foo/message url and the value should be printed to my log.

I used curl to send the request:

curl -i -X POST -H "Content-Type: application/json" -d '{"content": "Hello World"}' http://localhost/api/foo/message

One would expect that after I send the request I’ll see the Hello World content in my log. Unfortunatelly, the only thing I saw in the log was empty string. I was like what the hell is going on? It took me quite a bit of time to figure it out. I tried to serialize the Message class using JSON converter that is used for deserializing too and there it was. Instead of the Content field the serialized JSON contained this strange <Content>k__BackingField field. Not really something completelly strange, but certainly unexpected. But it was quite obvious what could cause such thing and yes, it is the Serializable attribute on the Message class. It completelly changed behavior of the JSON deserializer so much that instead of Content field it expected <Content>k__BackingField as field name in the JSON. Even though I knew the reason I tried the following JSON request anyway

{
    "<Content>k__BackingField": "Hello World"
}

and it worked. I saw nice Hello World in my log.

I removed the Serializable attribute to fix my code.