জাভাস্ক্রিপ্টসরিয়ালাইজার - স্ট্রিং হিসাবে এনামের জেএসএন সিরিয়ালাইজেশন


1160

আমার একটি শ্রেণি রয়েছে যার মধ্যে একটি enumসম্পত্তি রয়েছে এবং এটি ব্যবহার করে অবজেক্টটি সিরিয়ালাইজ করার পরে JavaScriptSerializer, আমার জসন রেজাল্টে তার stringনামটির পরিবর্তে অঙ্কের পূর্ণসংখ্যার মান থাকে । stringকাস্টম তৈরি না করে আমার জসনে এনাম পাওয়ার উপায় আছে কি JavaScriptConverter? সম্ভবত এমন একটি বৈশিষ্ট্য আছে যা আমি enumসংজ্ঞাটি, বা সম্পত্তি সম্পর্কিত সম্পত্তি সাজাতে পারি?

উদাহরণ হিসাবে:

enum Gender { Male, Female }

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

পছন্দসই জসন ফলাফল:

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

আদর্শভাবে অন্তর্নির্মিত .NET ফ্রেমওয়ার্ক ক্লাসগুলির সাথে উত্তর সন্ধান করা সম্ভব না হলে বিকল্প বিকল্পগুলি (জসনন.কম) স্বাগতম are


8
কোনটিতে পরিবর্তন? সর্বাধিক উত্সাহিত উত্তরটি আসলে প্রশ্নের উত্তর দেয় না - হ্যাঁ এটি অন্যান্য প্রেক্ষাপটে কার্যকর, সুতরাং ভোটগুলি, তবে এটি এমএস জাভাস্ক্রিপ্টসিরাইজারের সাথে আটকে থাকলে আপনি যা ব্যবহারিক তা ব্যবহার করতে পারেন না, মূলত আপনি যদি পৃষ্ঠাগুলি ব্যবহার করেন এবং , সবচেয়ে গুরুত্বপূর্ণভাবে, যেমন প্রশ্ন দ্বারা প্রয়োজনীয়। গৃহীত উত্তর বলে যে এটি সম্ভব নয়। আমার উত্তরটি হ্যাকের কিছুটা কাজ হয়ে গেলে।
স্টিফেন কেনেডি

উত্তর:


374

না আপনি ব্যবহার করতে পারেন এমন কোনও বিশেষ গুণ নেই। তাদের সংখ্যাসূচক মানগুলিতে JavaScriptSerializerক্রমিকায়িত enumsহয় এবং তাদের স্ট্রিং প্রতিনিধিত্ব করে না। সংখ্যাটির enumপরিবর্তে এর নাম হিসাবে সিরিয়ালায়িত করতে আপনাকে কাস্টম সিরিয়ালাইজেশন ব্যবহার করতে হবে ।


আপনি পরিবর্তে JSON.Net ব্যবহার করতে পারেন তাহলে JavaScriptSerializerচেয়ে দেখুন এই প্রশ্নে উত্তর দ্বারা উপলব্ধ OmerBakhari : JSON.net এই ব্যবহারের ক্ষেত্রে (অনুষঙ্গ মাধ্যমে জুড়ে [JsonConverter(typeof(StringEnumConverter))]) এবং আরও অনেক কিছু .net serializers সালে নির্মিত দ্বারা পরিচালিত নয়। সিরিয়ালাইজারগুলির বৈশিষ্ট্য এবং কার্যকারিতা তুলনা করার জন্য এখানে একটি লিঙ্ক দেওয়া আছে


7
@ ফ্যাজটার - আপনার সমাধানটি নিউটনসফটসের জসন ব্যবহার করে আমার সাথে কাজ করেছে
বিমারগুই 12:48

1
@ বার্নটোকোড জসন.এনইটি হ'ল সিরিয়ালাইজার যা এএসপি.এনইটি ডিফল্টরূপে ব্যবহার করে।
BrainSlugs83

12
@ ব্রেইনস্লাগস ৩৩ - জাভাস্ক্রিপ্টশিরাইজার ব্যবহার করার বিষয়ে প্রশ্ন ছিল, জাসন.এনইটি নয় (এবং আপনি যদি পুনর্বিবেচনার ইতিহাসটি দেখেন তবে আপনি দেখতে পাবেন যে এটির জন্য একটি সম্পাদনা ছিল), আপনি যদি জাভাস্ক্রিপ্টসিরাইজার ব্যবহার করেন তবে বৈশিষ্ট্যটি কাজ JsonConverterকরছে না।
BornToCode

50
দয়া করে এটি গ্রহণযোগ্য উত্তর হিসাবে সরান কারণ এটি সমস্যার সমাধান করে না, নীচের উত্তরটি 1000+ upvotes করবেন।
এমএইচগেমওয়ার্ক

আপনি কি আমাকে জবাব দিতে পারবেন
ইয়ংকিয়াং চেন

2100

আমি খুঁজে পেয়েছি যে Json.NET একটি বিশেষত্বের সাথে আমি সন্ধান করছি সঠিক কার্যকারিতা সরবরাহ করে StringEnumConverter:

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

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

StringEnumConverterডকুমেন্টেশনে উপলভ্য আরও বিশদ ।

আরও বিশ্বব্যাপী এই রূপান্তরকারীটি কনফিগার করার অন্যান্য জায়গা রয়েছে:

  • আপনি যদি এনামকে সর্বদা স্ট্রিং হিসাবে সিরিয়ালাইজড / ডিসরিয়ালাইজ করতে চান তবে এনাম নিজেই এনাম:

    [JsonConverter(typeof(StringEnumConverter))]  
    enum Gender { Male, Female }
  • যদি কেউ অ্যাট্রিবিউট সাজসজ্জা এড়াতে চায়, আপনি আপনার জসনসিরাইজারে রূপান্তরকারী যুক্ত করতে পারেন (বিজার্ন এগিল প্রস্তাবিত ):

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

    এবং এটি সিরিয়ালাইজেশনের সময় এটি দেখতে পাওয়া প্রতিটি এনামের জন্য কাজ করবে ( ট্র্যাভিস প্রস্তাবিত )।

  • বা জসনকনভার্টার ( কলা দ্বারা প্রস্তাবিত ):

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

অতিরিক্তভাবে আপনি কেসিং নিয়ন্ত্রণ করতে পারেন এবং স্ট্রিংএইনম কনভার্টার (নামিংস্ট্রেজি, বুলিয়ান) কনস্ট্রাক্টর ব্যবহার করে সংখ্যাগুলি এখনও গৃহীত হয়েছে কিনা ।


9
এএসপিএন এমভিসি অ্যাপ্লিকেশনটিতে এটি কীভাবে ব্যবহার করা যায় তার বিবরণের জন্য লিঙ্ক অনুসরণ করুন james.newtonking.com/archive/2008/10/16/…
RredCat

2
এখানে এই ফাংশনটির লিঙ্কটি রয়েছে: james.newtonking.com/projects/json/help/html/…
সিএডি

61
এইচটিটিপি কনফিগারেশন কনফিগারেশন = গ্লোবাল কনফিগারেশন। কনফিগারেশন; কনফিগারেশন.ফর্মেটর.জসনফরম্যাটর.সরিয়ালাইজারসেটেটিংস.ফর্ম্যাটিং = নিউটোনসফট.জসন.ফর্ম্যাটিং.আইডেন্টেন্ট; কনফিগারেশন.ফর্মেটর.জসনফোরমেটার.শিরাইজারসেটেটিংস.কনভার্টারস.এড করুন (নতুন নিউটোনসফট.জসন.কনভার্টারস.স্ট্রিংইনম কনভার্টার ());
Iggy

1
ডিফল্টরূপে এএসপি.নেট এমভিসি Json.Net কে জসন সিরিয়ালাইজার হিসাবে ব্যবহার করে না এবং Controllerপ্রতিটি সিরিয়ালাইজেশন বর্ধিত বা ম্যানুয়ালি ওভাররাইড করা দরকার default
ওডিস

2
আপনি রূপান্তরকারীটি কাস্টমাইজ করতে পারেন ( camelCaseআউটপুট হিসাবে বলুন):new StringEnumConverter { CamelCaseText = true }
সীফিশ

172

স্ট্রিং হিসাবে সি # এনামের জেএসওএন সিরিয়ালাইজেশনের জন্য আপনার গ্লোবাল.এক্সএক্সে নীচে যুক্ত করুন

  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 ফাইলটিতে যুক্ত করা হয়েছিল এবং আমার কাছে একটি এসপি.নেট ওয়েব এপিআই ২.১ প্রকল্পে রিআরটি (জসন ফোম্যাট) কলগুলিতে এনাম মানগুলির জন্য স্ট্রিং ফিরিয়ে দেওয়ার জন্য একটি কৌশল করেছিল।
গ্রেগ জেড।

1
কেবলমাত্র অনুরোধের সুযোগ অনুযায়ী এই সম্পত্তিটি সেট করার কোনও উপায় আছে?
অ্যানেস্টিস কিভরনোগ্লো

@ এনেস্টিসকিরানোগ্লো আপনার নিজস্ব সেটিংসের মাধ্যমে অনুরোধ অনুযায়ী একটি কাস্টম জসন সিরিয়ালাইজার ব্যবহার করুন।
BrainSlugs83

3
ইন্ডেন্ট করা প্রথম সিরিয়ালাইজার সেটিংটি অপ প্রশ্নের সাথে সম্পর্কিত নয়।
ব্যবহারকারী 3791372

153

@ আইজি উত্তর সি এস এনামের জেএসএন সিরিয়ালাইজেশন কেবল এএসপি.নেট (ওয়েব এপিআই এবং এর জন্য) হিসাবে স্ট্রিং হিসাবে সেট করে।

তবে এটি এডহক সিরিয়ালাইজেশনের সাথেও কাজ করতে আপনার শুরুর ক্লাসে নিম্নলিখিত যুক্ত করুন (যেমন গ্লোবাল.এক্সএক্স অ্যাপ্লিকেশন_স্টার্ট)

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

6
ধন্যবাদ! আমি সন্ধান করছি [EnumMember]
পুলিড

CamelCaseTextসম্পত্তি এখন অপ্রচলিত চিহ্নিত করা হয়। কনভার্টার instantiate করার নতুন পদ্ধতি:new StringEnumConverter(new CamelCaseNamingStrategy())
ক্ষমতাপ্রদান

আপনাকে অনেক ধন্যবাদ, আমার দিন তৈরি! :)
Eldoïr

39

আমি উপরের উত্তরের মতো (@ ওব।) উত্সের মডেলটি পরিবর্তন করতে পারিনি, এবং আমি @ ইগির মতো বিশ্বব্যাপী এটি নিবন্ধ করতে চাইনি। তাই আমি মিলিত https://stackoverflow.com/a/2870420/237091 এবং @ ইগি এর https://stackoverflow.com/a/18152942/237091 SerializeObject কমান্ড নিজেই থাকাকালীন স্ট্রিং enum রূপান্তরকারী স্থাপনের অনুমতি দিতে:

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

আপনার যদি এই তালিকার মতো কোনও সম্পত্তি থাকে তবে এটি খুব ভাল লাগবে <সোনাম টাইম>
বোগদান

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এনাম সদস্যদের জন্য ব্যবহার করছিলাম এবং এটি সাধারণ ডিসরিয়ালাইজেশন কাজের জন্য কাজ করছে। দুঃখের বিষয়, এর সাথে ম্যানুয়াল টুইটের সময় JTokenএটি উপেক্ষা করা হয়। হ্যাপিলি 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
প্রকৃতপক্ষে, মডেলটি নিয়ন্ত্রণকারীর কাছ থেকে ডেটা পাস করার জন্য ব্যবহৃত হয়, পিঁপড়ে এটি নিয়ামক, যিনি উপস্থাপনের বিষয়ে চিন্তা করেন না। স্বয়ংক্রিয় সম্পত্তি পরিচিতি (এখানে জেন্ডারস্ট্রিং) নিয়ামককে বিরতি দেয় না, যা এখনও জেন্ডার সম্পত্তি ব্যবহার করে তবে দেখার জন্য সহজ অ্যাক্সেস সরবরাহ করে। যৌক্তিক সমাধান।
দিমা

17
@RredCat "ভিউ মডেল" -তে নির্দিষ্ট-সুনির্দিষ্ট বৈশিষ্ট্য থাকাতে কোনও ভুল নেই having আইএমএইচও ভুলটি ডোমেন মডেল থেকে ভিউ মডেলকে বিভক্ত না করা হবে: ব্লগস.এমএসএনএন
মারিয়ানো দেশানজে

5
@ রেডটিক্স, যদিও এটি কিছু প্যাটার্ন অনুসারে ভুল ছিল, ওপি এ সম্পর্কে কিছুই বলে না, তাই এটি সত্যই সঠিক উত্তর। (এমনকি যদি আমি দার্শনিকভাবে আপনার
বক্তব্যটির

10
এই মন্তব্য থ্রেডে প্যাডেন্টিক্যালি অযৌক্তিক বাইক-শেডিং আকর্ষণীয়।
মাইক মুনি

26

স্টিফেনের উত্তরের এই সংস্করণটি জেএসএনে নাম পরিবর্তন করে না:

[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 ফ্রেমওয়ার্ক সিরিয়ালাইজার ব্যবহার করে আমার জন্য সহজ এবং সমস্যা সমাধান করে।
সিনেটর

আমার পক্ষে সর্বোত্তম সমাধান যেহেতু আমাকে তৃতীয় পক্ষের গ্রন্থাগারগুলি ব্যবহার করার অনুমতি নেই (আইএসআই প্রশংসাপত্র বিষয়গুলি)
ড্যানিয়েল গ্রাস্জেকিক

এটি অবশ্যই প্রশ্নে সিরিয়াল আকার দেওয়ার জন্য নয়। জাভাস্ক্রিপ্টসরিয়ালাইজার এমন সব কিছু সিরিয়াল করে যা যা উপেক্ষা করা হয় না, যেখানে ডেটা কন্ট্রাক্ট জসনসিরাইজারের ডেটা মেম্বার বৈশিষ্ট্য প্রয়োজন। চিৎকার করার জন্য ধন্যবাদ তবে দয়া করে মনে রাখবেন আপনি আমার নামটি বানান ভুল করেছেন :)
স্টিফেন কেনেডি

25

Newtonsoft.json এর উত্তর এখানে

enum Gender { Male, Female }

class Person
{
    int Age { get; set; }

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

1
এই উত্তরের জন্য আপনাকে ধন্যবাদ, আমাকে অনেক সাহায্য করেছেন! আপনি যদি trueপাস্কেলকেসে আপনার এনামগুলি সংজ্ঞায়িত করতে চান তবে আপনি এটিটি উটকেসে সিরিয়ালাইজ করাতে চান তবে আপনার জাসনকনভার্টর টাইপের সাথে এটি যুক্ত করতে হবে:[JsonConverter(typeof(StringEnumConverter), true)]
পিট


16

আপনি JsonSerializerযদি JsonConverterঅ্যাট্রিবিউট ব্যবহার করতে না চান তবে আপনি নিজেরটিতে একটি রূপান্তরকারী যুক্ত করতে পারেন :

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

enumএই সিরিয়ালাইজেশন চলাকালীন প্রত্যেকটির জন্য এটি কাজ করবে ।


15

এখানে একটি সহজ সমাধান যা জেএসএনে একটি সার্ভার-সাইড সি # এনামকে সিরিয়ালযুক্ত করে এবং ক্লায়েন্ট-সাইডকে জনপ্রিয় করতে ফলাফলটি ব্যবহার করে <select> উপাদানটি তৈরি । এটি সহজ এনাম এবং বিটফ্ল্যাগ এনাম উভয়ের জন্যই কাজ করে।

আমি শেষ-থেকে-শেষের সমাধানটি অন্তর্ভুক্ত করেছি কারণ আমি মনে করি যে 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 ..] উপর নির্ভর করতে পারবেন না।

সার্ভার সাইড - সি #

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()সাহায্যকারী পদ্ধতিটি ব্যবহার করে - তবে চিন্তা করবেন না, এনামটি ইতিমধ্যে সিরিয়ালাইজেশনের জন্য প্রস্তুত একটি সাধারণ বেনাম প্রকার হিসাবে প্রজেক্ট করা হয়েছে বলে আপনি কোনও মানক জেএসওএন ফর্ম্যাটর ব্যবহার করতে পারেন।

জেএসএন তৈরি করা হয়েছে

[
    {"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

এইচটিএমএল আগে

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

এইচটিএমএল পরে

<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

এএসপি.নেট কোরের জন্য কেবল আপনার স্টার্টআপ ক্লাসে নিম্নলিখিতটি যুক্ত করুন:

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

1
এটি কেবল মূল নয়, সমস্ত সংস্করণের জন্য কাজ করে।
বাইকম্যান 868

11

আপনি নীচের মত জসনকনভার্টারে কল দিয়ে জসনসিরাইজারসেটেটিং তৈরি করতে পারেন।

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

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

নেট কোর এর জন্য: -

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

9

নেট কোর 3 এ এখন সিস্টেম.টেক্সট.জসনের বিল্ট-ইন ক্লাসগুলির মাধ্যমে এটি সম্ভব:

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 }

9

System.Text.Json এর সাথে Asp.Net Core 3

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

এটি একটি পুরানো প্রশ্ন তবে আমি ভেবেছিলাম আমি কেবল ক্ষেত্রেই অবদান রাখব। আমার প্রকল্পগুলিতে আমি কোনও জসন অনুরোধের জন্য পৃথক মডেল ব্যবহার করি। একটি মডেলের সাধারণত "জসন" উপসর্গের সাথে ডোমেন অবজেক্টের একই নাম থাকবে। মডেলগুলি অটোম্যাপার ব্যবহার করে ম্যাপ করা হয় । জসন মডেল একটি স্ট্রিং বৈশিষ্ট্য যা ডোমেন ক্লাসের একটি এনাম হিসাবে ঘোষণা করে, অটোম্যাপার তার স্ট্রিং উপস্থাপনায় সমাধান করবে।

আপনি যদি ভাবছেন তবে জসন সিরিয়ালাইজড ক্লাসগুলির জন্য আমার আলাদা মডেল দরকার কারণ ইনবিল্ট সিরিয়ালাইজারটি অন্যথায় বিজ্ঞপ্তি রেফারেন্স নিয়ে আসে।

আশা করি এটি কাউকে সাহায্য করবে।


অটোম্যাপারের সেই বৈশিষ্ট্যটি শিখতে পেরে ভালো লাগল ;-) [স্ক্রিপ্টআইগনোর] বৈশিষ্ট্যটি বিজ্ঞপ্তি সংক্রান্ত রেফারেন্সগুলি সরিয়ে ফেলবে
নেতৃত্বেরাগন ২

1
উহু. বৈশিষ্ট্য সম্পর্কে জানতেন না। ধন্যবাদ! আপনি কি তা আপনার পোকোসে ব্যবহার করবেন? আমি কেবল পরিষ্কার রাখার জন্য কোনও পোকো গুণাবলীর জন্য মেটাডেটাটাইপ সংজ্ঞাগুলি ব্যবহার করে নিয়েছি। বৈশিষ্ট্যটি এখনও মেটা ডেটার মাধ্যমে কাজ করবে?
এলেস পোটোকনিক হাহোনিনা

3

বিল্ট-ইন জাভাস্ক্রিপ্টসরিয়ালাইজার দিয়ে এটি সম্পাদন করতে আপনি আসলে একটি জাভাস্ক্রিপ্ট কনভার্টর ব্যবহার করতে পারেন। আপনার এনামকে উরিতে রূপান্তরিত করে আপনি এটিকে একটি স্ট্রিং হিসাবে এনকোড করতে পারেন।

আমি তারিখের জন্য এটি কীভাবে করব তা বর্ণনা করেছি তবে এটি এনামগুলিতেও ব্যবহার করা যেতে পারে। .NET জাভাস্ক্রিপ্টসরিয়ালাইজারের জন্য কাস্টম ডেটটাইম জেএসএন ফর্ম্যাট


খুব আকর্ষণীয় সমাধান! ভাগ করে নেওয়ার জন্য ধন্যবাদ.
অলিভার

1

এটি এখনও প্রাসঙ্গিক কিনা তা নিশ্চিত নয় তবে আমাকে সরাসরি একটি জসন ফাইলে লিখতে হয়েছিল এবং আমি নীচে পাইকিং করে বেশ কয়েকটি স্ট্যাকওভারফ্লো উত্তর একসাথে নিয়ে এসেছি

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

এটি আমার সমস্ত জেসন কীগুলি জেসন "বিধি" অনুসারে ছোট ছোট হাত থেকে শুরু করার আশ্বাস দেয়। এটি পরিষ্কারভাবে ইন্ডেন্টেড ফর্ম্যাট করে এবং আউটপুটে শূন্যপালা উপেক্ষা করে। স্ট্রিংয়েম কনভার্টর যুক্ত করে এটি তাদের স্ট্রিংয়ের মান সহ প্রিন্ট করে।

টীকাগুলি দিয়ে মডেলটিকে নোংরা না করে ব্যক্তিগতভাবে আমি এটিকে পরিষ্কার দেখতে পাচ্ছি I

ব্যবহার:

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

0

আমি Newtonsoft.Jsonলাইব্রেরিটি ব্যবহার করে এই সমাধানটির সমস্ত টুকরো একসাথে রেখেছি । এটি এনাম সমস্যাটি সমাধান করে এবং ত্রুটিটি পরিচালনা করে আরও ভাল করে তোলে এবং এটি আইআইএস হোস্টেড পরিষেবাদিতে কাজ করে। এটি বেশ কয়েকটি কোড, তাই আপনি এটি এখানে গিটহাবটিতে খুঁজে পেতে পারেন: https://github.com/jongrant/wcfjsonserializer/blob/master/NewtonsoftJson

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যে আমাদের এনাম মানগুলি deserializing পাশের বিপর্যয় ছাড়াই সময়ের সাথে প্রসারিত হতে পারে তা নিশ্চিত করার জন্য আমাদের একটি কাস্টম সংস্করণ প্রয়োজন (নীচের ব্যাকগ্রাউন্ড দেখুন)। ব্যবহার করেSafeEnumConverter নিচের শেষ deserialization এমনকি যদি পে লোড enum করে একটি নামে সংজ্ঞা কিভাবে 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নিউটসনফট জেএসএনের সাথে প্যাকেজযুক্ত 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]  
);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.