有选择地使用默认的JSON转换器 [英] Selectively use default JSON converter
问题描述
我在Web API项目的Startup.cs
中使用以下内容将Enums JSON序列化为字符串:
// Configure JSON Serialization
var jsonSerializationSettings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
jsonSerializationSettings.Formatting = Newtonsoft.Json.Formatting.None;
jsonSerializationSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
这是为了避免用[JsonConverter(typeof(StringEnumConverter))]
现在,如何选择某些枚举属性退出全局序列化设置,并使用默认的序列化器转换为整数?
您可以将虚拟转换器添加到有问题的不执行任何操作的属性中:
public class NoConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
// Note - not called when attached directly via [JsonConverter(typeof(NoConverter))]
throw new NotImplementedException();
}
public override bool CanRead { get { return false; } }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
然后使用 [JsonConverter(typeof(NoConverter))]
将其附加到属性.这样做之后,JsonConverter
属性的转换器取代了全局指定的转换器,但是由于CanRead
和CanWrite
都返回false,因此不执行任何转换.对于枚举的集合,可以使用 [JsonProperty(ItemConverterType = typeof(NoConverter))]
.>
例如,如果您定义类型:
public enum Foo { A, B, C }
public class RootObject
{
[JsonConverter(typeof(NoConverter))]
public Foo FooAsInteger { get; set; }
public Foo FooAsString { get; set; }
}
然后
var root = new RootObject { FooAsInteger = Foo.B, FooAsString = Foo.B };
var json = JsonConvert.SerializeObject(root, Formatting.Indented, new StringEnumConverter());
Console.WriteLine(json);
产生输出
{
"FooAsInteger": 1,
"FooAsString": "B"
}
请注意,如果要将所有数据模型中所有出现的枚举都序列化为整数,也可以直接将NoConverter
应用于枚举:
[JsonConverter(typeof(NoConverter))]
public enum FooAlwaysAsInteger { A, B, C }
示例小提琴.
I use the following in my Web API project's Startup.cs
to JSON-serialize Enums into strings:
// Configure JSON Serialization
var jsonSerializationSettings = GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings;
jsonSerializationSettings.Formatting = Newtonsoft.Json.Formatting.None;
jsonSerializationSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
This is to avoid decorating every Enum property with [JsonConverter(typeof(StringEnumConverter))]
Now, how can I selectively opt out of my global serialization setting for some Enum properties and use the default serializer that converts to integers?
You could add a dummy converter to the properties in question that does nothing:
public class NoConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
// Note - not called when attached directly via [JsonConverter(typeof(NoConverter))]
throw new NotImplementedException();
}
public override bool CanRead { get { return false; } }
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
throw new NotImplementedException();
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
Then attach it to the property using [JsonConverter(typeof(NoConverter))]
. Having done so, the JsonConverter
attribute's converter supersedes the globally specified converter, but since CanRead
and CanWrite
both return false no conversion is performed. For collections of enums, you could use [JsonProperty(ItemConverterType = typeof(NoConverter))]
.
For instance, if you define the types:
public enum Foo { A, B, C }
public class RootObject
{
[JsonConverter(typeof(NoConverter))]
public Foo FooAsInteger { get; set; }
public Foo FooAsString { get; set; }
}
Then
var root = new RootObject { FooAsInteger = Foo.B, FooAsString = Foo.B };
var json = JsonConvert.SerializeObject(root, Formatting.Indented, new StringEnumConverter());
Console.WriteLine(json);
Produces the output
{
"FooAsInteger": 1,
"FooAsString": "B"
}
Note that you can also apply NoConverter
directly to the enum, if you want all occurrences of the enum in all data models to be serialized as an integer:
[JsonConverter(typeof(NoConverter))]
public enum FooAlwaysAsInteger { A, B, C }
Sample fiddle.
这篇关于有选择地使用默认的JSON转换器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!