अगर मेरे पास ऐसा मॉडल है:

public class Person
{
    public string Name { get; set; }
    public DateTime DOB { get; set; }
    public Dictionary<string, string> Address { get; set; }
}

जहां शब्दकोश में डेटा हो सकता है

"Number", "18"
"Line1", "Knotta Street"
"Line2", "Thrumpton-on-Thames"
"Postcode", "SW1 2AA"

क्या कोई तरीका है जिससे मैं इस मॉडल के एक उदाहरण को एक नया, अस्थायी अज्ञात ऑब्जेक्ट बनाने के लिए फ़्लैट कर सकता हूं जो इस तरह दिखेगा:

Name : Jim
DOB : 21/01/1990
Number : 18
Line1 : Knotta Street
Line2 : Thrumpton-on-Thames
Postcode : SW1 2AA

अंतिम लक्ष्य के साथ कि मैं इसे पूरी तरह से फ्लैट 1:1 प्रारूप में JSON पर आउटपुट कर सकता हूं

c#
1
jamheadart 2 सितंबर 2021, 22:31

3 जवाब

सबसे बढ़िया उत्तर

आपको बस एक चपटा शब्दकोश बनाने की जरूरत है। आप स्थिर गुणों के लिए अपनी कुंजियों और मानों को मैन्युअल रूप से जोड़कर और फिर Address शब्दकोश में अपने मौजूदा कुंजी मान जोड़े को गतिशील रूप से जोड़कर इसे प्राप्त कर सकते हैं।

व्यक्तिगत रूप से, मैं एक ऐसी विधि बनाने की सलाह देता हूं जो डेटा को समतल कर दे और इसे JSON स्ट्रिंग के रूप में वापस दे:

public class Person {
    public string Name { get; set; }
    public DateTime DOB { get; set; }
    public Dictionary<string, string> Address { get; set; }
    public string GetFlattenedJson() {
        var result = new Dictionary<string, object> {
            { "Name", Name },
            { "DOB", DOB }
        };
        foreach (var datum in Address)
            result.Add(datum.Key, datum.Value);

        return JsonConvert.SerializeObject(result);
    }
}

फिर, जब आपको फ़्लैटेड डेटा की आवश्यकता होती है, तो आप इसे उस विधि से एक्सेस कर सकते हैं:

var flatJson = myPerson.GetFlattenedJson();
1
Taco タコス 2 सितंबर 2021, 23:39

स्पष्टीकरण संपादित करें: गतिशील वस्तुएं अज्ञात वस्तुएं नहीं हैं, मैंने गतिशील के साथ प्रदर्शन किया क्योंकि यह निकटतम समाधान उपलब्ध है - एक वास्तविक अज्ञात वस्तु में एक शब्दकोश के आधार पर रनटाइम पर गुण नहीं हो सकते हैं (जब तक फ्लाई पर कोड पीढ़ी पेश नहीं की जाती है), केवल गतिशील वस्तुएं इसका समर्थन करती हैं।


आपको गतिशील गुणों के साथ एक अनाम वस्तु उत्पन्न करने के लिए डायनामिक का उपयोग करने की आवश्यकता है, आमतौर पर ExpandoObject ऐसे परिदृश्यों में उपयोग किया जाता है:

        var person = new Person
        {
            Name = "Jim",
            DOB = DateTime.UtcNow,
            Address = new Dictionary<string, string>
            {
                { "Number", "18" },
                { "Line1", "Knotta Street" },
                { "Line2", "Thrumpton-on-Thames" },
                { "Postcode", "SW1 2AA" },
            }
        };
        dynamic flatterned = new ExpandoObject();
        flatterned.Name = person.Name;
        flatterned.DOB = person.DOB;

        foreach (var kv in person.Address)
        {
            (flatterned as IDictionary<string, object>).Add(kv.Key, kv.Value);
        }

        Console.WriteLine(JsonConvert.SerializeObject(flatterned));

ध्यान दें कि जैसा कि अन्य ने टिप्पणी की है, जेएसओएन को क्रमबद्ध ऑब्जेक्ट बनाने की कोई आवश्यकता नहीं है, लेकिन आपने यही पूछा है, इसलिए मुझे लगा कि यह आपको दिखाने में मदद कर सकता है।

-1
Pranav Hosangadi 2 सितंबर 2021, 23:54

आप जो खोज रहे हैं उसे आसानी से प्राप्त करने के लिए आप ExpandoObjects का उपयोग कर सकते हैं। मैंने नीचे एक विस्तार विधि लिखी है जो आपके किसी भी वस्तु के साथ काम करेगी। हालाँकि, यह इस समय केवल Dictionary को समतल करेगा। इसे बाद में अपडेट करने का प्रयास करेंगे।

public static class ExtentionClasses
{
    public static dynamic Flatten<T>(this T item)
    {
        // Get all the properties not of type dictionary
        var regularProps = item.GetType().GetProperties().Where(x => !typeof(Dictionary<string, string>).IsAssignableFrom(x.PropertyType));
        var dictionaryProps = item.GetType().GetProperties().Where(x => typeof(Dictionary<string, string>).IsAssignableFrom(x.PropertyType));

        var outputDict = new Dictionary<object, object>();

        // Create a dynamic object
        dynamic expando = new ExpandoObject();

        // Add the regular properties
        foreach (var prop in regularProps)
        {
            AddProperty(expando, prop.Name, prop.GetValue(item));
        }

        // Add the dictionary properties
        foreach (var prop in dictionaryProps)
        {
            // convert to dict
            var val = prop.GetValue(item);
            var dict = (Dictionary<string, string>)val;

            foreach(var keyValue in dict)
            {
                AddProperty(expando, keyValue.Key, keyValue.Value);
            }
        }

        return expando;
    }

    public static void AddProperty(ExpandoObject expando, string propertyName, object propertyValue)
    {
        // ExpandoObject supports IDictionary so we can extend it like this
        var expandoDict = expando as IDictionary<string, object>;
        if (expandoDict.ContainsKey(propertyName))
            expandoDict[propertyName] = propertyValue;
        else
            expandoDict.Add(propertyName, propertyValue);
    }
} 

उपयोग उदाहरण:

var person = new Person()
{
    Name = "Jhon",
    DOB = DateTime.Today,
    Address = new Dictionary<string, string>()
    {
        {"Number", "18"},
        {"Line1", "Knotta Street"},
        {"Line2", "Thrumpton-on-Thames"},
        {"Postcode", "SW1 2AA"}
    }
};

var x = person.Flatten();

Console.WriteLine(x.Name);
Console.WriteLine(x.Postcode);

और परिणाम:

Jhon
SW1 2AA

इस तरह आप JsonConvert.SerializeObject(x) के साथ Json परिणाम को प्रिंट करने से पहले अपनी इच्छित वस्तु का संदर्भ दे सकते हैं

-1
user15119845 3 सितंबर 2021, 00:15