6

Based on Diego's unanswered comment under the top-voted answer in this question:

JSON serialization of enum as string

So for an enum:

public enum ContactType
{
    Phone = 0,
    Email = 1,
    Mobile = 2
}

And for eg. a property:

//could contain ContactType.Phone, ContactType.Email, ContactType.Mobile
IEnumerable<ContactType> AvailableContactTypes {get;set;} 

To something like the JSON:

{ContactTypes : ['Phone','Email','Mobile']}

instead of

{ContactTypes : [0,1,2]}

As is the case with the normal JavaScriptSerializer?

Community
  • 1
  • 1
Mark Gibaud
  • 2,061
  • 23
  • 35
  • Use strings for the values? – Shmiddty Feb 19 '13 at 18:05
  • Some serialization libraries have a boolean that you can flip to determine the output of a serialized enumeration. I seen a video of one of the MVC developers that demoed the feature..unfortunately I couldn't hunt down the video. – afreeland Feb 19 '13 at 20:22

2 Answers2

3

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;} 
dbc
  • 104,963
  • 20
  • 228
  • 340
Mark Gibaud
  • 2,061
  • 23
  • 35
2

I've always found it easier to add an additional property in these cases than to try to change the behavior of the json.net parser.

[JsonIgnore]
IEnumerable<ContactType> AvailableContactTypes {get;set;}

IEnumerable<string> AvailableContactTypesString
{
    get { return AvailableContactTypes.Select(c => c.ToString()); }
}

Of course, if you need to deserialize, you'd need a setter on that property as well.

set { AvailableContactTypes = value
    .Select(c => Enum.Parse(typeof(ContactType), c) as ContactType); }
Jeff-Meadows
  • 2,154
  • 18
  • 25