By default, Json.NET ignores the Serializable attribute. However, according to the commentary, this answer is from Maggie Ying ( given below because the comments are not meant to be continued), the WebAPI overrides this behavior that causes your output.
The Json.NET serial analyzer sets the IgnoreSerializableAttribute parameter to true by default. In WebAPI, we set to false. The reason you ran into this problem is because Json.NET ignores properties: "Json.NET now detects types that have SerializableAttribute, and serializes all fields of this type, both public and private, and ignores properties "(quoted from james.newtonking.com/archive/2012/04/11 / ... )
A simple example showing the same behavior without a WebAPI might look like this:
using Newtonsoft.Json; using Newtonsoft.Json.Serialization; using System; namespace Scratch { [Serializable] class Foo { public string Bar { get; set; } } class Program { static void Main() { var foo = new Foo() { Bar = "Blah" }; Console.WriteLine(JsonConvert.SerializeObject(foo, new JsonSerializerSettings() { ContractResolver = new DefaultContractResolver() { IgnoreSerializableAttribute = false } })); } } }
There are several ways around this behavior. One is to decorate your model with a simple JsonObject attribute:
[Serializable] [JsonObject] class Foo { public string Bar { get; set; } }
Another way is to override the default settings in Application_Start() . According to this answer , the default settings should do this:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings();
If this does not work, you may be explicit:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings() { ContractResolver = new DefaultContractResolver() { IgnoreSerializableAttribute = true } };
source share