在WebAPI中使用Model上的Serializable属性

我有以下场景:我正在使用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输出为:

 { "k__BackingField": 1, "k__BackingField": "Resort A" } 

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

默认情况下,Json.NET忽略Serializable属性。 但是,根据Maggie Ying 对此答案的评论(下面引用因为评论并不意味着持续),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 } };