我有以下情形:我正在使用WebAPI,并根据模型将JSON结果返回给使用者。现在,我还具有将模型序列化为base64的附加要求,以便能够将其持久化在缓存中和/或用于审计目的。问题是,当我将[Serializable]属性添加到模型中以便将模型转换为Base64时,JSON输出更改如下:
[Serializable]
该模型:
[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输出的情况下使用属性?
默认情况下,Json.NET会忽略该Serializable属性。不过,根据要评论此答案由张曼玉颖,覆盖的WebAPI这种行为,这会导致你的输出。
Serializable
默认情况下,Json.NET序列化程序将IgnoreSerializableAttribute设置为true。在WebAPI中,我们将其设置为false。遇到此问题的原因是Json.NET忽略了属性:“ Json.NET现在检测到具有SerializableAttribute的类型,并对该类型上的所有字段(包括公共字段和私有字段)进行序列化,并忽略属性”(引自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属性装饰模型:
JsonObject
[Serializable] [JsonObject] class Foo { public string Bar { get; set; } }
另一种方法是覆盖的默认设置Application_Start()。根据此答案,默认设置应执行以下操作:
Application_Start()
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings();
如果那不起作用,您可以明确地知道它:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings() { ContractResolver = new DefaultContractResolver() { IgnoreSerializableAttribute = true } };