JavaScriptSerializer - JSON серіалізація перерахунку як рядка


1160

У мене є клас, який містить enumвластивість, і після серіалізації об'єкта за допомогою JavaScriptSerializerмого результату json містить ціле значення перерахунку, а не його string"ім'я". Чи є спосіб отримати перерахунок як stringв моєму json, не створюючи користувальницький JavaScriptConverter? Можливо, є атрибут, з яким я міг би прикрасити enumвизначення чи властивість об’єкта?

Як приклад:

enum Gender { Male, Female }

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

Бажаний результат json:

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

Ідеально шукаю відповіді за допомогою вбудованих рамок .NET Framework, якщо не можливі альтернативи (наприклад, Json.net).


8
Зміна на яку? Відповідь з найбільш високою оцінкою насправді не відповідає на питання - так, це корисно в інших контекстах, отже, і голоси, але це практично не корисно, якщо ви застрягли з MS JavaScriptSerializer, оскільки, по суті, ви використовуєте методи сторінки та , головне, як того вимагає запитання. Прийнята відповідь говорить, що це неможливо. Моя відповідь в той час, як трохи зламає роботу.
Стівен Кеннеді

Відповіді:


376

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


Якщо ви можете використовувати JSON.Net замість того, JavaScriptSerializerщоб побачити відповідь на це запитання, надане OmerBakhari : JSON.net охоплює цей випадок використання (через атрибут [JsonConverter(typeof(StringEnumConverter))]) та багато інших, які не обробляються вбудованими серіалізаторами .net. Ось посилання, що порівнює особливості та функціональні можливості серіалізаторів .


7
@Fabzter - ваше рішення працювало зі мною, використовуючи Json
Newtonsoft

1
@BornToCode Json.NET - це серіалізатор, який ASP.NET використовує за замовчуванням.
BrainSlugs83

12
@ BrainSlugs83 - Питання стосувалося використання JavaScriptSerializer, а не Json.NET (і якщо ви подивитесь на історію редагувань, ви побачите, що для уточнення цього було редагування), якщо ви використовуєте JavaScriptSerializer, атрибут JsonConverterне працюватиме.
BornToCode

50
Будь ласка, видаліть це як прийняту відповідь, оскільки це не вирішує проблему, відповідь нижче - 1000+ оновлень.
MHGameWork

Ви могли б відповісти мені
Yongqiang Chen

2101

Я виявив, що Json.NET забезпечує точний функціонал, який я шукаю з StringEnumConverterатрибутом:

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

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

Більш детальна інформація доступна в StringEnumConverterдокументації .

Є й інші місця для налаштування цього перетворювача у більш глобальному масштабі:

  • enum себе, якщо ви хочете, щоб enum завжди був серіалізований / дезаріалізований як рядок:

    [JsonConverter(typeof(StringEnumConverter))]  
    enum Gender { Male, Female }
  • Якщо хтось хоче уникнути декорування атрибутів, ви можете додати перетворювач до свого JsonSerializer (запропонований Bjørn Egil ):

    serializer.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter()); 

    і він буде працювати для кожного перерахунку, який він побачить під час цієї серіалізації (запропонований Тревісом ).

  • або JsonConverter (пропонований бананом ):

    JsonConvert.SerializeObject(MyObject, 
        new Newtonsoft.Json.Converters.StringEnumConverter());

Крім того, ви можете керувати корпусом і чи все ще приймаються цифри за допомогою конструктора StringEnumConverter (NamingStrategy, Boolean) .


9
Перейдіть за посиланням для опису, як його використовувати в додатку asp.net mvc james.newtonking.com/archive/2008/10/16/…
RredCat

2
Ось посилання на цю функцію: james.newtonking.com/projects/json/help/html/…
CAD

61
HttpConfiguration config = GlobalConfiguration.Configuration; config.Formatters.JsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented; config.Formatters.JsonFormatter.SerializerSettings.Converters.Add (новий Newtonsoft.Json.Converters.StringEnumConverter ());
Іггі

1
Корисно зауважити, що за замовчуванням ASP.NET MVC не використовує Json.Net як серіалізатор json, і потрібно будь-яку розширювати Controllerабо вручну змінювати кожну серіалізацію.
Одіс

2
Ви можете налаштувати перетворювач (скажімо, для camelCaseвиведення):new StringEnumConverter { CamelCaseText = true }
Seafish

172

Додайте нижче до свого 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());

4
Я чомусь не змушую це працювати. Фіддлер показує впертість 2, а не «Попередження», навіть якщо це є на місці. Також - будь-яка причина, чому потрібно змінити Formattingна Indented?
sq33G

5
Третій рядок з цього прикладу був доданий до файлу App_start / webapiconfig.cs і зробив для мене фокус у проекті ASP.NET Web API 2.1, щоб повернути рядки для значень перерахувань у викликах REST (json fomat).
Грег З.

1
Чи є спосіб встановити це властивість лише за шкалою запиту?
Anestis Kivranoglou

@AnestisKivranoglou просто використовуйте користувальницький серіалізатор json за запитом із власними налаштуваннями.
BrainSlugs83

3
перша настройка серіалізатора з відступом не пов'язана з питанням op.
користувач3791372

153

@Iggy відповідь встановлює JSON серіалізацію c # enum як рядок лише для ASP.NET (Web 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
}

6
Дякую! Я просто шукав[EnumMember] .
Poulad

CamelCaseTextВластивість тепер позначається як застаріле. Новий спосіб інстанціювати перетворювач:new StringEnumConverter(new CamelCaseNamingStrategy())
fiat

Дуже дякую, зробили мій день! :)
Eldoïr

39

Я не зміг змінити модель джерела, як у верхній відповіді (@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()
        }
    })

це також дивовижно, якщо у вас є такий ресурс, як цей Список <someEnumType>
Богдан

34

Поєднання відповідей Омера Бохарі та відповіді Урі завжди є моїм рішенням, оскільки значення, які я хочу надати, зазвичай відрізняються від тих, що я маю в перерахунку, особливо, що я хотів би змінити свої перерахунки, якщо мені потрібно.

Тож якщо когось цікавить, це приблизно так:

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

class Person
{
    int Age { get; set; }
    [JsonConverter(typeof(StringEnumConverter))]
    Gender Gender { get; set; }
}

1
Я використовував JsonPropertyAttributeдля членів enum, і він працює для простих задач деріаріалізації. На жаль, під час ручних налаштувань з JTokens воно ігнорується. Гаппіллі EnumMemberAttributeпрацює як шарм. Дякую!
Пролог

Що працює з JavaScriptSerializer?
Стівен Кеннеді

31

Це легко зробити, додавши ScriptIgnoreатрибут до Genderвластивості, змусивши його не серіалізувати, і додавши GenderStringвластивість, яке дійсно серіалізується:

class Person
{
    int Age { get; set; }

    [ScriptIgnore]
    Gender Gender { get; set; }

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

29
Дозвольте спробувати пояснити. Це рішення не є правильним відповідно до дизайнерських робіт. Ви змінили модель відповідно до цілей перегляду. Але модель повинна містити лише дані і не хвилює презентацій. Ви повинні перемістити цю функціональність на інший шар.
RredCat

4
Власне, Модель використовується для передачі даних від контролера, а це контролер, який не дбає про презентацію. Введення автоматизованої властивості (GenderString тут) не порушує контролер, який все ще використовує властивість Gender, але забезпечує простий доступ для перегляду. Логічне рішення.
Діма

17
@RredCat Немає нічого поганого в наявності властивостей, характерних для перегляду, у "моделі перегляду". IMHO помилкою було б не розділяти модель перегляду від моделі домена: blogs.msdn.com/b/simonince/archive/2010/01/26/…
Mariano Desanze

5
@RredCat, навіть якщо це було невірно за якоюсь схемою, ОП нічого не говорить про це, тому це справді правильна відповідь. (Навіть якщо я по-філософськи можу погодитися з вашою точкою.)
ПАМ'ЯТЬ

10
Педантично абсурдні прокладки велосипедів у цій темі коментарів є захоплюючими.
Майк Муні

26

Ця версія Стівена відповіді не змінює ім'я в форматі 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; 
        }
    }
}

3
Я вважаю, що це справедливо для DataContractJsonSerializerнеJavaScriptSerializer
KCD

Проста і вирішує проблему для мене за допомогою нативних серіалізаторів .NET Framework.
Сенатор

найкраще рішення для мене, оскільки мені заборонено користуватися сторонніми бібліотеками (питання
дотримання

Звичайно, це не для типу серіалізатора. JavaScriptSerializer серіалізує все, що не ігнорується, тоді як DataContractJsonSerializer вимагає атрибутів DataMember. Дякую за крик, але зауважте, що ви неправильно написали моє ім'я :)
Стівен Кеннеді

25

Ось відповідь для newtonsoft.json

enum Gender { Male, Female }

class Person
{
    int Age { get; set; }

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

1
Дякую за цю відповідь, мені дуже допомогли! Якщо ви хочете визначити ваших переліків у PascalCase, але ви хочете, щоб вони були серіалізовані у camelCase, тоді вам потрібно додати trueдо свого типу JsonConverter, як це:[JsonConverter(typeof(StringEnumConverter), true)]
Peet


16

Ви також можете додати конвертер до свого, JsonSerializerякщо ви не хочете використовувати JsonConverterатрибут:

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

Він працюватиме для кожного, що enumвін бачить під час серіалізації.


15

Ось просте рішення, яке серіалізує C # enum на стороні сервера до JSON і використовує результат для заселення клієнтської сторони <select> елемента. Це працює як для простих, так і для бітфлагів.

Я включив цільове рішення, тому що я думаю, що більшість людей, які хочуть серіалізувати C # перерахунок до JSON, також, ймовірно, будуть використовувати його для заповнення <select> спадного меню.

Ось:

Приклад Enum

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

Складний перелік, який використовує побітові АБО для створення системи дозволів. Таким чином, ви не можете покластися на простий індекс [0,1,2 ..] для цілого значення перерахунку.

Сторона сервера - 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);
};

У наведеному вище коді використовується рамка NancyFX для обробки запиту Get. Він використовує НенсіResponse.AsJson() допоміжний метод - але не хвилюйтеся, ви можете використовувати будь-який стандартний форматник JSON, оскільки перерахунок вже спроектований у простий анонімний тип, готовий до серіалізації.

Створений JSON

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

Сторона клієнта - 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 раніше

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

HTML Після

<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

Для ядра ASP.Net Просто додайте наступне до класу запуску:

JsonConvert.DefaultSettings = (() =>
        {
            var settings = new JsonSerializerSettings();
            settings.Converters.Add(new StringEnumConverter { AllowIntegerValues = false });
            return settings;
        });

1
Це працює для всіх версій, а не лише для основних.
bikeman868

11

Ви можете створити JsonSerializerSettings з викликом JsonConverter.SerializeObject, як показано нижче:

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

10

Помітив, що немає відповіді на серіалізацію, коли є атрибут Description.

Ось моя реалізація, яка підтримує атрибут Description.

public class CustomStringEnumConverter : Newtonsoft.Json.Converters.StringEnumConverter
{
    public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
    {
        Type type = value.GetType() as Type;

        if (!type.IsEnum) throw new InvalidOperationException("Only type Enum is supported");
        foreach (var field in type.GetFields())
        {
            if (field.Name == value.ToString())
            {
                var attribute = Attribute.GetCustomAttribute(field, typeof(DescriptionAttribute)) as DescriptionAttribute;
                writer.WriteValue(attribute != null ? attribute.Description : field.Name);

                return;
            }
        }

        throw new ArgumentException("Enum not found");
    }
}

Enum:

public enum FooEnum
{
    // Will be serialized as "Not Applicable"
    [Description("Not Applicable")]
    NotApplicable,

    // Will be serialized as "Applicable"
    Applicable
}

Використання:

[JsonConverter(typeof(CustomStringEnumConverter))]
public FooEnum test { get; set; }

10

Для .Net Core: -

public void ConfigureServices(IServiceCollection services)
{
    ...
    services.AddJsonFormatters(f => f.Converters.Add(new StringEnumConverter()));
    ...
}

2
Якщо це Microsoft.AspNetCore.Mvc.Formatters.Jsonпакет із пакета NuGet, він, здається, є лише методом розширення IMvcCoreBuilder, а не IMvcBuilder. Так воно використовується як services.AddMvcCore().AddJsonFormatters(f => f.Converters.Add(new StringEnumConverter()));.
infl3x

9

У ядрі .net 3 тепер це можливо завдяки вбудованим класам у System.Text.Json:

var person = new Person();
// Create and add a converter which will use the string representation instead of the numeric value.
var stringEnumConverter = new System.Text.Json.Serialization.JsonStringEnumConverter();
JsonSerializerOptions opts = new JsonSerializerOptions();
opts.Converters.Add(stringEnumConverter);
// Generate json string.
var json = JsonSerializer.Serialize<Person>(person, opts);

Щоб настроїти JsonStringEnumConverterдекор атрибутів для конкретного властивості:

using System.Text.Json.Serialization;

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

Якщо ви хочете завжди перетворювати enum як рядок, помістіть атрибут у самому enum.

[JsonConverter(typeof(JsonStringEnumConverter))] 
enum Gender { Male, Female }

9

Asp.Net Core 3 з System.Text.Json

public void ConfigureServices(IServiceCollection services)
{

    services
        .AddControllers()
        .AddJsonOptions(options => 
           options.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter())
        );

    //...
 }

8

На всякий випадок, якщо хтось вважає, що вищезазначене є недостатнім, я закінчився з цим перевантаженням:

JsonConvert.SerializeObject(objToSerialize, Formatting.Indented, new Newtonsoft.Json.Converters.StringEnumConverter())

Це хороше рішення для мого поточного випадку використання: я не хочу змінювати типові параметри серіалізаторів, і у мене є проблеми з використанням атрибутів, оскільки мої властивості мають тип IList <EnumType>.
Дірк

5

Це давнє питання, але я подумав, що буду робити внесок у будь-якому випадку. У своїх проектах я використовую окремі моделі для будь-яких запитів Json. Модель зазвичай має те саме ім’я, що і доменний об’єкт з префіксом "Json". Моделі відображаються за допомогою AutoMapper . Маючи модель json оголосити властивість рядка, яка є перерахунком доменного класу, AutoMapper вирішить подати рядок.

У випадку, якщо вам цікаво, мені потрібні окремі моделі для серіалізованих класів Json, тому що вбудований серіалізатор в іншому випадку пропонує кругові посилання.

Сподіваюся, що це комусь допоможе.


Приємно дізнатися, що функція атрибута Automapper ;-) [ScriptIgnore] видалить кругові посилання
ledragon

1
Ой. Не знав про атрибут. Дякую! Чи використовуєте ви це на Pocos? Я вдався до використання визначень MetadataType для будь-яких атрибутів Poco лише для того, щоб вони були чистими. Чи все-таки атрибут працюватиме за допомогою метаданих?
Алесь Поточник Гахоніна

3

Ви можете фактично використовувати JavaScriptConverter, щоб досягти цього за допомогою вбудованого JavaScriptSerializer. Перетворивши перерахунок на Uri, ви можете кодувати його як рядок.

Я описав, як це зробити для побачень, але це можна використовувати і для перерахунків. Спеціальний формат JSON DateTime для .NET JavaScriptSerializer .


Дуже цікаве рішення! Дякую, що поділились.
Олівер

1

Не впевнений, чи це все-таки актуально, але мені довелося писати прямо у файл json, і я придумав наступне визначення кількох відповідей stackoverflow разом

public class LowercaseJsonSerializer
{
    private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
    {
        ContractResolver = new LowercaseContractResolver()
    };

    public static void Serialize(TextWriter file, object o)
    {
        JsonSerializer serializer = new JsonSerializer()
        {
            ContractResolver = new LowercaseContractResolver(),
            Formatting = Formatting.Indented,
            NullValueHandling = NullValueHandling.Ignore
        };
        serializer.Converters.Add(new Newtonsoft.Json.Converters.StringEnumConverter());
        serializer.Serialize(file, o);
    }

    public class LowercaseContractResolver : DefaultContractResolver
    {
        protected override string ResolvePropertyName(string propertyName)
        {
            return Char.ToLowerInvariant(propertyName[0]) + propertyName.Substring(1);
        }
    }
}

Це запевняє, що всі мої клавіші json - це малі літери, починаючи з "правил" json. Форматує його з чітким відступом і ігнорує нулі у висновку. Aslo, додавши StringEnumConverter, він друкує перерахунки з їх значенням рядка.

Особисто я вважаю це найчистішим, що я міг придумати, не маючи брудної моделі анотаціями.

використання:

    internal void SaveJson(string fileName)
    {
        // serialize JSON directly to a file
        using (StreamWriter file = File.CreateText(@fileName))
        {
            LowercaseJsonSerializer.Serialize(file, jsonobject);
        }
    }

0

Я зібрав усі фрагменти цього рішення, використовуючи Newtonsoft.Jsonбібліотеку. Він виправляє проблему перерахунків, а також робить обробку помилок значно кращою, і вона працює в розміщених службах IIS. Коду досить багато, тому його можна знайти на GitHub тут: https://github.com/jongrant/wcfjsonserializer/blob/master/NewtonsoftJsonFormatter.cs

Ви повинні додати деякі записи до свого, Web.configщоб змусити його працювати, ви можете побачити приклад файлу тут: https://github.com/jongrant/wcfjsonserializer/blob/master/Web.config


0

А для VB.net я знайшов такі роботи:

Dim sec = New Newtonsoft.Json.Converters.StringEnumConverter()
sec.NamingStrategy() = New Serialization.CamelCaseNamingStrategy

Dim JSON_s As New JsonSerializer
JSON_s.Converters.Add(sec)

Dim jsonObject As JObject
jsonObject = JObject.FromObject(SomeObject, JSON_s)
Dim text = jsonObject.ToString

IO.File.WriteAllText(filePath, text)

0

Трохи більш надійний варіант

Зіткнувшись з тим же запитом, ми визначили, що нам потрібна спеціальна версія, StringEnumConverterщоб переконатися, що наші значення перерахунку можуть розширюватися з часом, не руйнуючись катастрофічно на стороні десеріалізації (див. Фон нижче). ВикористанняSafeEnumConverter наведеного нижче дає змогу завершити десяріалізацію, навіть якщо корисне навантаження містить значення для перерахунку, яке не має іменного визначення, ближче до того, як працюватиме перетворення int-enum.

Використання:

[SafeEnumConverter]
public enum Colors
{
    Red,
    Green,
    Blue,
    Unsupported = -1
}

або

[SafeEnumConverter((int) Colors.Blue)]
public enum Colors
{
    Red,
    Green,
    Blue
}

Джерело:

public class SafeEnumConverter : StringEnumConverter
{
    private readonly int _defaultValue;

    public SafeEnumConverter()
    {
        // if you've been careful to *always* create enums with `0` reserved
        // as an unknown/default value (which you should), you could use 0 here. 
        _defaultValue = -1;
    }

    public SafeEnumConverter(int defaultValue)
    {
        _defaultValue = defaultValue;
    }

    /// <summary>
    /// Reads the provided JSON and attempts to convert using StringEnumConverter. If that fails set the value to the default value.
    /// </summary>
    /// <returns>The deserialized value of the enum if it exists or the default value if it does not.</returns>
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        try
        {
            return base.ReadJson(reader, objectType, existingValue, serializer);
        }
        catch
        {
            return Enum.Parse(objectType, $"{_defaultValue}");
        }
    }

    public override bool CanConvert(Type objectType)
    {
        return base.CanConvert(objectType) && objectType.GetTypeInfo().IsEnum;
    }
}

Фон

Коли ми розглядали питання використання StringEnumConverter, проблема, яка була у нас, полягає в тому, що нам також потрібна пасивність у випадках, коли було додано нове значення перерахунку, але не кожен клієнт одразу усвідомлював нову цінність. У цих випадках StringEnumConverterупакований з Newtonsoft JSON видає JsonSerializationExceptionаналогічний "Помилка перетворення значення SomeString для введення EnumType", і тоді весь процес десеріалізації виходить з ладу. Це було для нас розривом угоди, тому що навіть якщо клієнт планував ігнорувати / відкидати вартість властивості, яку він не розумів, він все одно повинен бути здатний десаріалізувати решту корисного навантаження!


-2
        Person p = new Person();
        p.Age = 35;
        p.Gender = Gender.Male;
        //1.  male="Male";
        string male = Gender.Male.ToString();

        p.Gender = Gender.Female;

        //2.  female="Female";
        string female = Enum.GetName(typeof(Gender), p.Gender);

        JObject jobj = new JObject();
        jobj["Age"] = p.Age;
        jobj["Gender"] = male;
        jobj["Gender2"] = female;

        //you result:  josn= {"Age": 35,"Gender": "Male","Gender2": "Female"}
        string json = jobj.ToString();

-5
new JavaScriptSerializer().Serialize(  
    (from p   
    in (new List<Person>() {  
        new Person()  
        {  
            Age = 35,  
            Gender = Gender.Male  
        }  
    })  
    select new { Age =p.Age, Gender=p.Gender.ToString() }  
    ).ToArray()[0]  
);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.