Serialize a Container of Enums as Strings Using JSON.Net

Serialize a container of enums as strings using JSON.net

You need to use JsonPropertyAttribute.ItemConverterType property:

class Example2
{
[JsonProperty (ItemConverterType = typeof(StringEnumConverter))]
public IList<Size> Sizes { get; set; }
}

Are there any attributes for serializing Enums as strings in Json.NET?

Just use StringEnumConverter

var actual = json.ToString(Formatting.None, 
new Newtonsoft.Json.Converters.StringEnumConverter());

EDIT

Is there no way to tell it to automatically use that converter every time you call ToString()?

JsonConvert.DefaultSettings = () => new JsonSerializerSettings() { 
Converters = new List<Newtonsoft.Json.JsonConverter>() { new Newtonsoft.Json.Converters.StringEnumConverter() }
};

var actual = JsonConvert.SerializeObject(json);

Serialize enum to string

The JSON formatter has very specialized behaviour when working with enumerations; the normal Data Contract attributes are ignored and it treats your enum as a number, not the more human-readable string you'd expect with other formats. Whilst this makes it easy to deal with flag-type enumerations, it makes most other types much harder to work with.

From MSDN:

Enumeration member values are treated as numbers in JSON, which is
different from how they are treated in data contracts, where they are
included as member names. For more information about the data contract
treatment, see Enumeration Types in Data Contracts.

  • For example, if you have public enum Color {red, green, blue, yellow,
    pink}
    , serializing yellow produces the number 3 and not the string
    "yellow".

  • All enum members are serializable. The EnumMemberAttribute and the
    NonSerializedAttribute attributes are ignored if used.

  • It is possible to deserialize a nonexistent enum value - for example,
    the value 87 can be deserialized into the previous Color enum even
    though there is no corresponding color name defined.

  • A flags enum is not special and is treated the same as any other enum.

The only practical way to resolve this, to allow end-users to specify a string instead of a number, is to not use the enum in your contract. Instead the practical answer is to replace your enum with a string and perform internal validation on the value such that it can be parsed into one of the valid enum representations.

Alternatively (though not for the feint of heart), you could replace the JSON formatter with your own, which would respect enumerations in the same way as other formatters.

Serialise an array of enums to their string values in JSON.NET

Try to add StringEnumConverter into your WebApiConfig

public static void Register(HttpConfiguration config)
{
config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new StringEnumConverter());

//...........................................
}

How do you serialize an enum array to a Json array of strings?

It would appear that in one of the later versions of Json.NET there is proper provision for this, via the ItemConverterType property of the JsonProperty attribute, as documented here:

http://james.newtonking.com/archive/2012/05/08/json-net-4-5-release-5-jsonproperty-enhancements.aspx

I was unable to try it out as I hit problems upgrading from Json.NET 3.5 that were related to my own project. In the end I converted my viewmodel to IEnumerable<string> as per Shmiddty's suggestion (there is still an impedance mismatch though and I will come back to refactor this in future).

Hope that helps anyone else with the same problem!

Example usage:

[JsonProperty(ItemConverterType = typeof(StringEnumConverter))]
IEnumerable<ContactType> AvailableContactTypes {get;set;}

Tell Nancy to serialize enums into strings

I haven't had the time to test it myself, but the following code should work for all Enum types

public class JsonConvertEnum : JavaScriptPrimitiveConverter
{
public override IEnumerable<Type> SupportedTypes
{
get
{
yield return typeof(Enum);
}
}

public override object Deserialize(
object primitiveValue, Type type, JavaScriptSerializer serializer)
{
if (!type.IsEnum)
{
return null;
}

return Enum.Parse(type, (string)primitiveValue);
}

public override object Serialize(
object obj, JavaScriptSerializer serializer)
{
if (!obj.GetType().IsEnum)
{
return null;
}

return obj.ToString();
}
}

Basically it uses the Type metadata to determine if it is an Enum or not and then makes use of Enum.Parse(...) to convert it from the primitive value back to the correct enum. To convert from Enum to string all you have to do is to cast the value to a string

It can be made more terse by using the ternary operator, but I left the more verbose version for clarity

Hope this helps



Related Topics



Leave a reply



Submit