JavaScriptSerializer - enum'un dize olarak JSON serileştirmesi


1161

Bir enumözellik içeren bir sınıf var ve nesneyi kullanarak seri hale getirme JavaScriptSerializer, benim json sonucu numaralandırma string"adı" yerine tamsayı değeri içerir . stringBir özel oluşturmak zorunda kalmadan benim json olarak bir numaralandırma almak için bir yolu var mı JavaScriptConverter? Belki enumtanımı veya nesne özelliğini dekore edebileceğim bir özellik var mı?

Örnek olarak:

enum Gender { Male, Female }

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

İstenen json sonucu:

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

İdeal olarak yerleşik .NET framework sınıflarıyla cevap aramak, mümkün değilse alternatifler (Json.net gibi) açıktır.


8
Hangisine değiştirilsin? En yüksek oylanan cevap aslında soruyu cevaplamıyor - evet, diğer bağlamlarda, dolayısıyla oylarda yararlıdır, ancak MS JavaScriptSerializer ile sıkışıp kalırsanız pratik olarak kullanılamaz, çünkü sayfa yöntemlerini ve , en önemlisi, sorunun gerektirdiği şekilde. Kabul edilen cevap mümkün olmadığını söylüyor. Cevabım biraz hacklenirken işimi hallederim.
Stephen Kennedy

Yanıtlar:


376

Hayır, kullanabileceğiniz özel bir özellik yoktur. dizgi gösterimleri yerine sayısal değerlerine JavaScriptSerializerserileştirir enums. enumSayısal değer yerine adını serileştirmek için özel serileştirme kullanmanız gerekir .


Eğer Json.NET yerine kullanabiliyorsa JavaScriptSerializerdaha bkz bu sorusuna da cevap tarafından sağlanan OmerBakhari : JSON.net Bu kullanım (özelliğiyle durum kapak [JsonConverter(typeof(StringEnumConverter))]) ve .net serileştiriciler inşa tarafından işlenmez diğerleri. Serileştiricilerin özelliklerini ve işlevlerini karşılaştıran bir bağlantı .


7
@Fabzter - çözümünüz Newtonsoft'tan Json'u kullanarak benimle çalıştı
BeemerGuy

1
@BornToCode Json.NET, ASP.NET'in varsayılan olarak kullandığı serileştiricidir.
BrainSlugs83

12
@ BrainSlugs83 - Soru Json.NET değil, JavaScriptSerializer'ı kullanmakla ilgiliydi (ve revizyon geçmişine bakarsanız, bunu açıklığa kavuşturmak için bir düzenleme olduğunu görürsünüz), JavaScriptSerializer'ı kullanırsanız özellik JsonConverterçalışmaz.
BornToCode

50
Lütfen sorunu çözmediği için kabul edilen cevap olarak kaldırın, 1000'den fazla upvotes ile aşağıdaki cevap yapar.
MHGameWork

u beni rahatsız edebilir
Yongqiang Chen

2101

Json.NET bir StringEnumConverteröznitelik ile aradığım tam işlevsellik sağlar bulduk :

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

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

StringEnumConverterDokümanlarda daha fazla bilgi bulabilirsiniz .

Bu dönüştürücüyü daha global olarak yapılandırmak için başka yerler var:

  • enum'un her zaman dize olarak serileştirilmesini / serileştirilmesini istiyorsanız enum'un kendisi:

    [JsonConverter(typeof(StringEnumConverter))]  
    enum Gender { Male, Female }
  • Herhangi bir kişinin nitelik dekorasyonundan kaçınmak istemesi durumunda, dönüştürücüyü JsonSerializer'ınıza ekleyebilirsiniz ( Bjørn Egil tarafından önerilir ):

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

    ve bu serileştirme sırasında gördüğü her numaralandırma için çalışır ( Travis tarafından önerilir ).

  • veya JsonConverter ( muz tarafından önerilir ):

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

Ayrıca , StringEnumConverter (NamingStrategy, Boolean) yapıcısını kullanarak kasaları ve sayıların hala kabul edilip edilmediğini denetleyebilirsiniz .


9
Asp.net mvc uygulamasında nasıl kullanılacağı hakkında açıklama için bağlantıyı takip edin james.newtonking.com/archive/2008/10/16/…
RredCat 29:10


61
HttpConfiguration config = GlobalConfiguration.Configuration; config.Formatters.JsonFormatter.SerializerSettings.Formatting = Newtonsoft.Json.Formatting.Indented; config.Formatters.JsonFormatter.SerializerSettings.Converters.Add (yeni Newtonsoft.Json.Converters.StringEnumConverter ());
Iggy

1
ASP.NET MVC varsayılan olarak Json.Net'i json serileştirici olarak kullanmaz ve Controllerher serileştirmeyi genişletmek veya el ile geçersiz kılmak gerektiğine dikkat etmek yararlıdır .
Odys

2
Sen (için, diyelim dönüştürücü özelleştirebilirsiniz camelCaseçıkışı):new StringEnumConverter { CamelCaseText = true }
SEAFISH

172

Aşağıdakileri c # enum'un JSON serileştirmesi için global.asax dizenize ekleyin

  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
Bazı nedenlerden dolayı, bunun işe yaramadığını düşünüyorum. Fiddler, yerinde olsa bile, 'Uyarı' yerine inatçı bir 2 gösterir. Ayrıca - herhangi bir neden değiştirmek Formattingiçin Indented?
sq33G

5
Bu örnekten üçüncü satır App_start / webapiconfig.cs dosyasına eklendi ve ASP.NET Web API 2.1 projesinde benim için bir numara yaptı.
Greg Z.

1
Bu özelliği yalnızca İstek Kapsamı'na göre ayarlamanın bir yolu var mı?
Anestis Kivranoglou

@AnestisKivranoglou sadece kendi ayarları ile istek başına özel bir json serileştirici kullanın.
BrainSlugs83

3
girintili olan ilk serileştirici ayarı op sorusuyla ilgisizdir.
user3791372

153

@Iggy cevap c # enum JSON serileştirme yalnızca ASP.NET (Web API ve benzeri) için dize olarak ayarlar.

Ancak geçici serileştirmeyle de çalışması için başlangıç ​​sınıfınıza aşağıdakileri ekleyin (Global.asax Application_Start gibi)

//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 sayfası hakkında daha fazla bilgi

Ayrıca, enum üyenizin belirli bir metne serileştirilmesini / metinden serileştirilmesini sağlamak için

System.Runtime.Serialization.EnumMember

öznitelik, şöyle:

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

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

6
Teşekkür ederim! Sadece arıyordum [EnumMember].
Poulad

Tesis CamelCaseTextartık kullanılmıyor olarak işaretlendi. Dönüştürücüyü başlatmanın yeni yolu:new StringEnumConverter(new CamelCaseNamingStrategy())
fiat

Çok teşekkür ederim, benim günümü yaptı! :)
Eldoïr

39

Kaynak modeli üst yanıtta (@ob.) Olduğu gibi değiştiremedim ve küresel olarak @Iggy gibi kaydetmek istemedim. Kombine Ben So https://stackoverflow.com/a/2870420/237091 ve @ Iggy'nın https://stackoverflow.com/a/18152942/237091 SerializeObject komutu kendisi sırasında Dize sıralaması dönüştürücü kurma izin vermek:

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

Liste gibi <someEnumType>
Bogdan

34

Ömer Bokhari ve uri'nin cevaplarının kombinasyonu her zaman benim çözümümdür, çünkü sağlamak istediğim değerler genellikle numaramda olanlardan genellikle gerektiğinde enum'larımı değiştirmek istediğimden farklı.

Yani kimse ilgileniyorsa, şöyle bir şeydir:

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
JsonPropertyAttributeNumaralandırma üyeleri için kullanıyordum ve basit serileştirme görevleri için çalışıyor. Ne yazık ki, JTokens ile manuel ayarlar sırasında göz ardı edilir. Happilly EnumMemberAttributebir cazibe gibi çalışır. Teşekkürler!
Prolog

İle çalışır JavaScriptSerializer?
Stephen Kennedy

31

Bu kolayca ekleyerek yapılır ScriptIgnoreiçin niteliği Gendero getirilemez neden, mülk ve bir ekleme GenderStringözelliği yok tefrika olsun:

class Person
{
    int Age { get; set; }

    [ScriptIgnore]
    Gender Gender { get; set; }

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

29
Anlatmaya çalışayım. Tasarım çözümlerine göre bu çözüm doğru değildir. Modeli görüntüleme amacına göre değiştirdiniz. Ancak modelin yalnızca veri içermesi gerekir ve sunumlarla ilgilenmez. Bu işlevi diğer katmana taşımalısınız.
RredCat

4
Aslında, Model denetleyiciden veri aktarmak için kullanılır, karınca sunumla ilgilenmeyen denetleyicidir. Otomatik mülkün (GenderString burada) tanıtılması, yine de Cinsiyet özelliğini kullanan denetleyiciyi bozmaz, ancak bir görünüm için kolay erişim sağlar. Mantıksal çözüm.
Dima

17
@RredCat "Görünüm modelinde" görünüme özgü özelliklere sahip olmanın yanlış bir yanı yoktur. IMHO hata, görünüm modelini alan modelinden ayırmamak olacaktır
Mariano Desanze

5
@ RedCat, bazı modellere göre yanlış olsa bile, OP bu konuda hiçbir şey söylemez, bu yüzden bu doğru bir cevaptır. (Felsefi açıdan senin
fikrinle

10
Bu yorum dizisindeki bilgiçlikle saçma bisiklet dökülmeleri büyüleyici.
Mike Mooney

26

Stephen'ın cevabının bu sürümü JSON'daki adı değiştirmiyor:

[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
Ben bunun için geçerli DataContractJsonSerializerolmadığına inanıyorumJavaScriptSerializer
KCD

Basit ve yerel .NET framework serileştiricileri kullanarak benim için sorunu çözer.
Senatör

parti kütüphanelerini kullanmama izin verilmediği için benim için en iyi çözüm (ISO uyumluluğu sorunları)
Daniel Gruszczyk

Bu elbette söz konusu serileştiricinin türü için değil. JavaScriptSerializer, yok sayılmayan her şeyi serileştirirken DataContractJsonSerializer, DataMember öznitelikleri gerektirir. Haykırış için teşekkürler ama lütfen adımı yanlış yazdığınızı unutmayın :)
Stephen Kennedy

25

İşte newtonsoft.json için cevap

enum Gender { Male, Female }

class Person
{
    int Age { get; set; }

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

1
Bu cevap için teşekkür ederim, bana çok yardımcı oldu! Eğer enCum'larınızı PascalCase'de tanımlamak istiyorsanız, ancak camelCase'de serileştirilmesini istiyorsanız, JsonConverter tipinize şu şekilde eklemeniz gerekir true:[JsonConverter(typeof(StringEnumConverter), true)]
Peet


16

Özellik JsonSerializerkullanmak istemiyorsanız, cihazınıza bir dönüştürücü de ekleyebilirsiniz JsonConverter:

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

Bu enumserileştirme sırasında gördüğü her şey için çalışacaktır .


15

Burada, sunucu tarafı C # numaralandırmasını JSON'a serileştiren ve sonucu istemci tarafı <select>öğeyi doldurmak için kullanan basit bir çözüm var . Bu hem basit sıralamalar hem de bitflag sıralamaları için çalışır.

JSON için bir C # enumize serileştirmek isteyen çoğu insan da muhtemelen bir <select>açılır listeyi doldurmak için kullanacağını düşünüyorum çünkü uçtan uca çözüm dahil .

İşte gidiyor:

Örnek Numaralandırma

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

Bir izin sistemi oluşturmak için bitsel OR'leri kullanan karmaşık bir numaralandırma. Böylece, sayının tamsayı değeri için basit dizine [0,1,2 ..] güvenemezsiniz.

Sunucu Tarafı - 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);
};

Yukarıdaki kod, Get isteğini işlemek için NancyFX çerçevesini kullanır. Nancy'nin Response.AsJson()yardımcı yöntemini kullanır - ancak endişelenmeyin, enum zaten serileştirmeye hazır basit bir anonim türe yansıtıldığı için herhangi bir standart JSON formatlayıcıyı kullanabilirsiniz.

Oluşturulan JSON

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

İstemci Tarafı - 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

Önce HTML

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

Sonra 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 çekirdeği için Başlangıç ​​Sınıfınıza aşağıdakileri eklemeniz yeterlidir:

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

1
Bu, yalnızca çekirdek için değil, tüm sürümler için geçerlidir.
bikeman868

11

JsonSerializerSettings'i JsonConverter.SerializeObject çağrısıyla aşağıdaki gibi oluşturabilirsiniz:

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

10

Açıklama özniteliği olduğunda serileştirme için bir yanıt olmadığını fark ettim.

İşte Description özniteliğini destekleyen benim uygulama.

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

Sıralama:

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

    // Will be serialized as "Applicable"
    Applicable
}

Kullanımı:

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

10

Net Core için: -

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

2
Bu Microsoft.AspNetCore.Mvc.Formatters.JsonNuGet paketindeyse, sadece bir genişletme yöntemi gibi görünüyor IMvcCoreBuilder, değil IMvcBuilder. Yani böyle kullanılır services.AddMvcCore().AddJsonFormatters(f => f.Converters.Add(new StringEnumConverter()));.
infl3x

9

.Net core 3'te bu, System.Text.Json içindeki yerleşik sınıflarla artık mümkün:

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

JsonStringEnumConverterBelirli bir mülk için nitelik dekorasyonu ile yapılandırmak için:

using System.Text.Json.Serialization;

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

Numaralandırmayı her zaman dize olarak dönüştürmek istiyorsanız, özniteliği enum'a koyun.

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

9

System.Text.Json ile Asp.Net Core 3

public void ConfigureServices(IServiceCollection services)
{

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

    //...
 }

8

Yukarıdakilerin yetersiz kalması durumunda, bu aşırı yüklenme ile sonuçlandım:

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

Bu benim şu anki kullanım durumu için iyi bir çözümdür: Serileştiricilerin varsayılanlarını değiştirmek istemiyorum ve özelliklerim IList <EnumType> tipi olduğundan öznitelikleri kullanarak sorun yaşıyorum.
Dirk Brockhaus

5

Bu eski bir soru ama her ihtimale karşı katkıda bulunacağımı düşündüm. Projelerimde herhangi bir Json talebi için ayrı modeller kullanıyorum. Bir model genellikle "Json" önekine sahip etki alanı nesnesiyle aynı ada sahip olur. Modeller AutoMapper kullanılarak eşlenir . Json modelinin etki alanı sınıfında bir enum olan bir dize özelliği bildirmesini sağlayarak, AutoMapper dize sunumuna çözümlenir.

Merak ediyorsanız, Json serileştirilmiş sınıflar için ayrı modellere ihtiyacım var çünkü dahili serileştirici aksi halde dairesel referanslarla geliyor.

Umarım bu birine yardımcı olur.


Automapper ;-) [ScriptIgnore] özelliğinin bu özelliğinin dairesel referansları kaldıracağını öğrenmek güzel
ledragon

1
Ah. Özellik hakkında bilmiyordum. Teşekkürler! Pocos'unda kullanır mısın? Ben sadece onları temiz tutmak için herhangi bir Poco öznitelikleri için MetadataType tanımlarını kullanarak başvurdum. Özellik hala meta verilerle çalışır mı?
Ales Potocnik Hahonina


1

Bu hala alakalı olup olmadığından emin değilim ama doğrudan bir json dosyasına yazmak zorunda kaldım ve birlikte birkaç stackoverflow cevaplarını birlikte ekleme ile geldim

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

Tüm json anahtarlarım json "kurallarına" göre küçük harfle yazılır. Temiz bir şekilde girintili olarak biçimlendirir ve çıktıdaki boş değerleri yok sayar. Ayrıca bir StringEnumConverter ekleyerek numaralandırmaları dize değerleriyle yazdırır.

Şahsen bunu, modelin ek açıklamalarla kirletmesine gerek kalmadan, yapabileceğim en temiz buluyorum.

kullanımı:

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

0

Bu çözümün tüm parçalarını Newtonsoft.Jsonkütüphaneyi kullanarak bir araya getirdim . Enum sorununu giderir ve hata işlemeyi çok daha iyi hale getirir ve IIS tarafından barındırılan hizmetlerde çalışır. Oldukça fazla kod var, bu yüzden GitHub'da bulabilirsiniz: https://github.com/jongrant/wcfjsonserializer/blob/master/NewtonsoftJsonFormatter.cs

Web.configÇalışması için bazı girişler eklemeniz gerekiyor, burada bir örnek dosya görebilirsiniz: https://github.com/jongrant/wcfjsonserializer/blob/master/Web.config


0

Ve VB.net için aşağıdaki işleri buldum:

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

Biraz daha geleceğe dönük bir seçenek

Aynı soruya baktığımızda StringEnumConverter, enum değerlerimizin serileştirme tarafında felaketle kırılmadan zaman içinde genişleyebilmesini sağlamak için özel bir sürümüne ihtiyacımız olduğunu belirledik (aşağıdaki arka plana bakın). SafeEnumConverterAşağıdakilerin kullanılması, yük, adlandırılmış bir tanıma sahip olmayan numaralandırma için int-to-enum dönüşümünün nasıl çalışacağına daha yakın bir değer içeriyor olsa bile serileştirmenin bitmesini sağlar.

Kullanımı:

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

veya

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

Kaynak:

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

Arka fon

Kullanmaya baktığımızda StringEnumConverter, yaşadığımız sorun, yeni bir enum değeri eklendiği durumlarda pasifliğe ihtiyacımız vardı, ancak her müşteri yeni değerin hemen farkında değildi. Bu durumlarda, StringEnumConverterNewtonsoft JSON ile paketlenen JsonSerializationException"SomeString değeri EnumType türüne dönüştürülürken hata oluştu" biçimine benzer ve tüm serileştirme işlemi başarısız olur. Bu bizim için bir anlaşma kırıcıydı, çünkü müşteri anlamadığı mülk değerini görmezden gelmeyi / atmayı planlasa bile, yine de yükün geri kalanını serileştirebilmesi gerekiyordu!


-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]  
);
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.