一尘不染

在WebAPI中的模型上使用Serializable属性

json

我有以下情形:我正在使用WebAPI,并根据模型将JSON结果返回给使用者。现在,我还具有将模型序列化为base64的附加要求,以便能够将其持久化在缓存中和/或用于审计目的。问题是,当我将[Serializable]属性添加到模型中以便将模型转换为Base64时,JSON输出更改如下:

该模型:

[Serializable]
public class ResortModel
{
    public int ResortKey { get; set; }

    public string ResortName { get; set; }
}

没有该[Serializable]属性,JSON输出为:

{
    "ResortKey": 1,
    "ResortName": "Resort A"
}

使用该[Serializable]属性,JSON输出为:

{
    "<ResortKey>k__BackingField": 1,
    "<ResortName>k__BackingField": "Resort A"
}

如何在[Serializable]不更改JSON输出的情况下使用属性?


阅读 314

收藏
2020-07-27

共1个答案

一尘不染

默认情况下,Json.NET会忽略该Serializable属性。不过,根据要评论此答案由张曼玉颖,覆盖的WebAPI这种行为,这会导致你的输出。

默认情况下,Json.NET序列化程序将IgnoreSerializableAttribute设置为true。在WebAPI中,我们将其设置为false。遇到此问题的原因是Json.NET忽略了属性:“
Json.NET现在检测到具有Seri​​alizableAttribute的类型,并对该类型上的所有字段(包括公共字段和私有字段)进行序列化,并忽略属性”(引自james。
newtonking.com/archive/2012/04/11/…)

一个简单的示例演示没有WebAPI时的相同行为,如下所示:

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
                    }
                }));
        }
    }
}

有几种方法可以解决此问题。一种是用普通JsonObject属性装饰模型:

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

另一种方法是覆盖的默认设置Application_Start()。根据此答案,默认设置应执行以下操作:

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

如果那不起作用,您可以明确地知道它:

GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings()
    {
        ContractResolver = new DefaultContractResolver()
        {
            IgnoreSerializableAttribute = true
        }
    };
2020-07-27