অভিধান সিরিয়াল করার সময় কেসিং রাখুন


92

আমার একটি ওয়েব এপিআই প্রকল্পটি এটির মতো কনফিগার করা হচ্ছে:

config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();

তবে, আমি চাই চাই অভিধানের কীগুলি কেসিংটি অপরিবর্তিত থাকে। Newtonsoft.Jsonসিরিয়ালাইজেশন চলাকালীন আমি কেসটি অপরিবর্তিত থাকতে চাই তা বোঝাতে কোনও শ্রেণীর কাছে আমি কী কোনও গুণাবলীর ব্যবহার করতে পারি?

public class SomeViewModel
{
    public Dictionary<string, string> Data { get; set; }    
}

4
আপনি কি ডিফল্ট সমাধানকারী চেষ্টা করেছেন?
— ম্যাথু

4
@ ম্যাথু না, আমি নেই; কোডটি কেমন হবে এমন উদাহরণ দিয়ে আপনি ব্যাখ্যা করতে পারেন? দ্রষ্টব্য, আমি এখনও আমার সমস্ত ওয়েব এপিআই অনুরোধগুলির জন্য ক্যামেলের কেস সিরিয়ালাইজেশন চাই, আমি কেবল শ্রেণীর জন্য কাস্টম সিরিয়ালাইজেশন চাই (বা কোনও অভিধান কীগুলির জন্য)।
— zafeiris.m

উত্তর:


133

এটি করার কোনও বৈশিষ্ট্য নেই, তবে আপনি এটি সমাধানকারীকে কাস্টমাইজ করে এটি করতে পারেন।

আমি দেখতে পাচ্ছি যে আপনি ইতিমধ্যে একটি ব্যবহার করছেন CamelCasePropertyNamesContractResolver। যদি আপনি সে থেকে একটি নতুন সমাধানকারী শ্রেণি সংগ্রহ করেন এবং CreateDictionaryContract()পদ্ধতিটি ওভাররাইড করেন তবে আপনি একটি বিকল্প DictionaryKeyResolverফাংশন সরবরাহ করতে পারেন যা মূল নামগুলি পরিবর্তন করে না।

আপনার প্রয়োজনীয় কোডটি এখানে রয়েছে:

class CamelCaseExceptDictionaryKeysResolver : CamelCasePropertyNamesContractResolver
{
    protected override JsonDictionaryContract CreateDictionaryContract(Type objectType)
    {
        JsonDictionaryContract contract = base.CreateDictionaryContract(objectType);

        contract.DictionaryKeyResolver = propertyName => propertyName;

        return contract;
    }
}

ডেমো:

class Program
{
    static void Main(string[] args)
    {
        Foo foo = new Foo
        {
            AnIntegerProperty = 42,
            HTMLString = "<html></html>",
            Dictionary = new Dictionary<string, string>
            {
                { "WHIZbang", "1" },
                { "FOO", "2" },
                { "Bar", "3" },
            }
        };

        JsonSerializerSettings settings = new JsonSerializerSettings
        {
            ContractResolver = new CamelCaseExceptDictionaryKeysResolver(),
            Formatting = Formatting.Indented
        };

        string json = JsonConvert.SerializeObject(foo, settings);
        Console.WriteLine(json);
    }
}

class Foo
{
    public int AnIntegerProperty { get; set; }
    public string HTMLString { get; set; }
    public Dictionary<string, string> Dictionary { get; set; }
}

উপরে থেকে আউটপুট এখানে। লক্ষ্য করুন যে শ্রেণীর সমস্ত সম্পত্তির নাম উট-কেসযুক্ত তবে অভিধান কীগুলি তাদের মূল আবরণ ধরে রেখেছে।

{
  "anIntegerProperty": 42,
  "htmlString": "<html></html>",
  "dictionary": {
    "WHIZbang": "1",
    "FOO": "2",
    "Bar": "3"
  }
}

4
এফওয়াইআই, সম্পত্তি সম্পত্তি রিসোলভার এখন অপ্রচলিত। মনে হচ্ছে ঠিক contract.DictionaryKeyResolver = key => key;কাজ করে।
— জন গিয়েজেন

4
এটি এখনও বেনামে প্রকারের সাথে খুব প্রাসঙ্গিক, বিশেষত যখন আমরা বেশিরভাগ কাঠামোর জন্য উট কেসিং চাই না, তবে চাই না অভিধানের ভিতরে থাকা কীগুলি উটচিহ্নিত হোক।
— ক্রিস শ্যাচলার

ক্রিসের সাথে একেবারে একমত। আমি কেবল আমার জাভাস্ক্রিপ্টে হুপের মধ্য দিয়ে যেতে বাধ্য হয়েছিল কারণ আমি অভিধানকে উটচানা থেকে আটকাতে পারি না। দেখা যাচ্ছে যে এক লাইনের কোডই এই সমস্যাটি সমাধান করবে (এবং আমার জাভাস্ক্রিপ্টকে অনেক সহজ করে তুলবে)!
— স্টিফেন চুং

@ ব্রায়ানরোজার্স দুর্দান্ত কাজ করে! তবে, আপনি কি জানেন DictionaryKeyResolverযে আমার অভিধান অভিধানে যদি কিছু কাস্টম অ্যাট্রিবিউট থাকে তবে আমি কেবল এটিই ব্যবহার করতে পারি ?
— মুগেন

@ মিগেন আমার মাথার উপরে নেই আমি এটি একটি নতুন প্রশ্ন হিসাবে জিজ্ঞাসা সুপারিশ করব। আপনার যদি প্রসঙ্গ সরবরাহের প্রয়োজন হয় তবে আপনি এই প্রশ্নের সাথে আবার লিঙ্ক করতে পারেন।
— ব্রায়ান রজার্স

67

Json.NET 9.0.1NamingStrategy এই ধরণের সমস্যাটি পরিচালনা করার জন্য শ্রেণি শ্রেণিবিন্যাসের সূচনা করেছিল । এটি চুক্তির সমাধান থেকে পৃথক, লাইটওয়েট শ্রেণিতে সম্পত্তি নাম অ্যালগরিদমিক পুনর্নির্মাণের যুক্তি সন্ধান করে যা অভিধান কীগুলি , সুস্পষ্টভাবে নির্দিষ্ট সম্পত্তির নাম এবং এক্সটেনশন ডেটার নামগুলি ( 10.0.1 এ ) পুনরায় পুনরায় তৈরি করা হয়েছে কিনা তা নিয়ন্ত্রণের অনুমতি দেয় ।

উদাহরণস্বরূপ ব্যবহার করে DefaultContractResolverএবং সেটিংস স্থাপন করে NamingStrategyআপনি CamelCaseNamingStrategyউট-কেসযুক্ত সম্পত্তির নাম এবং অমার্জনিত অভিধান কীগুলি এটিকে সেট করে জেনসন তৈরি করতে পারেন JsonSerializerSettings.ContractResolver:

var resolver = new DefaultContractResolver
{
    NamingStrategy = new CamelCaseNamingStrategy
    {
        ProcessDictionaryKeys = false,
        OverrideSpecifiedNames = true
    }
};
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = resolver;

মন্তব্য:

  • বর্তমান প্রয়োগটি CamelCasePropertyNamesContractResolverএটিও উল্লেখ করে যে। বিশদভাবে সুনির্দিষ্টভাবে চিহ্নিত সম্পত্তির নাম সহ নেট সদস্যদের (যেমন JsonPropertyAttribute.PropertyNameসেট করা হয়েছে) তাদের নামগুলি পুনরায় রেখে দেওয়া উচিত:

    public CamelCasePropertyNamesContractResolver()
    {
        NamingStrategy = new CamelCaseNamingStrategy
        {
            ProcessDictionaryKeys = true,
            OverrideSpecifiedNames = true
        };
    }
    

    উপরের resolverএই আচরণ সংরক্ষণ করে। আপনি যদি এটি না চান তবে সেট করুন OverrideSpecifiedNames = false।

  • জসন.এনইটের কয়েকটি অন্তর্নির্মিত নামকরণ কৌশল রয়েছে:

    1. CamelCaseNamingStrategy। একটি উটের কেস নামকরণের কৌশলটিতে পূর্বে এম্বেড থাকা নাম-রিম্যাপিং যুক্তি রয়েছে CamelCasePropertyNamesContractResolver।
    2. SnakeCaseNamingStrategy। একটি সাপের কেস নামকরণের কৌশল।
    3. DefaultNamingStrategy। ডিফল্ট নামকরণ কৌশল। সম্পত্তির নাম এবং অভিধান কীগুলি অপরিবর্তিত।

    বা, আপনি বিমূর্ত বেস বর্গ থেকে উত্তরাধিকারসূত্রে তৈরি করে নিজের তৈরি করতে পারেন NamingStrategy।

  • যদিও এটি সংশোধন করা সম্ভব NamingStrategyএকটি দৃষ্টান্ত এর CamelCasePropertyNamesContractResolver, আধুনিক যেহেতু বিশ্বব্যাপী প্রতিটি টাইপ সমস্ত উদাহরণ জুড়ে শেয়ার চুক্তি তথ্য , এই অপ্রত্যাশিত পার্শ্ব প্রতিক্রিয়া হতে পারে আপনার আবেদন একাধিক দৃষ্টান্ত ব্যবহার করার চেষ্টা করে যদি CamelCasePropertyNamesContractResolver। এ জাতীয় কোনও সমস্যা নেই DefaultContractResolver, সুতরাং কেসিং লজিকের কোনও কাস্টমাইজেশন প্রয়োজন হলে এটি ব্যবহার করা নিরাপদ।


এই সমাধানটি কোনও সম্পত্তির জন্য কাজ করছে না public Dictionary<string, Dictionary<string, string>> Values { get; set; }। এটি এখনও অভ্যন্তরীণ অভিধান কীগুলির জন্য উটকেস করে।
— হিক্যালকান

@ হিক্যালকান - যখন আমি আপনার যথাযথ সমস্যাটি পুনরুত্পাদন করতে পারিনি, তখন একাধিক উদাহরণ ব্যবহার করার সময় আমি একটি সমস্যা খুঁজে পেতে সক্ষম হয়েছি CamelCasePropertyNamesContractResolver। মূলত NamingStrategyপ্রথমটির জন্য দ্বিতীয় দ্বারা উত্পন্ন চুক্তিগুলিকে প্রভাবিত করবে। যে পারে হতে কি আপনি দেখতে পান। পরিবর্তে নতুন প্রস্তাবনা ব্যবহার করে দেখুন এবং আপনার সমস্যার সমাধান করে দিলে আমাকে জানান।
— dbc

4
এটি কি নমনীয় NamingStrategy, যাতে এটি উটের কেস এবং পাস্কেল উভয় ক্ষেত্রেই পার্স করতে সক্ষম?
— শিমি ওয়েটজ্যান্ডলার

@dbc প্রাথমিক কোড নমুনায়, কী হওয়ার configকথা?
— রায়ান লুন্ডি 16

@RyanLundy - আমি এটা প্রাথমিক প্রশ্ন, যা কোডের নিম্নলিখিত লাইন দেখিয়েছেন থেকে অনুলিপি: config.Formatters.JsonFormatter.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver();। এটা তোলে MVC 4 ওয়েব এপিআই বলে মনে হচ্ছে HttpConfiguration, দেখুন কিভাবে MVC 4 ওয়েব এপিআই মধ্যে Json.NET জন্য সেট কাস্টম JsonSerializerSettings কিভাবে? ।
— ডিবিসি

12

এটি একটি খুব সুন্দর উত্তর। তবে কেন শুধু ওভাররাইড করবেন না ResolveDictionaryKey?

class CamelCaseExceptDictionaryResolver : CamelCasePropertyNamesContractResolver
    {
        #region Overrides of DefaultContractResolver

        protected override string ResolveDictionaryKey(string dictionaryKey)
        {
            return dictionaryKey;
        }

        #endregion
    }

অনেকটাই ভাগ করে নেওয়ার জন্য ধন্যবাদ।
— আবু আবদুল্লাহ

1

নির্বাচিত উত্তরটি নিখুঁত তবে আমি অনুমান করি যে আমি এটি টাইপ করার সময়, চুক্তি সমাধানকারীকে অবশ্যই এটির মতো কিছুতে পরিবর্তন করতে হবে কারণ অভিধানকিরিয়েসোলভার আর উপস্থিত নেই :)

public class CamelCaseExceptDictionaryKeysResolver : CamelCasePropertyNamesContractResolver
    {
        protected override JsonDictionaryContract CreateDictionaryContract(Type objectType)
        {
            JsonDictionaryContract contract = base.CreateDictionaryContract(objectType);
            contract.PropertyNameResolver = propertyName => propertyName;
            return contract;
        }
    }

4
আসলে বিপরীতটি সত্য। আপনি অবশ্যই জসন.নেটের একটি পুরানো সংস্করণ ব্যবহার করছেন। সংস্করণ 7.0.1 এDictionaryKeyResolver যুক্ত করা হয়েছিল এবং এটি অপ্রচলিত হিসাবে চিহ্নিত হয়েছে। PropertyNameResolver
— ব্রায়ান রজার্স
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.