JavaScriptSerializer - JSON එනූම් නූලක් ලෙස අනුක්‍රමණය කිරීම


1174

මට enumදේපලක් අඩංගු පංතියක් ඇති අතර , එම වස්තුව අනුක්‍රමිකව භාවිතා කිරීමෙන් JavaScriptSerializer, මගේ json ප්‍රති result ලය එහි string"නමට" වඩා ගණන් කිරීමේ පූර්ණ අගය අඩංගු වේ . stringචාරිත්රයක් නිර්මාණය නොකර මගේ json හි enum ලබා ගැනීමට ක්රමයක් JavaScriptConverterතිබේද? සමහර විට මට enumඅර්ථ දැක්වීම හෝ වස්තු දේපල අලංකාර කළ හැකි ලක්ෂණයක් තිබේද?

උදාහරණයක් ලෙස:

enum Gender { Male, Female }

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

කැමති json ප්‍රති result ලය:

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

බිල්ට් .නෙට් රාමු පංති සමඟ ඉතා මැනවින් පිළිතුරු සෙවීම, නොහැකි නම් විකල්ප (Json.net වැනි) සාදරයෙන් පිළිගනිමු.


8
කුමන දෙයට වෙනස් කරන්න? ඉහළම උත්තරීතර පිළිතුර ඇත්ත වශයෙන්ම ප්‍රශ්නයට පිළිතුරු සපයන්නේ නැත - ඔව් එය වෙනත් සන්දර්භයන් සඳහා ප්‍රයෝජනවත් වේ, එබැවින් ඡන්දය, නමුත් ඔබ එම්එස් ජාවාස්ක්‍රිප්ට් සීරියලයිසර් සමඟ සිරවී සිටින්නේ නම් එය ප්‍රායෝගිකව ප්‍රයෝජනවත් නොවේ. , වඩාත්ම වැදගත් දෙය නම් ප්‍රශ්නයට අවශ්‍ය පරිදි. පිළිගත් පිළිතුර පවසන්නේ එය කළ නොහැකි බවයි. මගේ පිළිතුර ටිකක් අනවසරයෙන් වැඩ කරන අතරම කාර්යය ඉටු කරයි.
ස්ටීවන් කෙනඩි

Answers:


384

ඔබට භාවිතා කළ හැකි විශේෂ ලක්ෂණයක් නොමැත. JavaScriptSerializerඅනුක්‍රමිකව enumsඒවායේ සංඛ්‍යාත්මක අගයන්ට මිස ඒවායේ නූල් නිරූපණයට නොවේ. enumසංඛ්‍යාත්මක අගය වෙනුවට එහි නම අනුක්‍රමික කිරීමට ඔබට අභිරුචි අනුක්‍රමිකකරණය භාවිතා කිරීමට අවශ්‍ය වනු ඇත .


ඔමර්බහාරි විසින් සපයන ලද මෙම ප්‍රශ්නයට පිළිතුරJavaScriptSerializer බැලීමට වඩා ඔබට JSON.Net භාවිතා කළ හැකි නම් : JSON.net මෙම භාවිත නඩුව (ගුණාංගය හරහා ) ආවරණය කරයි . අනුක්‍රමිකයන්ගේ විශේෂාංග සහ ක්‍රියාකාරීත්වය සංසන්දනය කරන සබැඳියක් මෙන්න .[JsonConverter(typeof(StringEnumConverter))]


7
Ab ෆැබ්ස්ටර් - ඔබේ විසඳුම නිව්ටන්සොෆ්ට් හි
ජේසන්

1
OrnBornToCode Json.NET යනු ASP.NET පෙරනිමියෙන් භාවිතා කරන අනුක්‍රමිකකරණයයි.
BrainSlugs83

13
@ BrainSlugs83 - ප්‍රශ්නය වූයේ Json.NET නොව JavaScriptSerializer භාවිතා කිරීමයි (ඔබ සංශෝධන ඉතිහාසය දෙස බැලුවහොත් එය පැහැදිලි කිරීම සඳහා සංස්කරණයක් ඇති බව ඔබට පෙනෙනු ඇත), ඔබ JavaScriptSerializer භාවිතා කරන්නේ නම් එම ගුණාංගය JsonConverterක්‍රියා නොකරනු ඇත.
BornToCode

ඔබට මාව අවදි කළ හැකිද
යොංකිං චෙන්

"Json.NET යනු ASP.NET පෙරනිමියෙන් භාවිතා කරන අනුක්‍රමිකකරණයයි" - ප්‍රශ්නය ඇසූ විට හෝ පිළිතුරු දුන් විට මෙය සත්‍යයක් නොවීය. (නමුත් වඩාත්ම වැදගත් දෙය වන්නේ පිළිතුරේ පැහැදිලිකමයි)
ryanwebjackson

2115

මම සොයන නිශ්චිත ක්‍රියාකාරිත්වය Json.NET මඟින් සපයන බව මම සොයාගෙන ඇත StringEnumConverter:

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

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

වැඩි විස්තර StringEnumConverterප්‍රලේඛනයෙන් ලබා ගත හැකිය .

මෙම පරිවර්තකය වඩාත් ගෝලීයව වින්‍යාස කිරීමට වෙනත් ස්ථාන තිබේ:

  • ඔබට අවශ්‍ය නම් 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

62
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 serializer ලෙස භාවිතා නොකරන අතර Controllerසෑම අනුක්‍රමිකකරණයක්ම දිගු කිරීම හෝ අතින් අභිබවා යාම අවශ්‍ය වේ .
ඔඩිස්

2
ඔබට පරිවර්තකය රිසිකරණය කළ හැකිය (කියන්න, camelCaseප්‍රතිදානය සඳහා ):new StringEnumConverter { CamelCaseText = true }
මුහුදු මාළු

173

C # enum නූල ලෙස JSON අනුක්‍රමිකකරණය සඳහා පහත ඔබගේ global.asax වෙත එක් කරන්න

  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 ගොනුවට එකතු කරන ලද අතර REST (json fomat) ඇමතුම්වල එනූම් අගයන් සඳහා නූල් නැවත ලබා දීම සඳහා ASP.NET වෙබ් API 2.1 ව්‍යාපෘතියක මා වෙනුවෙන් උපක්‍රමයක් කළේය.
ග්‍රෙග් ඉසෙඩ්

1
ඉල්ලීම් විෂය පථයකට පමණක් මෙම දේපල සැකසීමට ක්‍රමයක් තිබේද?
ඇනෙස්ටිස් කිව්රානොග්ලෝ

N ඇනෙස්ටිස්කිව්රොනොග්ලෝ විසින් තමන්ගේම සැකසුම් සමඟ ඉල්ලීමකට අනුව අභිරුචි json අනුක්‍රමික යන්ත්‍රයක් භාවිතා කරන්න.
BrainSlugs83

3
ඉන්ඩෙන්ට් කරන ලද පළමු අනුක්‍රමික සැකසුම දෘශ්‍ය ප්‍රශ්නයට සම්බන්ධ නොවේ.
user3791372

155

G ඉග්ගි පිළිතුර JSON විසින් සී # එනුම් අනුක්‍රමිකකරණය 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 පිටුවේ වැඩි විස්තර

ඊට අමතරව, ඔබේ පා en මාලාවේ සාමාජිකයාට නිශ්චිත පා to යෙන් අනුක්‍රමිකකරණය / ආශා කිරීම සඳහා, භාවිතා කරන්න

System.Runtime.Serialization.EnumMember

ගුණාංගය, මේ වගේ:

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

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

6
ඔබට ස්තුතියි! මම සොයමින් සිටියෙමි [EnumMember].
පෝලාඩ්

මෙම CamelCaseTextදේපල යල් පිනූ ලෙස ලකුණු කර ඇත. පරිවර්තකය new StringEnumConverter(new CamelCaseNamingStrategy())
fiat

බොහොම ස්තූතියි, මගේ දවස හැදුවා! :)
එල්ඩෝවර්

39

ඉහළ පිළිතුරේ (@ob.) මෙන් ප්‍රභව ආකෘතිය වෙනස් කිරීමට මට නොහැකි වූ අතර එය g ඉග්ගි මෙන් ගෝලීයව ලියාපදිංචි කිරීමට මට අවශ්‍ය නොවීය. මම ඒකාබද්ධ ඒ නිසා https://stackoverflow.com/a/2870420/237091 හා @ Iggy ගේ 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>
බොග්ඩාන්

35

ඔමර් බොහාරි සහ යූරිගේ පිළිතුරු සංයෝජනය සැමවිටම මගේ විසඳුම වන බැවින් මට ලබා දීමට අවශ්‍ය අගයන් සාමාන්‍යයෙන් මගේ එනූම් හි ඇති දේට වඩා වෙනස් බැවින් මට අවශ්‍ය නම් මගේ එනූම්ස් වෙනස් කිරීමට මට හැකි වනු ඇත.

එබැවින් යමෙකු උනන්දුවක් දක්වන්නේ නම්, එය මෙවැනි දෙයකි:

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කළේ එනුම් සාමාජිකයින් සඳහා වන අතර එය සරල ඩෙසරයිලේෂන් කාර්යයන් සඳහා ක්‍රියා කරයි. කනගාටුවට කරුණ නම්, JTokens සමඟ අතින් කරකැවීම් අතරතුර එය නොසලකා හැරීමයි . හැපිලි EnumMemberAttributeවැඩ කරන්නේ චමත්කාරයක් මෙනි. ස්තූතියි!
Prolog

31

මෙම පහසුවෙන් එකතු කිරීමෙන් මෙය සිදු වේ ScriptIgnoreවෙත විශේෂණය Gender, දේපළ එය serialized කළ නොහැකි හේතු, සහ එකතු GenderStringවන දේපළ නැහැ serialized ලබා ගන්න:

class Person
{
    int Age { get; set; }

    [ScriptIgnore]
    Gender Gender { get; set; }

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

29
මට පැහැදිලි කිරීමට උත්සාහ කරන්නම්. නිර්මාණ අනුග්‍රාහකයන්ට අනුව මෙම විසඳුම නිවැරදි නොවේ. දර්ශන අරමුණ අනුව ඔබ ආකෘතිය වෙනස් කරන ලදි. නමුත් ආකෘතියට දත්ත පමණක් අඩංගු විය යුතු අතර ඉදිරිපත් කිරීම් ගැන තැකීමක් නොකරයි. ඔබ මෙම ක්‍රියාකාරීත්වය අනෙක් ස්ථරයට ගෙන යා යුතුය.
RredCat

4
ඇත්ත වශයෙන්ම, මාදිලිය පාලකයෙන් දත්ත යැවීමට භාවිතා කරයි, කුහුඹුවා එය පාලකය, ඉදිරිපත් කිරීම ගැන තැකීමක් නොකරයි. ස්වයංක්‍රීය දේපල හඳුන්වාදීම (මෙහි GenderString) පාලකය බිඳ දමන්නේ නැත, එය තවමත් ස්ත්‍රී පුරුෂ දේපල භාවිතා කරයි, නමුත් බැලීමට පහසු ප්‍රවේශයක් සපයයි. තාර්කික විසඳුම.
ඩීමා

17
RedRredCat "දර්ශන ආකෘතියේ" දර්ශන-විශේෂිත ගුණාංග තිබීමේ වරදක් නැත. IMHO හි වැරැද්ද වනුයේ දර්ශන ආකෘතිය වසම් ආකෘතියෙන් වෙන් නොකිරීමයි
මාරියානෝ ඩෙසන්සේ

5
RedRredCat, එය යම් රටාවකට අනුව වැරදියි වුවද, OP මේ ගැන කිසිවක් නොකියයි, එබැවින් මෙය ඇත්ත වශයෙන්ම නිවැරදි පිළිතුරකි. (මම දාර්ශනිකව ඔබේ අදහස සමඟ එකඟ වුවද.)
MEMark

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 රාමු අනුක්‍රමික භාවිතා කරමින් මට ඇති ගැටළුව සරල හා විසඳයි.
සෙනෙට් සභික

තෙවන පාර්ශවීය පුස්තකාල භාවිතා කිරීමට මට අවසර නැති බැවින් මට හොඳම විසඳුම (අයිඑස්ඕ අනුකූලතා ගැටළු)
ඩැනියෙල් ග්‍රුස්සික්

මෙය ඇත්ත වශයෙන්ම ප්‍රශ්නයේ ඇති අනුක්‍රමික වර්ගය සඳහා නොවේ. JavaScriptSerializer නොසලකා හරින සෑම දෙයක්ම අනුක්‍රමික කරයි, නමුත් DataContractJsonSerializer හට DataMember ගුණාංග අවශ්‍ය වේ. කෑගැසීමට ස්තූතියි නමුත් කරුණාකර සටහන් කරන්න ඔබ මගේ නම වැරදියට ලියා ඇති බව :)
ස්ටීවන් කෙනඩි


25

Newtonsoft.json සඳහා පිළිතුර මෙන්න

enum Gender { Male, Female }

class Person
{
    int Age { get; set; }

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

1
මෙම පිළිතුරට ස්තූතියි, මට ගොඩක් උදව් කළා! trueපැස්කල් කේස් හි ඔබේ එනූම්ස් නිර්වචනය කිරීමට ඔබට අවශ්‍ය නම්, නමුත් එය ඔටුවන් කේස් හි අනුක්‍රමිකකරණය කිරීමට ඔබට අවශ්‍ය නම්, එවිට ඔබ ඔබේ JsonConverter වර්ගයට එකතු කළ යුතුය:[JsonConverter(typeof(StringEnumConverter), true)]
පීට්

17

ඔබට ගුණාංගය JsonSerializerභාවිතා කිරීමට අවශ්‍ය නැතිනම් ඔබට පරිවර්තකයක් එක් කළ හැකිය JsonConverter:

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

enumඑම අනුක්‍රමිකකරණයේදී එය දකින සෑම කෙනෙකුටම එය ක්‍රියා කරනු ඇත .


15

මෙන්න සරල විසඳුමක් වන්නේ සේවාදායක පැත්තේ C # enum JSON වෙත අනුක්‍රමික කරන අතර ප්‍රති -ලය සේවාදායක පාර්ශවීය <select>අංගයක් ජනගහනය කිරීමට භාවිතා කිරීමයි . මෙය සරල එනූම් සහ බිට්ෆ්ලැග් එනූම් සඳහා ක්‍රියා කරයි.

මම අවසාන සිට විසඳුම ඇතුළත් කර ඇති නිසා JSON වෙත C # enum අනුක්‍රමික කිරීමට කැමති බොහෝ අය එය <select>පහළට වැටීම පිරවීම සඳහා භාවිතා කරනු ඇතැයි මම සිතමි .

මෙන්න:

උදාහරණ එනුම්

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

අවසර පද්ධතියක් ජනනය කිරීම සඳහා බිට්වේස් OR භාවිතා කරන සංකීර්ණ එනුම්. එබැවින් ඔබට එනුම් වල පූර්ණ සංඛ්‍යා අගය සඳහා සරල දර්ශකය [0,1,2 ..] මත විශ්වාසය තැබිය නොහැක.

සේවාදායක පැත්ත - සී #

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

ලබා ගැනීමේ ඉල්ලීම හැසිරවීමට ඉහත කේතය නැන්සිඑෆ්එක්ස් රාමුව භාවිතා කරයි. එය නැන්සිගේ 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>

13

ASP.Net core සඳහා ඔබේ ආරම්භක පන්තියට පහත සඳහන් දෑ එක් කරන්න:

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

13

System.Text.Json සමඟ Asp.Net Core 3

public void ConfigureServices(IServiceCollection services)
{

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

    //...
 }

12

.Net core 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; }

ඔබට සෑම විටම එනුම් එක නූල් බවට පරිවර්තනය කිරීමට අවශ්‍ය නම්, එම ගුණාංගය එනුම් තුළම තබන්න.

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

11

ඔබට පහත පරිදි JsonConverter.SerializeObject වෙත ඇමතුමකින් JsonSerializerSettings නිර්මාණය කළ හැකිය:

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

10

විස්තර කිරීමේ ලක්ෂණයක් ඇති විට අනුක්‍රමිකකරණය සඳහා පිළිතුරක් නොමැති බව සැලකිල්ලට ගත්තා.

විස්තර කිරීමේ ගුණාංගයට සහය දක්වන මගේ ක්‍රියාත්මක කිරීම මෙන්න.

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

එනුම්:

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

.නෙට් කෝර් සඳහා: -

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

2
මෙය Microsoft.AspNetCore.Mvc.Formatters.Jsonනුජෙට් පැකේජයෙන් එකක් නම්, එය පෙනෙන්නේ දිගු කිරීමේ ක්‍රමයක් මත IMvcCoreBuilderමිස නොවේ IMvcBuilder. ඒ නිසා එය භාවිතා කර services.AddMvcCore().AddJsonFormatters(f => f.Converters.Add(new StringEnumConverter()));ඇත.
infl3x

8

යමෙකුට ඉහත ප්‍රමාණවත් නොවන බව යමෙකු දුටුවහොත්, මම මෙම අධික බර පැටවීම අවසන් කළෙමි:

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

මගේ වර්තමාන භාවිත නඩුව සඳහා මෙය හොඳ විසඳුමකි: මට අනුක්‍රමික පෙරනිමි වෙනස් කිරීමට අවශ්‍ය නොවන අතර මට ගුණාංග භාවිතා කිරීමේ ගැටළු ඇත, මන්ද මගේ ගුණාංග IList <EnumType> වර්ගයට අයත් වේ.
ඩර්ක් බ්‍රොක්හවුස්

5

මෙය පරණ ප්‍රශ්නයක් නමුත් මම හිතුවා මම දායක වේවි කියලා. මගේ ව්‍යාපෘති වලදී මම ඕනෑම ජේසන් ඉල්ලීම් සඳහා වෙනම ආකෘති භාවිතා කරමි. ආකෘතියකට සාමාන්‍යයෙන් "ජේසන්" උපසර්ගය සහිත ඩොමේන් වස්තුවට සමාන නමක් ඇත. ආකෘති සිතියම් ගත කර භාවිතයෙන්ස්වයංක්‍රීය ඇත . Json මාදිලිය ඩොමේන් පංතියේ එනූම් එකක් වන සංගීත ගුණාංගයක් ප්‍රකාශයට පත් කිරීමෙන්, ඔටෝමැපර් විසින් එහි සංගීත ඉදිරිපත් කිරීම විසඳනු ඇත.

ඔබ කල්පනා කරන්නේ නම්, මට ජේසන් අනුක්‍රමික පන්ති සඳහා වෙනම ආකෘති අවශ්‍යයි, මන්ද ඉන්බිල්ට් අනුක්‍රමිකකරණය වෙනත් ආකාරයකින් චක්‍රලේඛ යොමු කිරීම් සමඟ එන බැවිනි.

මෙය යමෙකුට උපකාරී වේ යැයි සිතමි.


Automapper හි එම අංගය ඉගෙන ගැනීමට ලැබීම සතුටක් ;-) [ScriptIgnore] ගුණාංගය රවුම් යොමු ඉවත් කරයි
ledragon

1
ඔහ්. ගුණාංගය ගැන දැන සිටියේ නැත. ස්තූතියි! ඔබ එය ඔබේ පොකෝස් මත භාවිතා කරනවාද? ඕනෑම පොකෝ ගුණාංග සඳහා මෙටා ඩේටා ටයිප් නිර්වචන භාවිතා කර ඒවා පිරිසිදුව තබා ගැනීමට මම යොමු වී සිටිමි. ගුණාංගය මෙටා දත්ත හරහා තවමත් ක්‍රියාත්මක වේද?
ඇලෙස් පොටොක්නික් හහෝනිනා

3

සාදන ලද ජාවාස්ක්‍රිප්ට් සීරියලයිසර් සමඟ මෙය සිදු කිරීම සඳහා ඔබට සැබවින්ම ජාවාස්ක්‍රිප්ට්කොන්වර්ටරයක් ​​භාවිතා කළ හැකිය. ඔබේ එනූමය යූරි බවට පරිවර්තනය කිරීමෙන් ඔබට එය නූලක් ලෙස කේතනය කළ හැකිය.

දිනයන් සඳහා මෙය කරන්නේ කෙසේදැයි මම විස්තර කර ඇති නමුත් එය එනුම් සඳහාද භාවිතා කළ හැකිය. .NET JavaScriptSerializer සඳහා අභිරුචි දිනය ටයිම් JSON ආකෘතිය .


ඉතා රසවත් විසඳුමක්! බෙදා ගැනීමට ස්තූතියි.
ඔලිවර්

1

මෙය තවමත් අදාළ දැයි නිශ්චිතවම කිව නොහැකි නමුත් මට කෙලින්ම json ගොනුවකට ලිවීමට සිදු වූ අතර මම පහත දැක්වෙන කොටස් සමඟ ස්ටොක් ඕවර් ප්‍රවාහ පිළිතුරු කිහිපයක් ඉදිරිපත් කළෙමි

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 "නීති" අනුව ආරම්භ වන කුඩා අකුරු බව සහතික කරයි. එය පිරිසිදු ලෙස ඉන්ඩෙන්ට් කර ප්‍රතිදානයේ ඇති ශුන්‍යයන් නොසලකා හරින ආකෘති. StringEnumConverter එකක් එකතු කිරීමෙන් අස්ලෝ ඒවායේ නූල් අගය සමඟ enums මුද්‍රණය කරයි.

පුද්ගලිකව මම මෙය ව්‍යාඛ්‍යාව සමඟ ආකෘතිය අපිරිසිදු නොකර මට ඉදිරිපත් කළ හැකි පිරිසිදුම බව සොයා ගතිමි.

භාවිතය:

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

1

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

මම 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

තරමක් වැඩි අනාගත-ඔප්පු විකල්පයක්

එම ප්‍රශ්නයටම මුහුණ දෙමින්, StringEnumConverterඅපේ එන්යූම් අගයන් කාලයාගේ ඇවෑමෙන් ව්‍යසනකාරී ලෙස විනාශ නොවී පුළුල් විය හැකි බවට වග බලා ගැනීම සඳහා අපට අභිරුචි අනුවාදයක් අවශ්‍ය බව අපි තීරණය කළෙමු (පහත පසුබිම බලන්න). භාවිතා කිරීමSafeEnumConverterපහත දැක්වෙන දේ මඟින් නම් කරන ලද අර්ථ දැක්වීමක් නොමැති එනූම් සඳහා ගෙවුම් භාරය වටිනාකමක් තිබුණද, ඉන්ටර්-සිට-එනුම් පරිවර්තනය ක්‍රියාත්මක වන ආකාරය වෙත සමීප වේ.

භාවිතය:

[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නිව්ටන්සොෆ්ට් JSON සමඟ ඇසුරුම් කර ඇති අතර JsonSerializationExceptionඑය "සොම්ස්ට්‍රිං අගය එනුම් ටයිප් ටයිප් කිරීම සඳහා දෝෂයක් බවට පරිවර්තනය කිරීමේ දෝෂයට" සමාන වේ. එවිට සමස්ත ඩෙසරීලේෂණ ක්‍රියාවලිය අසාර්ථක වේ. මෙය අපට ගනුදෙනු කඩකිරීමක් විය, මන්ද සේවාදායකයා එය තේරුම් නොගත් දේපල වටිනාකම නොසලකා හැරීමට / ඉවත දැමීමට සැලසුම් කළද, ඉතිරි ගෙවීම් අවප්‍රමාණ කිරීමේ හැකියාව තවමත් එයට අවශ්‍ය විය!


-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]  
);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.