c# - تسلسل JSON التعداد كسلسلة




asp.net enums (13)

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

بالإضافة إلى ذلك ، لجعل عضو التعداد الخاص بك لإجراء تسلسل / إلغاء تسلسل إلى / من نص محدد ، استخدم

System.Runtime.Serialization.EnumMember

سمة ، مثل هذا:

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

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

لدي فئة تحتوي على خاصية 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" }

أضف أدناه إلى 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());

لا يغير هذا الإصدار من answer ستيفن الاسم في 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; 
        }
    }
}

لا يوجد سمة خاصة يمكنك استخدامها. JavaScriptSerializer تسلسل enums إلى قيمها الرقمية وليس تمثيل السلسلة الخاصة بهم. ستحتاج إلى استخدام التسلسل المخصص لإجراء تسلسل enum بدلاً من قيمة رقمية.

تحرير: كما أشار إليهاOmerBakhari JSON.net يغطي حالة الاستخدام هذه (عبر السمة [JsonConverter(typeof(StringEnumConverter))] وغيرها الكثير غير المتداولة من خلال المسلسلات المدمجة في .net. هنا هو رابط يقارن بين الميزات والوظائف من المسلسلات .


لـ .Net Core Web Api: -

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

لقد قمت بتجميع كل أجزاء هذا الحل باستخدام مكتبة Newtonsoft.Json . إنه يعمل على إصلاح مشكلة التعداد كما أنه يجعل معالجة الأخطاء أفضل بكثير ، وهو يعمل في خدمات استضافة IIS. إنه رمز كثير جدًا ، لذا يمكنك العثور عليه على GitHub هنا: https://github.com/jongrant/wcfjsonserializer/blob/master/NewtonsoftJsonFormatter.cs

يجب عليك إضافة بعض الإدخالات إلى Web.config للحصول عليها ، يمكنك مشاهدة ملف مثال هنا: https://github.com/jongrant/wcfjsonserializer/blob/master/Web.config


لم أتمكن من تغيير نموذج المصدر كما في الإجابة الأعلى (ob.) ، ولم أكن أرغب في تسجيله عالميًا مثلIggy. لذلك جمعت https://.com/a/2870420/237091 و @ Iggy https://.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()
        }
    })

مزيج Omer Bokhari و uri 's الإجابات هو alsways حل لي لأن القيم التي أرغب في تقديمها عادة ما تكون مختلفة عن ما لدي في تعداد خاص لذلك أود أن أتمكن من تغيير التعداد الخاص بي إذا كنت بحاجة إلى ذلك.

لذلك إذا كان أي شخص مهتم ، فهو شيء من هذا القبيل:

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

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

هذا هو الحل البسيط الذي يقوم بتسلسل التعداد C # من جانب الخادم إلى JSON ويستخدم النتيجة لملء عنصر <select> جانب العميل. يعمل هذا لكل من التعدادات البسيطة وتعدادات bitflag.

لقد قمت بتضمين الحل المتكامل لأنني أعتقد أن معظم الأشخاص الراغبين في تسلسل C # enum إلى JSON ربما يستخدمونه أيضًا لملء قائمة <select> المنسدلة.

هنا يذهب:

مثال التعداد

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 للتعامل مع طلب الحصول على. ويستخدم أسلوب مساعد Nancy's Response.AsJson() - ولكن لا تقلق ، يمكنك استخدام أي من منسق JSON القياسي حيث تم طرح التعداد بالفعل في نوع مجهول بسيط جاهز للتسلسل.

JSON منشأ

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

جانب العميل - قهوة

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>

هنا هو الجواب ل newtonsoft.json

enum Gender { Male, Female }

class Person
{
    int Age { get; set; }

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

يمكنك أيضًا إضافة محول إلى JsonSerializer إذا كنت لا ترغب في استخدام سمة JsonConverter :

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

سوف يعمل مع كل enum الذي يراه أثناء التسلسل.


يمكنك إنشاء JsonSerializerSettings مع المكالمة إلى JsonConverter.SerializeObject على النحو التالي:

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

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




javascriptserializer