JSON कुंजियों को सुनिश्चित करना .NET में लोअरकेस है


103

क्या यह सुनिश्चित करने के लिए .NET में JSON का उपयोग करने का सरल तरीका है कि कुंजियों को निचले मामले के रूप में भेजा जाए?

फिलहाल मैं newtonsoft की Json.NET लाइब्रेरी का उपयोग कर रहा हूं और बस उपयोग कर रहा हूं

string loginRequest = JsonConvert.SerializeObject(auth);

इस मामले authमें सिर्फ निम्नलिखित वस्तु है

public class Authority
{
    public string Username { get; set; }
    public string ApiToken { get; set; }
}

इसका परिणाम यह होगा

{"Username":"Mark","ApiToken":"xyzABC1234"}

वहाँ सुनिश्चित करना है कि एक रास्ता है usernameऔर apitokenकुंजी लोअरकेस के रूप में के माध्यम से आते हैं?

मैं इसे केवल String.ToLower()पाठ्यक्रम के माध्यम से नहीं चलाना चाहता क्योंकि मूल्य usernameऔर apitokenमिश्रित मामले हैं।

मुझे लगता है कि मैं प्रोग्राम कर सकता हूं और मैन्युअल रूप से JSON स्ट्रिंग बना सकता हूं, लेकिन मुझे लगभग 20 या तो JSON डेटा स्ट्रिंग्स के लिए इसकी आवश्यकता है और मैं देख रहा हूं कि क्या मैं खुद को कुछ समय के लिए बचा सकता हूं। मैं सोच रहा था कि क्या कोई पहले से ही निर्मित पुस्तकालय हैं जो आपको प्रमुख निर्माण के लिए लोअरकेस लागू करने की अनुमति देते हैं।


हो सकता है कि json serialization lib कुछ प्रकार की सीरियलाइज़ेशन विशेषताएँ प्रदान करता है जिनका उपयोग आप अपनी संपत्तियों के json-serialized नामों को बदलने के लिए कर सकते हैं?
tdammers

@ दोस्त, धन्यवाद मैं कुछ ऐसा करने की कोशिश कर रहा हूं जो ऐसा करता है, लेकिन अभी तक असफल है। यहां किसी से उम्मीद करना मुझे इस ओर इशारा कर सकता है।
मार्क

1
यह उस स्थिति में उपयोगी हो सकता है जब आप एक शब्द के साथ एकरूप होते हैं।
लिपोटम

हुह। मुझे विपरीत समस्या आ रही है ... यह भी - यह हास्यास्पद है कि आप "उपयोगकर्ता नाम" मिश्रित मामला है। क्या आपका मतलब "यूजरनेम" था?
ब्रेनस्ल्गस 83

कोई बात नहीं कि मिश्रित स्थिति बने रहने के लिए जिन मूल्यों की आवश्यकता होती है केवल वही हैं जिन्हें मुझे छूने की आवश्यकता है। मान अकेले छोड़ दें।
मार्क

जवाबों:


176

आप इसके लिए एक कस्टम कॉन्ट्रैक्ट रिज़ॉल्वर बना सकते हैं। निम्न अनुबंध रिज़ॉल्वर सभी कुंजियों को लोअरकेस में बदल देगा:

public class LowercaseContractResolver : DefaultContractResolver
{
    protected override string ResolvePropertyName(string propertyName)
    {
        return propertyName.ToLower();
    }
}

उपयोग:

var settings = new JsonSerializerSettings();
settings.ContractResolver = new LowercaseContractResolver();
var json = JsonConvert.SerializeObject(authority, Formatting.Indented, settings);

विल परिणाम:

{"username":"Mark","apitoken":"xyzABC1234"}

यदि आप हमेशा इसका उपयोग करना चाहते हैं LowercaseContractResolver, तो खुद को दोहराने से बचने के लिए इसे कक्षा में लपेटने पर विचार करें:

public class LowercaseJsonSerializer
{
    private static readonly JsonSerializerSettings Settings = new JsonSerializerSettings
    {
        ContractResolver = new LowercaseContractResolver()
    };

    public static string SerializeObject(object o)
    {
        return JsonConvert.SerializeObject(o, Formatting.Indented, Settings);
    }

    public class LowercaseContractResolver : DefaultContractResolver
    {
        protected override string ResolvePropertyName(string propertyName)
        {
            return propertyName.ToLower();
        }
    }
}

जिसका उपयोग इस तरह किया जा सकता है:

var json = LowercaseJsonSerializer.SerializeObject(new { Foo = "bar" });
// { "foo": "bar" }

ASP.NET MVC4 / WebAPI

यदि आप ASP.NET MVC4 / WebAPI का उपयोग कर रहे हैं, तो आप CamelCasePropertyNamesContractResolverNewtonsoft.Json लाइब्रेरी से उपयोग कर सकते हैं जो डिफ़ॉल्ट रूप से शामिल है।


रिवर्स में ऐसा करने का कोई उचित तरीका? विघटन के लिए?
शॉन रोवन

1
@Anzeo मैंने खुद ऐसा करने की कोशिश नहीं की है, और मुझे इसके बारे में कोई जानकारी नहीं मिली है। एक समाधान होगा कि आप अपनी ही कक्षा में JsonConvert.SerializeObject को लपेटें। मेरा अपडेट देखें।
एलेक्सन

3
ऐसा लगता है, यह कस्टम कॉन्ट्रेक्टसोलर JsonProperty विशेषता को ध्यान में नहीं रखता है, यदि आप अपवाद निर्दिष्ट करना चाहते हैं ... उदाहरण के लिए [JsonProperty ("alternateName") अभी भी नीचा हो जाता है या ऐसा करने का एक और तरीका है?
rekna

2
+1 ओर इशारा करने के लिए CamelCasePropertyNamesContractResolver। अब मैंने पाया System.Net.Http.Formatting.JsonContractResolverकि WebAPI में डिफ़ॉल्ट है और यह वर्ग आंतरिक है। मैं JsonContractResolverऊंट मामले के साथ फिर से लिखना चाहता हूं । किसी ने इसे सार्वजनिक होने की सूचना दी aspnetwebstack.codeplex.com/workitem/228
CallMeLaNN

10
CamelCasePropertyNamesContratResolverसंपत्तियों को लोअरकेस में न बदलें, सिर्फ पहला चार।
toxine

23
protected void Application_Start() {
    JsonConfig.Configure();   
}

public static class JsonConfig
{
    public static void Configure(){
        var formatters = GlobalConfiguration.Configuration.Formatters;
        var jsonFormatter = formatters.JsonFormatter;
        var settings = jsonFormatter.SerializerSettings;

        settings.ContractResolver = new CamelCasePropertyNamesContractResolver();
    }
}

10

में Json.NET 9.0.1 और बाद में इसे सुनिश्चित करना है कि सभी संपत्ति के नाम एक कस्टम का उपयोग करके लोअरकेस में बदल दिए जाते संभव है NamingStrategy। यह क्लास कॉन्ट्रैक्ट रिज़ॉल्वर से एक अलग, हल्के ऑब्जेक्ट पर सेट किए जाने वाले प्रॉपर्टी नामों के एल्गोरिदम रीमैपिंग के तर्क को निकालता है DefaultContractResolver.NamingStrategy। ऐसा करने से एक रिवाजContractResolver बनाने की आवश्यकता से बचा जाता है और इस प्रकार उन रूपरेखाओं को एकीकृत करना आसान हो सकता है जिनके पास पहले से ही अपने स्वयं के अनुबंध रिज़ॉल्वर हैं।

LowercaseNamingStrategyनिम्नानुसार परिभाषित करें :

public class LowercaseNamingStrategy : NamingStrategy
{
    protected override string ResolvePropertyName(string name)
    {
        return name.ToLowerInvariant();
    }
}

फिर इस प्रकार क्रमबद्ध करें:

var settings = new JsonSerializerSettings
{
    ContractResolver = new DefaultContractResolver { NamingStrategy = new LowercaseNamingStrategy() },
};
string loginRequest = JsonConvert.SerializeObject(auth, settings);

टिप्पणियाँ -

  • उपयोग string.ToLowerInvariant()सुनिश्चित करता है कि सभी स्थानों में एक ही अनुबंध उत्पन्न होता है।

  • चाहे ओवरराइड संपत्ति के नाम, शब्दकोश कुंजी और विस्तार डेटा नामों लोवरकेस को नियंत्रित करने के लिए, आप सेट कर सकते हैं NamingStrategy.OverrideSpecifiedNames, NamingStrategy.ProcessDictionaryKeysया NamingStrategy.ProcessExtensionDataNamesकरने के लिए (Json.NET 10.0.1 और बाद में) true

  • आप सर्वश्रेष्ठ प्रदर्शन के लिए अनुबंध रिज़ॉल्वर को कैश करना चाह सकते हैं ।

  • यदि आपके पास अपने ढांचे में सीरीज़र सेटिंग्स तक पहुंच नहीं है, तो आप NamingStrategyअपनी वस्तु पर सीधे आवेदन कर सकते हैं:

    [JsonObject(NamingStrategyType = typeof(LowercaseNamingStrategy))]
    public class Authority
    {
        public string Username { get; set; }
        public string ApiToken { get; set; }
    }
  • संशोधित मत करो NamingStrategyकी CamelCasePropertyNamesContractResolver। यह अनुबंध रिज़ॉल्वर अपने सभी उदाहरणों में वैश्विक स्तर पर जानकारी साझा करता है, और इसलिए किसी एक उदाहरण को संशोधित करने से अप्रत्याशित दुष्प्रभाव हो सकते हैं।


8

आप "JsonProperty" का उपयोग कर सकते हैं:

उपयोग:

public class Authority
{
    [JsonProperty("userName")] // or [JsonProperty("username")]
    public string Username { get; set; }
    [JsonProperty("apiToken")] // or [JsonProperty("apitoken")]
    public string ApiToken { get; set; }
}

var json  = JsonConvert.SerializeObject(authority);

0

मेरे लिए मैंने कुछ अन्य उत्तरों के संयोजन का उपयोग किया और इसके साथ समाप्त हुआ

        return JsonConvert.SerializeObject(obj, Formatting.Indented, new JsonSerializerSettings
        {
            ContractResolver = new CamelCasePropertyNamesContractResolver()
        });

एक समाधान के करीब था जिसे मैं ढूंढ रहा था क्योंकि मैं अपना खुद का निर्माण नहीं करना चाहता था

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.