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?
Specifies the settings on a JsonSerializer object. Newtonsoft.Json. JsonSerializerSettings. Namespace: Newtonsoft.Json.
SerializeObject Method (Object, Type, JsonSerializerSettings) Serializes the specified object to a JSON string using a type, formatting and JsonSerializerSettings. Namespace: Newtonsoft.Json.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With