Using Serializable attribute on Model in WebAPI

北慕城南 提交于 2019-11-27 23:40:55
Bart van Nierop

By default, Json.NET ignores the Serializable attribute. However, according to a comment to this answer by Maggie Ying (quoted below because comments are not meant to last), WebAPI overrides that behavior, which causes your output.

Json.NET serializer by default set the IgnoreSerializableAttribute to true. In WebAPI, we set that to false. The reason why you hit this issue is because Json.NET ignores properties: "Json.NET now detects types that have the SerializableAttribute and serializes all the fields on that type, both public and private, and ignores the properties" (quoted from james.newtonking.com/archive/2012/04/11/…)

A simple example that demonstrates the same behavior without WebAPI can 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 plain JsonObject attribute:

[Serializable]
[JsonObject]
class Foo
{
    public string Bar { get; set; }
}

Another way is to override the default settings in your Application_Start(). According to this answer, the default settings should do it:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings();

If that doesn't work, you could be explicit about it:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings()
    {
        ContractResolver = new DefaultContractResolver()
        {
            IgnoreSerializableAttribute = true
        }
    };
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!