मैं C # का उपयोग करके .NET में JSON स्वरूपित कैसे करूँ?


256

मैं .NET JSON पार्सर का उपयोग कर रहा हूं और अपनी कॉन्फिग फाइल को क्रमबद्ध करना चाहूंगा ताकि यह पठनीय हो। इसलिए इसके बजाय:

{"blah":"v", "blah2":"v2"}

मैं कुछ अच्छे चाहूँगा जैसे:

{
    "blah":"v", 
    "blah2":"v2"
}

मेरा कोड कुछ इस तरह है:

using System.Web.Script.Serialization; 

var ser = new JavaScriptSerializer();
configSz = ser.Serialize(config);
using (var f = (TextWriter)File.CreateText(configFn))
{
    f.WriteLine(configSz);
    f.Close();
}

जवाबों:


257

आपको JavaScriptSerializer के साथ इसे पूरा करने का कठिन समय मिलने वाला है।

JSON.Net आज़माएं ।

JSON.Net उदाहरण से मामूली संशोधनों के साथ

using System;
using Newtonsoft.Json;

namespace JsonPrettyPrint
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            Product product = new Product
                {
                    Name = "Apple",
                    Expiry = new DateTime(2008, 12, 28),
                    Price = 3.99M,
                    Sizes = new[] { "Small", "Medium", "Large" }
                };

            string json = JsonConvert.SerializeObject(product, Formatting.Indented);
            Console.WriteLine(json);

            Product deserializedProduct = JsonConvert.DeserializeObject<Product>(json);
        }
    }

    internal class Product
    {
        public String[] Sizes { get; set; }
        public decimal Price { get; set; }
        public DateTime Expiry { get; set; }
        public string Name { get; set; }
    }
}

परिणाम

{
  "Sizes": [
    "Small",
    "Medium",
    "Large"
  ],
  "Price": 3.99,
  "Expiry": "\/Date(1230447600000-0700)\/",
  "Name": "Apple"
}

दस्तावेज़ीकरण: एक वस्तु को क्रमबद्ध करें



15
@ ब्रैड उन्होंने बिल्कुल समान कोड दिखाया, लेकिन एक मॉडल का उपयोग करते हुए
मिया

तो यह विचार सिर्फ स्वरूपण है।
Indented

यह विधि JSON प्रारूप त्रुटियों को बनाने से भी बचाता है।
अंशुमान गोयल

172

Json.Net लाइब्रेरी के लिए एक छोटा नमूना कोड

private static string FormatJson(string json)
{
    dynamic parsedJson = JsonConvert.DeserializeObject(json);
    return JsonConvert.SerializeObject(parsedJson, Formatting.Indented);
}

1
आप वास्तव में इसे एक कदम आगे ले जा सकते हैं और एक विस्तार विधि बना सकते हैं; इसे सार्वजनिक करें और सिग्नेचर को फॉर्मेटजसन (इस स्ट्रिंग
जोंस

129

यदि आपके पास एक JSON स्ट्रिंग है और इसे "पहले से बताएं" करना चाहते हैं, लेकिन इसे किसी ज्ञात C # प्रकार से क्रमबद्ध नहीं करना चाहते हैं, तो निम्नलिखित ट्रिक (JSON.NET का उपयोग करके) करता है:

using System;
using System.IO;
using Newtonsoft.Json;

class JsonUtil
{
    public static string JsonPrettify(string json)
    {
        using (var stringReader = new StringReader(json))
        using (var stringWriter = new StringWriter())
        {
            var jsonReader = new JsonTextReader(stringReader);
            var jsonWriter = new JsonTextWriter(stringWriter) { Formatting = Formatting.Indented };
            jsonWriter.WriteToken(jsonReader);
            return stringWriter.ToString();
        }
    }
}

6
केवल एक जसन स्ट्रिंग के लिए यह दूसरों की तुलना में एक बहुत ही उचित समाधान है ...
जेन्स मार्चेवाका

2
निम्नलिखित उपयोग के मामले विफल हो जाएंगे: JsonPrettify("null")औरJsonPrettify("\"string\"")
ईकेवू

1
धन्यवाद @Ekevoo, मैंने इसे अपने पिछले संस्करण में वापस ले लिया है!
डंकन स्मार्ट

@DuncanSmart मुझे यह पसंद है! यह संस्करण कम अस्थायी वस्तुओं का रास्ता बनाता है। मुझे लगता है कि यह उन लोगों की तुलना में बेहतर है जिनकी मैंने आलोचना की भले ही उन मामलों का उपयोग किया।
एक्यूवू

97

मौजूदा JSON को छोटा करने के लिए सबसे छोटा संस्करण : (संपादित करें: JSON.net का उपयोग करके)

JToken.Parse("mystring").ToString()

इनपुट:

{"menu": { "id": "file", "value": "File", "popup": { "menuitem": [ {"value": "New", "onclick": "CreateNewDoc()"}, {"value": "Open", "onclick": "OpenDoc()"}, {"value": "Close", "onclick": "CloseDoc()"} ] } }}

आउटपुट:

{
  "menu": {
    "id": "file",
    "value": "File",
    "popup": {
      "menuitem": [
        {
          "value": "New",
          "onclick": "CreateNewDoc()"
        },
        {
          "value": "Open",
          "onclick": "OpenDoc()"
        },
        {
          "value": "Close",
          "onclick": "CloseDoc()"
        }
      ]
    }
  }
}

किसी वस्तु को सुंदर प्रिंट करना:

JToken.FromObject(myObject).ToString()

4
यह पहले से ही जसन की संरचना को जाने बिना भी काम करता है। और यह यहाँ सबसे छोटा जवाब है。
दूरदर्शिता

1
यह काम करता है, लेकिन केवल अगर json वस्तु एक सरणी नहीं है। यदि आप जानते हैं कि यह एक सरणी होगी तो आप हमारे बजाय JArray.Parse कर सकते हैं।
ल्यूक जेड

3
आह, अच्छी बात, धन्यवाद। मैंने JTokenइसके बजाय उपयोग करने के लिए अपना उत्तर अपडेट कर दिया है JObject। यह वस्तुओं या सरणियों के साथ काम करता है, क्योंकि JTokenदोनों के लिए पूर्वज वर्ग है JObjectऔर JArray
एशर

बहुत बहुत धन्यवाद, मैं इस समाधान को पाने के लिए लगभग 2 घंटे बर्बाद कर दिया ... @stackoverflow के बिना अपने जीवन की कल्पना नहीं कर सकता ...
रुद्रेश परमेशप्पा

मैं वास्तव में अन्य जवाबों में से एक को पसंद करता हूं। लघु कोड और प्रभावी। धन्यवाद
मार्क रसेल

47

ऑनलाइनर का उपयोग Newtonsoft.Json.Linq:

string prettyJson = JToken.Parse(uglyJsonString).ToString(Formatting.Indented);

मैं मानता हूं कि न्यूटनसॉफ्ट का उपयोग करने वाले JSON को प्रारूपित करने के लिए यह सबसे सरल एपीआई है
एथान वू

2
Newtonsoft.Json में यह नहीं मिल सका ... शायद मेरे पास एक पुराना संस्करण है।
cslotty

2
यह न्यूटनसॉफ्ट.जॉन.लिंक नामस्थान में है। मुझे यह केवल इसलिए पता है क्योंकि मैं इसकी खोज में भी गया था।
कप्तान केनपाची

12

Jatt स्वरूपित करने के लिए आप निम्न मानक विधि का उपयोग कर सकते हैं

JsonReaderWriterFactory.CreateJsonWriter (स्ट्रीम स्ट्रीम, एन्कोडिंग एन्कोडिंग, बूल मालिकाना, बूल इंडेंट, स्ट्रिंग इंडेंट)

केवल "इंडेंट == ट्रू" सेट करें

कुछ इस तरह की कोशिश करो

    public readonly DataContractJsonSerializerSettings Settings = 
            new DataContractJsonSerializerSettings
            { UseSimpleDictionaryFormat = true };

    public void Keep<TValue>(TValue item, string path)
    {
        try
        {
            using (var stream = File.Open(path, FileMode.Create))
            {
                //var currentCulture = Thread.CurrentThread.CurrentCulture;
                //Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

                try
                {
                    using (var writer = JsonReaderWriterFactory.CreateJsonWriter(
                        stream, Encoding.UTF8, true, true, "  "))
                    {
                        var serializer = new DataContractJsonSerializer(type, Settings);
                        serializer.WriteObject(writer, item);
                        writer.Flush();
                    }
                }
                catch (Exception exception)
                {
                    Debug.WriteLine(exception.ToString());
                }
                finally
                {
                    //Thread.CurrentThread.CurrentCulture = currentCulture;
                }
            }
        }
        catch (Exception exception)
        {
            Debug.WriteLine(exception.ToString());
        }
    }

अपना ध्यान लाइनों पर दें

    var currentCulture = Thread.CurrentThread.CurrentCulture;
    Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
    ....
    Thread.CurrentThread.CurrentCulture = currentCulture;

कुछ प्रकार के xml-serializers के लिए आपको कंप्यूटर पर अन्य क्षेत्रीय सेटिंग्स के साथ डीसर्लाइज़ेशन के दौरान अपवाद से बचने के लिए InvariantCulture का उपयोग करना चाहिए । उदाहरण के लिए, डबल या डेटाइम का अमान्य प्रारूप कभी-कभी उनका कारण बनते हैं।

Deserializing के लिए

    public TValue Revive<TValue>(string path, params object[] constructorArgs)
    {
        try
        {
            using (var stream = File.OpenRead(path))
            {
                //var currentCulture = Thread.CurrentThread.CurrentCulture;
                //Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;

                try
                {
                    var serializer = new DataContractJsonSerializer(type, Settings);
                    var item = (TValue) serializer.ReadObject(stream);
                    if (Equals(item, null)) throw new Exception();
                    return item;
                }
                catch (Exception exception)
                {
                    Debug.WriteLine(exception.ToString());
                    return (TValue) Activator.CreateInstance(type, constructorArgs);
                }
                finally
                {
                    //Thread.CurrentThread.CurrentCulture = currentCulture;
                }
            }
        }
        catch
        {
            return (TValue) Activator.CreateInstance(typeof (TValue), constructorArgs);
        }
    }

धन्यवाद!


नमस्ते, @ माकमैन, क्या आपने कभी विभिन्न संस्कृतियों के कारण क्रमिक त्रुटियों को पुन: उत्पन्न किया है? लगता है जैसे XmlJsonWriter / Reader रूपांतरण सभी संस्कृति अपरिवर्तनीय हैं।
ओलेक्सैंडर इवानित्सकी

नमस्कार, मैं XmlJsonWriter / Reader के बारे में निश्चित नहीं हूं, लेकिन DataContractJsonSerializer थ्रेड का उपयोग करता है। CurrentThread.CurrentCulture। त्रुटि तब हो सकती है जब डेटा को मशीन ए पर क्रमबद्ध किया गया हो, लेकिन एक और क्षेत्रीय सेटिंग्स के साथ बी पर deserialized।
मैकमैन

मैं DataContractJsonSerializerअसेंबली में विघटित हो गया System.Runtime.Serialization v.4.0.0.0, इसका कोई स्पष्ट उपयोग नहीं है CurrentCulture। एक संस्कृति का एकमात्र उपयोग CultureInfo.InvariantCultureआधार वर्ग XmlObjectSerializer, आंतरिक विधि में है TryAddLineInfo
ओलेक्सेंडर इवानित्सकी

तो, शायद यह मेरी गलती है। मैं बाद में इसकी जांच करूंगा। संभव है, मैं इस संस्कृति के मुद्दे को एक और धारावाहिक के कार्यान्वयन से हटा रहा हूं।
मैकमैन

1
मैंने मूल उत्तर संपादित कर दिया है। ऐसा लगता है कि DataContract serializers संस्कृति के प्रति उदासीन हैं, लेकिन आपको धारावाहिकों के अन्य प्रकारों द्वारा क्रमांकन के दौरान संस्कृति विशिष्ट त्रुटियों से बचने के लिए ध्यान देना चाहिए। :)
माकमैन

6

यह सब एक सरल रेखा में किया जा सकता है:

string jsonString = JsonConvert.SerializeObject(yourObject, Formatting.Indented);

1
याद रखें कि 'न्यूटनसॉफ्ट.जॉन का उपयोग करके' जोड़ना
Ebube

सबसे अच्छा जवाब मेरे दोस्त।
रोजरवर्ड

5

यहाँ Microsoft के System.Text.Json पुस्तकालय का उपयोग कर एक समाधान है :

static string FormatJsonText(string jsonString)
{
    using var doc = JsonDocument.Parse(
        jsonString,
        new JsonDocumentOptions
        {
            AllowTrailingCommas = true
        }
    );
    MemoryStream memoryStream = new MemoryStream();
    using (
        var utf8JsonWriter = new Utf8JsonWriter(
            memoryStream,
            new JsonWriterOptions
            {
                Indented = true
            }
        )
    )
    {
        doc.WriteTo(utf8JsonWriter);
    }
    return new System.Text.UTF8Encoding()
        .GetString(memoryStream.ToArray());
}

यह उन लोगों के लिए एक अच्छा उपाय है जो अतिरिक्त पैकेज नहीं खरीद सकते हैं। अच्छा काम करता है।
मार्क टी

2

पहले मैं डंकन स्मार्ट पोस्ट के तहत टिप्पणी जोड़ना चाहता था, लेकिन दुर्भाग्य से मुझे टिप्पणियों को छोड़ने के लिए अभी तक पर्याप्त प्रतिष्ठा नहीं मिली है। तो मैं इसे यहाँ कोशिश करूँगा।

मैं सिर्फ साइड इफेक्ट्स के बारे में चेतावनी देना चाहता हूं।

JsonTextReader आंतरिक रूप से टाइप किए गए JTokens में jars को पार्स करता है और फिर उन्हें वापस सीरियल करता है।

उदाहरण के लिए यदि आपका मूल JSON था

 { "double":0.00002, "date":"\/Date(1198908717056)\/"}

पहले से मिल जाने के बाद

{ 
    "double":2E-05,
    "date": "2007-12-29T06:11:57.056Z"
}

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


इस विवरण के बारे में यहाँ एक महान चर्चा है ... github.com/JamesNK/Newtonsoft.Json/issues/862 दिलचस्प है कि यह विवरण कैसे विकसित हुआ है। मैंने अपने प्राथमिक जोंस पार्सर के बारे में कुछ नया सीखा - आपकी टिप्पणी के लिए धन्यवाद।
Sql सर्फर

2

System.Text.Jsonसेट का उपयोग करना JsonSerializerOptions.WriteIndented = true:

JsonSerializerOptions options = new JsonSerializerOptions { WriteIndented = true };
string json = JsonSerializer.Serialize<Type>(object, options);

2

netcoreapp3.1

var js = JsonSerializer.Serialize(obj, new JsonSerializerOptions {
             WriteIndented = true
         });

0

इसने मेरे लिए काम किया। मामले में कोई VB.NET संस्करण की तलाश में है।

@imports System
@imports System.IO
@imports Newtonsoft.Json

Public Shared Function JsonPrettify(ByVal json As String) As String
  Using stringReader = New StringReader(json)

    Using stringWriter = New StringWriter()
      Dim jsonReader = New JsonTextReader(stringReader)
      Dim jsonWriter = New JsonTextWriter(stringWriter) With {
          .Formatting = Formatting.Indented
      }
      jsonWriter.WriteToken(jsonReader)
      Return stringWriter.ToString()
    End Using
  End Using
End Function

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