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,
, serializing yellow produces the number 3 and not the string
pink}
"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
Illustrating Usage of the Volatile Keyword in C#
Pattern for Calling Wcf Service Using Async/Await
Detecting Network Connection Speed and Bandwidth Usage in C#
How to Get the Width and Height of a Multi-Dimensional Array
Convert String to Hex-String in C#
Mvvm Light 5.0: How to Use the Navigation Service
Linq Order by Null Column Where Order Is Ascending and Nulls Should Be Last
Dependency Injection Using Azure Webjobs Sdk
Copy Rows from One Datatable to Another Datatable
How Does Foreach Work When Looping Through Function Results
How to Get the Last Five Characters of a String Using Substring() in C#
How to Bind Parameters via Odbc C#