Pregunta .NET - serialización JSON de enum como cadena


Tengo una clase que contiene un enum propiedad, y al serializar el objeto usando JavaScriptSerializer, mi resultado json contiene el valor entero de la enumeración en lugar de su string "nombre". ¿Hay alguna manera de obtener la enumeración como una string en mi json sin tener que crear una costumbre JavaScriptConverter? Tal vez hay un atributo que podría decorar el enum definición, o propiedad del objeto, con?

Como ejemplo:

enum Gender { Male, Female }

class Person
{
    int Age { get; set; }
    Gender Gender { get; set; }
}

Resultado json deseado:

{ "Age": 35, "Gender": "Male" }

852
2018-03-14 05:18


origen


Respuestas:


No, no hay ningún atributo especial que pueda usar. JavaScriptSerializer serializa enums a sus valores numéricos y no a su representación de cadena. Debería usar una serialización personalizada para serializar el enum como su nombre en lugar de valor numérico.

Editar: Como señala @OmerBakhari JSON.net cubre este caso de uso (a través del atributo [JsonConverter(typeof(StringEnumConverter))]) y muchos otros no manejados por los serializadores .net incorporados. Aquí hay un enlace que compara características y funcionalidades de los serializadores.


204
2018-03-14 06:21



He encontrado eso Json.NET proporciona la funcionalidad exacta que estoy buscando con un StringEnumConverter atributo:

using Newtonsoft.Json;
using Newtonsoft.Json.Converters;

[JsonConverter(typeof(StringEnumConverter))]
public Gender Gender { get; set; }

Más detalles disponibles en StringEnumConverter documentación.


1656
2018-05-20 00:58



Agregue lo siguiente a su global.asax para la serialización JSON de c # enum como cadena

  HttpConfiguration config = GlobalConfiguration.Configuration;
            config.Formatters.JsonFormatter.SerializerSettings.Formatting =
                Newtonsoft.Json.Formatting.Indented;

            config.Formatters.JsonFormatter.SerializerSettings.Converters.Add
                (new Newtonsoft.Json.Converters.StringEnumConverter());

150
2017-08-09 18:06



@Iggy answer establece la serialización JSON de c # enum como una cadena solo para ASP.NET (Web API y demás).

Pero para hacer que funcione también con serialización ad hoc, agregue lo siguiente a su clase de inicio (como Global.asax Application_Start)

//convert Enums to Strings (instead of Integer) globally
JsonConvert.DefaultSettings = (() =>
{
    var settings = new JsonSerializerSettings();
    settings.Converters.Add(new StringEnumConverter { CamelCaseText = true });
    return settings;
});

Más información en la página Json.NET

Además, para hacer que su enumerador se serialice / deserialice a / desde un texto específico, use el

System.Runtime.Serialization.EnumMember

atributo, como este:

public enum time_zone_enum
{
    [EnumMember(Value = "Europe/London")] 
    EuropeLondon,

    [EnumMember(Value = "US/Alaska")] 
    USAlaska
}

99
2017-11-24 11:24



Esto se hace fácilmente agregando un ScriptIgnore atribuir a la Gender propiedad, haciendo que no se serialice, y agregando un GenderString propiedad que hace ser serializado:

class Person
{
    int Age { get; set; }

    [ScriptIgnore]
    Gender Gender { get; set; }

    string GenderString { get { return Gender.ToString(); } }
}

28
2018-03-15 17:38



No pude cambiar el modelo de origen como en la respuesta superior (de @ob.), Y no quería registrarlo globalmente como @Iggy. Así que combiné https://stackoverflow.com/a/2870420/237091 y @ Iggy's https://stackoverflow.com/a/18152942/237091 para permitir la configuración del convertidor enum de cadena activado durante el comando SerializeObject mismo:

Newtonsoft.Json.JsonConvert.SerializeObject(
    objectToSerialize, 
    Newtonsoft.Json.Formatting.None, 
    new Newtonsoft.Json.JsonSerializerSettings()
    {
        Converters = new List<Newtonsoft.Json.JsonConverter> {
            new Newtonsoft.Json.Converters.StringEnumConverter()
        }
    })

27
2017-12-18 16:39



Esta versión de Stephen responder no cambia el nombre en el JSON:

[DataContract(
    Namespace = 
       "http://schemas.datacontract.org/2004/07/Whatever")]
class Person
{
    [DataMember]
    int Age { get; set; }

    Gender Gender { get; set; }

    [DataMember(Name = "Gender")]
    string GenderString
    {
        get { return this.Gender.ToString(); }
        set 
        { 
            Gender g; 
            this.Gender = Enum.TryParse(value, true, out g) ? g : Gender.Male; 
        }
    }
}

26
2018-04-26 13:55



Aquí está la respuesta para newtonsoft.json

enum Gender { Male, Female }

class Person
{
    int Age { get; set; }

    [JsonConverter(typeof(StringEnumConverter))]
    Gender Gender { get; set; }
}

21
2018-04-21 09:47



Aquí hay una solución simple que serializa una enumeración de C # del lado del servidor a JSON y usa el resultado para poblar un lado del cliente <select> elemento. Esto funciona tanto para enumeraciones simples como para enumeraciones bitflag.

He incluido la solución de extremo a extremo porque creo que la mayoría de las personas que desean serializar una enumeración de C # a JSON también la utilizarán probablemente para llenar un <select> desplegable.

Aquí va:

Ejemplo Enum

public enum Role
{
    None = Permission.None,
    Guest = Permission.Browse,
    Reader = Permission.Browse| Permission.Help ,
    Manager = Permission.Browse | Permission.Help | Permission.Customise
}

Una enumeración compleja que utiliza OR de bit a bit para generar un sistema de permisos. Por lo tanto, no puede confiar en el índice simple [0,1,2 ..] para el valor entero de la enumeración.

Lado del servidor - C #

Get["/roles"] = _ =>
{
    var type = typeof(Role);
    var data = Enum
        .GetNames(type)
        .Select(name => new 
            {
                Id = (int)Enum.Parse(type, name), 
                Name = name 
            })
        .ToArray();

    return Response.AsJson(data);
};

El código anterior usa el marco de NancyFX para manejar la solicitud Get. Utiliza Nancy Response.AsJson() método de ayuda, pero no se preocupe, puede usar cualquier formateador JSON estándar ya que la enumeración ya se ha proyectado en un tipo simple anónimo listo para la serialización.

Generado JSON

[
    {"Id":0,"Name":"None"},
    {"Id":2097155,"Name":"Guest"},
    {"Id":2916367,"Name":"Reader"},
    {"Id":4186095,"Name":"Manager"}
]

Lado del cliente - CoffeeScript

fillSelect=(id, url, selectedValue=0)->
    $select = $ id
    $option = (item)-> $ "<option/>", 
        {
            value:"#{item.Id}"
            html:"#{item.Name}"
            selected:"selected" if item.Id is selectedValue
        }
    $.getJSON(url).done (data)->$option(item).appendTo $select for item in data

$ ->
    fillSelect "#role", "/roles", 2916367

HTML antes

<select id="role" name="role"></select>

HTML después

<select id="role" name="role">
    <option value="0">None</option>
    <option value="2097155">Guest</option>
    <option value="2916367" selected="selected">Reader</option>
    <option value="4186095">Manager</option>
</select>

13
2018-04-10 10:06



Puede crear JsonSerializerSettings con la llamada a JsonConverter.SerializeObject de la siguiente manera:

var result = JsonConvert.SerializeObject
            (
                dataObject,
                new JsonSerializerSettings
                {
                    Converters = new [] {new StringEnumConverter()}
                }
            );

11
2018-06-17 12:29