Pertanyaan .NET - serialisasi JSON enum sebagai string


Saya memiliki kelas yang berisi sebuah enum properti, dan setelah serialisasi objek menggunakan JavaScriptSerializer, hasil json saya berisi nilai integer dari enumerasi daripada string "nama". Apakah ada cara untuk mendapatkan enum sebagai string di json saya tanpa harus membuat kebiasaan JavaScriptConverter? Mungkin ada atribut yang bisa saya hiasi enum definisi, atau properti objek, dengan?

Sebagai contoh:

enum Gender { Male, Female }

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

Hasil json yang diinginkan:

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

852
2018-03-14 05:18


asal


Jawaban:


Tidak ada atribut khusus yang dapat Anda gunakan. JavaScriptSerializer serializes enums ke nilai numerik mereka dan bukan representasi string mereka. Anda akan perlu menggunakan serialisasi kustom untuk cerita bersambung enum sebagai namanya, bukan nilai numerik.

Edit: Sebagaimana ditunjukkan oleh @OmerBakhari JSON.net mencakup kasus penggunaan ini (melalui atribut [JsonConverter(typeof(StringEnumConverter))]) dan banyak lainnya tidak ditangani oleh built in .net serializers. Berikut ini adalah tautan yang membandingkan fitur dan fungsionalitas dari serializers.


204
2018-03-14 06:21



Saya telah menemukan itu Json.NET menyediakan fungsionalitas yang tepat yang saya cari dengan StringEnumConverter atribut:

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

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

Detail lebih lanjut tersedia di StringEnumConverter dokumentasi.


1656
2018-05-20 00:58



Tambahkan di bawah ini ke global.asax Anda untuk serialisasi JSON dari c # enum sebagai string

  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 menetapkan serialisasi JSON dari c # enum sebagai string hanya untuk ASP.NET (Web API dan sebagainya).

Tetapi untuk membuatnya bekerja juga dengan serialisasi ad hoc, tambahkan berikut ke kelas awal Anda (seperti 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;
});

Informasi lebih lanjut di halaman Json.NET

Selain itu, agar anggota enum Anda membuat serialisasi / deserialize ke / dari teks tertentu, gunakan

System.Runtime.Serialization.EnumMember

atribut, seperti ini:

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

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

99
2017-11-24 11:24



Ini mudah dilakukan dengan menambahkan ScriptIgnore atribut ke Gender properti, menyebabkannya tidak diserialkan, dan menambahkan a GenderString properti yang tidak dapatkan serial:

class Person
{
    int Age { get; set; }

    [ScriptIgnore]
    Gender Gender { get; set; }

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

28
2018-03-15 17:38



Saya tidak dapat mengubah model sumber seperti di jawaban teratas (dari @ob.), Dan saya tidak ingin mendaftarkannya secara global seperti @Iggy. Jadi saya bergabung https://stackoverflow.com/a/2870420/237091 dan @ Iggy's https://stackoverflow.com/a/18152942/237091 untuk memungkinkan pengaturan konverter enum string pada saat perintah SerializeObject itu sendiri:

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



Versi Stefanus ini menjawab tidak mengubah nama di 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



Inilah jawaban untuk 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



Berikut ini adalah solusi sederhana yang berstandar C-server sisi-sisi ke JSON dan menggunakan hasilnya untuk mengisi sisi-klien <select> elemen. Ini berfungsi baik untuk enum sederhana dan enum bitflag.

Saya telah menyertakan solusi end-to-end karena saya pikir kebanyakan orang yang ingin membuat serial C # enum ke JSON juga mungkin akan menggunakannya untuk mengisi <select> tarik-turun.

Di sini:

Contoh Enum

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

Enum kompleks yang menggunakan OR bitwise untuk menghasilkan sistem perizinan. Jadi Anda tidak bisa mengandalkan indeks sederhana [0,1,2 ..] untuk nilai integer enum.

Sisi Server - 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);
};

Kode di atas menggunakan kerangka NancyFX untuk menangani permintaan Dapatkan. Itu menggunakan milik Nancy Response.AsJson() Metode pembantu - tetapi jangan khawatir, Anda dapat menggunakan format JSON standar apa pun karena enum telah diproyeksikan menjadi tipe anonim sederhana yang siap untuk serialisasi.

Generated JSON

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

Sisi Klien - 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 Sebelumnya

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

HTML Setelah

<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



Anda dapat membuat JsonSerializerSettings dengan panggilan ke JsonConverter.SerializeObject seperti di bawah ini:

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

11
2018-06-17 12:29



Anda juga dapat menambahkan konverter ke Anda JsonSerializer jika kamu tidak ingin menggunakannya JsonConverter atribut:

string SerializedResponse = JsonConvert.SerializeObject(
     objToSerialize, 
     new Newtonsoft.Json.Converters.StringEnumConverter()
); 

Ini akan bekerja untuk setiap orang enum itu melihat selama serialisasi itu.


9
2018-04-05 11:15