.NET - JSON-сериализация enum в виде строки - PullRequest
1017 голосов
/ 14 марта 2010

У меня есть класс, который содержит свойство enum, и после сериализации объекта с использованием JavaScriptSerializer мой результат json содержит целочисленное значение перечисления, а не его string "имя". Есть ли способ получить enum как string в моем json, не создавая пользовательский JavaScriptConverter? Возможно, есть атрибут, который я мог бы украсить определением enum, или свойством объекта, с помощью?

Как пример:

enum Gender { Male, Female }

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

Желаемый результат JSON:

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

Ответы [ 23 ]

1902 голосов
/ 20 мая 2010

Я обнаружил, что Json.NET обеспечивает именно ту функциональность, которую я ищу, с атрибутом StringEnumConverter:

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

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

Более подробная информация доступна на StringEnumConverter документации .

316 голосов
/ 14 марта 2010

Нет, нет специального атрибута, который вы можете использовать. JavaScriptSerializer сериализует enums в их числовые значения, а не в строковое представление. Вам потребуется использовать пользовательскую сериализацию для сериализации enum в качестве его имени вместо числового значения.

Edit: Как указано @OmerBakhari, JSON.net охватывает этот вариант использования (через атрибут [JsonConverter(typeof(StringEnumConverter))]) и многие другие, которые не обрабатываются встроенными сериализаторами .net. Вот ссылка, сравнивающая функции и возможности сериализаторов .

164 голосов
/ 09 августа 2013

Добавьте следующее в ваш global.asax для сериализации JSON c # enum в виде строки

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

            config.Formatters.JsonFormatter.SerializerSettings.Converters.Add
                (new Newtonsoft.Json.Converters.StringEnumConverter());
129 голосов
/ 24 ноября 2014

@ Игги ответ устанавливает JSON-сериализацию перечисления c # в виде строки только для ASP.NET (веб-API и т. Д.).

Но для того, чтобы это работало и со специальной сериализацией, добавьте следующее в ваш начальный класс (например, 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;
});

Дополнительная информация на странице Json.NET

Кроме того, чтобы ваш член enum мог сериализовать / десериализовать в / из определенного текста, используйте

System.Runtime.Serialization.EnumMember

Атрибут

, например:

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

    [EnumMember(Value = "US/Alaska")] 
    USAlaska
}
37 голосов
/ 18 декабря 2013

Мне не удалось изменить исходную модель, как в верхнем ответе (@ob.), И я не хотел регистрировать ее глобально, как @Iggy. Поэтому я объединил https://stackoverflow.com/a/2870420/237091 и @ Iggy's https://stackoverflow.com/a/18152942/237091, чтобы разрешить настройку преобразователя перечисления строк во время самой команды SerializeObject:

Newtonsoft.Json.JsonConvert.SerializeObject(
    objectToSerialize, 
    Newtonsoft.Json.Formatting.None, 
    new Newtonsoft.Json.JsonSerializerSettings()
    {
        Converters = new List<Newtonsoft.Json.JsonConverter> {
            new Newtonsoft.Json.Converters.StringEnumConverter()
        }
    })
31 голосов
/ 15 марта 2012

Это легко сделать, добавив атрибут ScriptIgnore к свойству Gender, исключив его сериализацию, и добавив свойство GenderString, которое делает get сериализованная:

class Person
{
    int Age { get; set; }

    [ScriptIgnore]
    Gender Gender { get; set; }

    string GenderString { get { return Gender.ToString(); } }
}
30 голосов
/ 16 августа 2017

Комбинация ответов Omer Bokhari и uri всегда является моим решением, поскольку значения, которые я хочу предоставить, обычно отличаются от того, что у меня есть в моем перечислении, особенно потому, что я хотел бы иметь возможность изменять свои перечисления, если мне нужно к.

Так что, если кому-то интересно, это примерно так:

public enum Gender
{
   [EnumMember(Value = "male")] 
   Male,
   [EnumMember(Value = "female")] 
   Female
}

class Person
{
    int Age { get; set; }
    [JsonConverter(typeof(StringEnumConverter))]
    Gender Gender { get; set; }
}
27 голосов
/ 26 апреля 2012

Эта версия ответа Стивена не меняет имя в 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; 
        }
    }
}
25 голосов
/ 21 апреля 2015

Вот ответ для newtonsoft.json

enum Gender { Male, Female }

class Person
{
    int Age { get; set; }

    [JsonConverter(typeof(StringEnumConverter))]
    Gender Gender { get; set; }
}
17 голосов
/ 19 июня 2018

ASP.NET Основной путь:

public class Startup
{
  public IServiceProvider ConfigureServices(IServiceCollection services)
  {
    services.AddMvc().AddJsonOptions(options =>
    {
      options.SerializerSettings.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
    });
  }
}

https://gist.github.com/regisdiogo/27f62ef83a804668eb0d9d0f63989e3e

...