c# - शब्दकोष में<<string, object> कन्वर्ट करें। क्या यह संभव है?




.net json (4)

मेरे पास एक वेब एपीआई विधि है जो एक JObject प्रॉपर्टी में एक मनमाना JObject पेलोड स्वीकार करता है। जैसे कि मुझे नहीं पता कि क्या आ रहा है, लेकिन मुझे अभी भी इसे .NET प्रकारों में अनुवाद करना होगा। मैं एक Dictionary<string,object> रखना चाहूंगा ताकि मैं किसी भी तरह से इससे निपट सकूं।

मैंने बहुत खोज की है, लेकिन कुछ भी नहीं खोज सका और इस रूपांतरण को करने के लिए एक गन्दा तरीका शुरू कर रहा हूं, कुंजी द्वारा कुंजी, मूल्य द्वारा मूल्य। वहाँ यह करने के लिए एक आसान तरीका है?

इनपुट ->

JObject person = new JObject(
    new JProperty("Name", "John Smith"),
    new JProperty("BirthDate", new DateTime(1983, 3, 20)),
    new JProperty("Hobbies", new JArray("Play football", "Programming")),
    new JProperty("Extra", new JObject(
        new JProperty("Foo", 1),
        new JProperty("Bar", new JArray(1, 2, 3))
    )
)

धन्यवाद!


मैंने दोनों उत्तरों के मिश्रण का उपयोग करते हुए समाप्त कर दिया क्योंकि वास्तव में किसी ने भी इसका उपयोग नहीं किया था।

ToObject () एक JSON ऑब्जेक्ट में गुणों का पहला स्तर कर सकता है, लेकिन नेस्टेड ऑब्जेक्ट्स को Dictionary () में परिवर्तित नहीं किया जाएगा।

ToObject के रूप में मैन्युअल रूप से सब कुछ करने की कोई आवश्यकता नहीं है () पहले स्तर के गुणों के साथ बहुत अच्छा है।

यहाँ कोड है:

public static class JObjectExtensions
{
    public static IDictionary<string, object> ToDictionary(this JObject @object)
    {
        var result = @object.ToObject<Dictionary<string, object>>();

        var JObjectKeys = (from r in result
                           let key = r.Key
                           let value = r.Value
                           where value.GetType() == typeof(JObject)
                           select key).ToList();

        var JArrayKeys = (from r in result
                          let key = r.Key
                          let value = r.Value
                          where value.GetType() == typeof(JArray)
                          select key).ToList();

        JArrayKeys.ForEach(key => result[key] = ((JArray)result[key]).Values().Select(x => ((JValue)x).Value).ToArray());
        JObjectKeys.ForEach(key => result[key] = ToDictionary(result[key] as JObject));

        return result;
    }
}

इसमें किनारे के मामले हो सकते हैं जहां यह काम नहीं करेगा और प्रदर्शन इसकी सबसे मजबूत गुणवत्ता नहीं है।

धन्यवाद दोस्तों!


यदि आपके पास JObject हैं, तो निम्नलिखित कार्य कर सकते हैं:

JObject person;
var values = person.ToObject<Dictionary<string, object>>();

यदि आपके पास एक JObject नहीं है, तो आप JObject साथ एक बना सकते हैं। Newtonsoft.Json.Linq एक्सटेंशन विधि:

using Newtonsoft.Json.Linq;

var values = JObject.FromObject(person).ToObject<Dictionary<string, object>>();

अन्यथा, यह उत्तर आपको सही दिशा में इंगित कर सकता है, क्योंकि यह एक शब्दकोश के लिए JSON स्ट्रिंग का वर्णन करता है।

var values = JsonConvert.DeserializeObject<Dictionary<string, object>>(json);

यहाँ एक स्थापना संस्करण है: मैंने JArrays / JObjects में निहित JArrays JArrays को पुनः प्राप्त करने के लिए कोड को संशोधित किया है, जो कि स्वीकृत उत्तर नहीं देता है, जैसा कि @Nawaz द्वारा बताया गया है।

using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json.Linq;

public static class JsonConversionExtensions
{
    public static IDictionary<string, object> ToDictionary(this JObject json)
    {
        var propertyValuePairs = json.ToObject<Dictionary<string, object>>();
        ProcessJObjectProperties(propertyValuePairs);
        ProcessJArrayProperties(propertyValuePairs);
        return propertyValuePairs;
    }

    private static void ProcessJObjectProperties(IDictionary<string, object> propertyValuePairs)
    {
        var objectPropertyNames = (from property in propertyValuePairs
            let propertyName = property.Key
            let value = property.Value
            where value is JObject
            select propertyName).ToList();

        objectPropertyNames.ForEach(propertyName => propertyValuePairs[propertyName] = ToDictionary((JObject) propertyValuePairs[propertyName]));
    }

    private static void ProcessJArrayProperties(IDictionary<string, object> propertyValuePairs)
    {
        var arrayPropertyNames = (from property in propertyValuePairs
            let propertyName = property.Key
            let value = property.Value
            where value is JArray
            select propertyName).ToList();

        arrayPropertyNames.ForEach(propertyName => propertyValuePairs[propertyName] = ToArray((JArray) propertyValuePairs[propertyName]));
    }

    public static object[] ToArray(this JArray array)
    {
        return array.ToObject<object[]>().Select(ProcessArrayEntry).ToArray();
    }

    private static object ProcessArrayEntry(object value)
    {
        if (value is JObject)
        {
            return ToDictionary((JObject) value);
        }
        if (value is JArray)
        {
            return ToArray((JArray) value);
        }
        return value;
    }
}

विस्तार के तरीकों के लिए एक अच्छे उपयोग के मामले की तरह लगता है - मेरे पास कुछ झूठ था जो कि Json.NET (धन्यवाद NuGet!) में बदलने के लिए बहुत सीधा था।

बेशक, यह जल्दी से एक साथ हैक किया गया है - आप इसे साफ करना चाहते हैं, आदि।

public static class JTokenExt
{
    public static Dictionary<string, object> 
         Bagify(this JToken obj, string name = null)
    {
        name = name ?? "obj";
        if(obj is JObject)
        {
            var asBag =
                from prop in (obj as JObject).Properties()
                let propName = prop.Name
                let propValue = prop.Value is JValue 
                    ? new Dictionary<string,object>()
                        {
                            {prop.Name, prop.Value}
                        } 
                    :  prop.Value.Bagify(prop.Name)
                select new KeyValuePair<string, object>(propName, propValue);
            return asBag.ToDictionary(kvp => kvp.Key, kvp => kvp.Value);
        }
        if(obj is JArray)
        {
            var vals = (obj as JArray).Values();
            var alldicts = vals
                .SelectMany(val => val.Bagify(name))
                .Select(x => x.Value)
                .ToArray();
            return new Dictionary<string,object>()
            { 
                {name, (object)alldicts}
            };
        }
        if(obj is JValue)
        {
            return new Dictionary<string,object>()
            { 
                {name, (obj as JValue)}
            };
        }
        return new Dictionary<string,object>()
        { 
            {name, null}
        };
    }
}




json.net