在 WebAPI 中对模型使用可序列化属性
Using Serializable attribute on Model in WebAPI
我遇到以下情况:我正在使用 WebAPI 并根据模型向消费者返回 JSON 结果。我现在有额外的要求将模型序列化为 base64,以便能够将它们保存在缓存中 and/or 将它们用于审计目的。问题是,当我将 [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"
}
如何在不更改 JSON 的输出的情况下使用 [Serializable]
属性?
默认情况下,Json.NET 忽略 Serializable
属性。但是,根据对 this answer by Maggie Ying 的评论(在下面引用,因为评论不会持续),WebAPI 会覆盖该行为,这会导致您的输出。
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/…)
在没有 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()
中的默认设置。根据 this answer,默认设置应该这样做:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings();
如果这不起作用,您可以明确说明:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings()
{
ContractResolver = new DefaultContractResolver()
{
IgnoreSerializableAttribute = true
}
};
我遇到以下情况:我正在使用 WebAPI 并根据模型向消费者返回 JSON 结果。我现在有额外的要求将模型序列化为 base64,以便能够将它们保存在缓存中 and/or 将它们用于审计目的。问题是,当我将 [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"
}
如何在不更改 JSON 的输出的情况下使用 [Serializable]
属性?
默认情况下,Json.NET 忽略 Serializable
属性。但是,根据对 this answer by Maggie Ying 的评论(在下面引用,因为评论不会持续),WebAPI 会覆盖该行为,这会导致您的输出。
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/…)
在没有 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()
中的默认设置。根据 this answer,默认设置应该这样做:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings();
如果这不起作用,您可以明确说明:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings = new JsonSerializerSettings()
{
ContractResolver = new DefaultContractResolver()
{
IgnoreSerializableAttribute = true
}
};