Json.Net में निजी बसने वाले


93

मुझे पता है कि निजी वासियों को संभालने की एक विशेषता है लेकिन मैं इस व्यवहार को एक डिफ़ॉल्ट के रूप में चाहता हूं, क्या इसे पूरा करने का कोई तरीका है? स्रोत को छोड़कर। इसके लिए एक सेटिंग थी तो बहुत अच्छा होगा।


1
मैं इस या उस उत्तर की तलाश में था ।
— मारबेल 4२

जवाबों:


112

मैं यहाँ वास्तविक विशेषता की तलाश में आया था, जो कि Json.NET को deserializing के समय एक बड़ी संपत्ति को आबाद करता है, और यह बस है [JsonProperty]:

[JsonProperty]
public Guid? ClientId { get; private set; }

दूसरा तरीका

बस एक निर्माता प्रदान करें जिसमें आपकी संपत्ति से मेल खाने वाला पैरामीटर हो:

public class Foo
{
    public string Bar { get; }

    public Foo(string bar)
    {
        Bar = bar;
    }
}

अब यह काम करता है:

string json = "{ \"bar\": \"Stack Overflow\" }";

var deserialized = JsonConvert.DeserializeObject<Foo>(json);
Console.WriteLine(deserialized.Bar); // Stack Overflow

मैं इस दृष्टिकोण को पसंद करता हूँ जहाँ से संभव हो:

  • यह आपको विशेषताओं के साथ अपने गुणों को सजाने की आवश्यकता नहीं है।
  • यह { get; private set; }और सिर्फ दोनों के साथ काम करता है { get; }।

19
सिर्फ एक छोटे से ध्यान दें: यह साथ काम करता है {get;private set;}, के साथ नहीं{get;}
— tymtam

8
बस थोड़ा सा अपडेट। अब यह {get;} के साथ भी काम करता है;
— हवलदार

1
@ हव क्या संस्करण है? मैंने अभी अभी v11.0.2 का परीक्षण किया है और यह {get;} काम नहीं करता है
— tymtam

1
@tymtam मुझे लगता है कि यह केवल { get; }उसी प्रकार से काम करता है जब प्रकार के पास संपत्ति का नाम मिलान करने वाले पैरामीटर के साथ एक कंस्ट्रक्टर हो।
— साब अमिनी

2
@tymtam ने इस विकल्प और एक उदाहरण के साथ उत्तर को अपडेट किया।
— साब अमीनी

77

अपडेट किया गया, नया उत्तर

मैंने इसके लिए एक सोर्स डिस्ट्रीब्यूशन NuGet लिखा है, जो दो कस्टम कॉन्ट्रैक्ट रिज़ॉल्वर के साथ एक एकल फ़ाइल स्थापित करता है:

  • PrivateSetterContractResolver
  • PrivateSetterCamelCasePropertyNamesContractResolver

NuGet स्थापित करें:

Install-Package JsonNet.PrivateSettersContractResolvers.Source

तो बस किसी भी resolvers का उपयोग करें:

var settings = new JsonSerializerSettings
{
    ContractResolver = new PrivateSetterContractResolver()
};

var model = JsonConvert.DeserializeObject<Model>(json, settings);

आप इसके बारे में यहां पढ़ सकते हैं: http://danielwertheim.se/json-net-pStreet-setters-nuget/

GitHub repo: https://github.com/danielwertheim/jsonnet-privatesetterscontroresresversvers

पुराना उत्तर (अभी भी मान्य)

दो विकल्प हैं जो समस्या को हल कर सकते हैं।

ऑल्ट 1: डिसेरिएलाइज़र पर

ContractResolver.DefaultMembersSearchFlags =
                             DefaultMembersSearchFlags | BindingFlags.NonPublic;

डिफ़ॉल्ट क्रमांकन विकल्प सभी प्रकार के वर्ग सदस्य का समर्थन करता है। इसलिए यह समाधान खेतों सहित सभी निजी सदस्यों के प्रकारों को वापस कर देगा। मैं केवल निजी बसने वालों का समर्थन करना चाहता हूं।

Alt2: कोई कस्टम अनुबंध बनाएँ:

इसलिए यह बेहतर विकल्प है क्योंकि हम केवल गुणों की जांच करते हैं।

public class SisoJsonDefaultContractResolver : DefaultContractResolver 
{
    protected override JsonProperty CreateProperty(
        MemberInfo member,
        MemberSerialization memberSerialization)
    {
        //TODO: Maybe cache
        var prop = base.CreateProperty(member, memberSerialization);

        if (!prop.Writable)
        {
            var property = member as PropertyInfo;
            if (property != null)
            {
                var hasPrivateSetter = property.GetSetMethod(true) != null;
                prop.Writable = hasPrivateSetter;
            }
        }

        return prop;
    }
}

अधिक जानकारी के लिए, मेरी पोस्ट पढ़ें: http://danielwertheim.se/json-net-pStreet-setters/


2
अपनी पोस्ट से लिंक करना daniel.wertheim.se/2010/11/06/json-net-pStreet-setters
— Jafin

1
@ जाफिन url मर चुका है, danielwertheim.wordpress.com/2010/11/06/… अब है
— क्रिस मैरिसिक

1
लगता है कि ऑल्ट 2 निश्चित रूप से आजकल जाने का रास्ता है। पदावनतDefaultMembersSearchFlags कर दिया गया है ।
— टोड मेनियर

4
सी # 6 के साथ, के {get; }बराबर नहीं है { get; private set; }। पहला तरीका के लिए property.GetSetMethod(true)रिटर्न nullऔर बाद true। इसने मुझे चौंका दिया। private set;उम्मीद के मुताबिक काम करने के लिए आपके पास deserialization होना चाहिए ।
— emragins

ऐसा लगता है कि इंस्टॉल-पैकेज JsonNet.ContractResolvers का उपयोग अब किया जाना चाहिए। github.com/danielwertheim/jsonnet-contractresolvers
— निरपेक्ष

14

@ डैनियल का जवाब (Alt2) हाजिर है, लेकिन मुझे निजी सेटर और गेटर्स दोनों के लिए काम करने के लिए इसकी आवश्यकता है (मैं एक एपीआई के साथ काम कर रहा हूं, जिसमें वास्तव में कुछ केवल लिखने योग्य चीजें हैं, जैसे user.password।) यहाँ है कि मैंने क्या किया है:

public class NonPublicPropertiesResolver : DefaultContractResolver
{
    protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) {
        var prop = base.CreateProperty(member, memberSerialization);
        if (member is PropertyInfo pi) {
            prop.Readable = (pi.GetMethod != null);
            prop.Writable = (pi.SetMethod != null);
        }
        return prop;
    }
}

इस प्रकार पंजीकृत:

JsonConvert.DefaultSettings = () => new JsonSerializerSettings {
    ContractResolver = new NonPublicPropertiesResolver()
};
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.