How do you serialize an enum array to a Json array of strings? [duplicate]
Asked Answered
U

2

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?

Univalent answered 19/2, 2013 at 17:55 Comment(2)
Use strings for the values?Madagascar
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.Chengtu
U
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;} 
Univalent answered 20/2, 2013 at 11:21 Comment(0)
L
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); }
Lanalanae answered 19/2, 2013 at 18:23 Comment(2)
Yeah, currently doing that but not as a property, just in the constructor...bit crufty though...Univalent
Could not get it to workFelspar

© 2022 - 2024 — McMap. All rights reserved.