Frage .NET - JSON Serialisierung von Enum als String


Ich habe eine Klasse, die ein enthält enum Eigenschaft und beim Serialisieren des Objekts mit JavaScriptSerializer, mein json-Ergebnis enthält den Integer-Wert der Enumeration statt dessen string "Name". Gibt es einen Weg, das Enum als ein zu bekommen? string in meinem JSON, ohne einen Brauch zu erstellen JavaScriptConverter? Vielleicht gibt es ein Attribut, das ich dekorieren könnte enum Definition oder Objekteigenschaft mit?

Als Beispiel:

enum Gender { Male, Female }

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

Gewünschtes JSon-Ergebnis:

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

852
2018-03-14 05:18


Ursprung


Antworten:


Nein, es gibt kein spezielles Attribut, das Sie verwenden können. JavaScriptSerializer serialisiert enums auf ihre numerischen Werte und nicht auf ihre Zeichenfolgendarstellung. Sie müssten die benutzerdefinierte Serialisierung zum Serialisieren des enum als sein Name anstelle von numerischen Wert.

Bearbeiten: Wie von @OmerBakhari gezeigt, behandelt JSON.net diesen Anwendungsfall (über das Attribut [JsonConverter(typeof(StringEnumConverter))]) und viele andere, die nicht von den eingebauten .net-Serialisierern verarbeitet werden. Hier finden Sie einen Link zum Vergleich der Funktionen und Funktionen der Serialisierer.


204
2018-03-14 06:21



Ich habe das gefunden Json.NET bietet die genaue Funktionalität, nach der ich suche StringEnumConverter Attribut:

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

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

Weitere Details unter verfügbar auf StringEnumConverter Dokumentation.


1656
2018-05-20 00:58



Fügen Sie das Folgende zu Ihrer global.asax für die JSON-Serialisierung von c # enum als Zeichenfolge hinzu

  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 antwort legt JSON-Serialisierung von c # enum als Zeichenfolge nur für ASP.NET (Web-API usw.) fest.

Damit es auch mit Ad-hoc-Serialisierung funktioniert, fügen Sie Ihrer Startklasse Folgendes hinzu (wie 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;
});

Mehr Informationen auf der Json.NET-Seite

Wenn Sie Ihr Enum - Mitglied serialisieren / deserialisieren möchten, verwenden Sie das

System.Runtime.Serialization.EnumMember

Attribut wie folgt:

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

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

99
2017-11-24 11:24



Dies ist leicht durch Hinzufügen eines ScriptIgnore Attribut an die Gender Eigenschaft, wodurch es nicht serialisiert wird, und Hinzufügen eines GenderString Eigenschaft, die tut serialisiert bekommen:

class Person
{
    int Age { get; set; }

    [ScriptIgnore]
    Gender Gender { get; set; }

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

28
2018-03-15 17:38



Ich konnte das Quellmodell nicht wie in der obersten Antwort (von @ob.) Ändern, und ich wollte es nicht global wie @Iggy registrieren. Also habe ich kombiniert https://stackoverflow.com/a/2870420/237091 und @ Iggy https://stackoverflow.com/a/18152942/237091 um zu ermöglichen, den String-Enum-Konverter während des Befehls SerializeObject selbst zu aktivieren:

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



Diese Version von Stephens Antworten ändert den Namen in JSON nicht:

[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



Hier ist die Antwort für 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



Hier ist eine einfache Lösung, die eine serverseitige C # -Enumerierung zu JSON serialisiert und das Ergebnis verwendet, um eine Clientseite aufzufüllen <select> Element. Dies funktioniert sowohl für einfache Enums als auch für Bitflag-Enums.

Ich habe die Ende-zu-Ende-Lösung aufgenommen, weil ich denke, dass die meisten Leute, die ein C # -Enumerium zu JSON serialisieren wollen, es wahrscheinlich auch verwenden werden, um ein <select> Dropdown-Liste.

Hier geht:

Beispiel Enum

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

Eine komplexe Enumeration, die bitweise ORs verwendet, um ein Berechtigungssystem zu generieren. Man kann sich also nicht auf den einfachen Index [0,1,2 ..] für den Integer-Wert der Enumeration verlassen.

Serverseite - 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);
};

Der obige Code verwendet das NancyFX-Framework, um die Get-Anforderung zu verarbeiten. Es benutzt Nancys Response.AsJson() Hilfsmethode - aber keine Sorge, Sie können jeden Standard-JSON-Formatierer verwenden, da die Aufzählung bereits in einen einfachen anonymen Typ für die Serialisierung projiziert wurde.

Generierte JSON

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

Clientseite - 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 vorher

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

HTML nach

<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



Sie können JsonSerializerSettings mit dem Aufruf von JsonConverter.SerializeObject wie folgt erstellen:

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

11
2018-06-17 12:29