मुझे पता है कि निजी वासियों को संभालने की एक विशेषता है लेकिन मैं इस व्यवहार को एक डिफ़ॉल्ट के रूप में चाहता हूं, क्या इसे पूरा करने का कोई तरीका है? स्रोत को छोड़कर। इसके लिए एक सेटिंग थी तो बहुत अच्छा होगा।
जवाबों:
मैं यहाँ वास्तविक विशेषता की तलाश में आया था, जो कि 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; }।{get;private set;}, के साथ नहीं{get;}
{ get; }उसी प्रकार से काम करता है जब प्रकार के पास संपत्ति का नाम मिलान करने वाले पैरामीटर के साथ एक कंस्ट्रक्टर हो।
मैंने इसके लिए एक सोर्स डिस्ट्रीब्यूशन NuGet लिखा है, जो दो कस्टम कॉन्ट्रैक्ट रिज़ॉल्वर के साथ एक एकल फ़ाइल स्थापित करता है:
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/
DefaultMembersSearchFlags कर दिया गया है ।
{get; }बराबर नहीं है { get; private set; }। पहला तरीका के लिए property.GetSetMethod(true)रिटर्न nullऔर बाद true। इसने मुझे चौंका दिया। private set;उम्मीद के मुताबिक काम करने के लिए आपके पास deserialization होना चाहिए ।
@ डैनियल का जवाब (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()
};