Bagaimana saya bisa mengurai JSON dengan C #?


455

Saya memiliki kode berikut:

var user = (Dictionary<string, object>)serializer.DeserializeObject(responsecontent);

Input in responsecontentadalah JSON, tetapi tidak diuraikan dengan benar ke dalam objek. Bagaimana saya harus deserialize dengan benar?


7
Hai, Anda mungkin ingin mencoba tautan ini techblog.procurios.nl/k/n618/news/view/14605/14863/…
Vamsi

34
Ada Jsondi System.Web.Helpers, ada JsonQueryStringConverterdi System.ServiceModel.Web, ada JavascriptSerializerdi System.Web.Script.Serialization, DataContractJsonSerializerdi System.Runtime.Serialization.Json, sih MS bahkan telah memutuskan untuk memasukkan pihak ketiga Json.NETdalam API Web ASP.NET. Jika Anda berpikir itu tidak cukup, MS akan muncul System.Jsontetapi saat ini tidak layak untuk dikonsumsi. Cara untuk pergi Microsoft cara untuk pergi .... Saya memilih oleh namespace yang paling tampan.
nawfal

4
@fusi sisanya dalam majelis terpisah. Google namespace / nama kelas, Anda akan menemukan majelis mereka dalam dokumentasi msdn. Cukup tambahkan referensi ke majelis itu.
nawfal

1
Hanya untuk lengkap, ada juga JsonValuedi Windows.Data.Jsonyang hanya untuk Windows 8 dan di atas. Saya menyukainya. MS ada dalam misi :)
nawfal

5
NewtonSoft memiliki halaman perbandingan di situs mereka (mungkin bias tetapi masih menarik): newtonsoft.com/json/help/html/jsonnetvsdotnetserializers.htm . Saya terutama menyukai baris serialisasi kamus Nonsensikal :)
Ohad Schneider

Jawaban:


365

Saya berasumsi Anda tidak menggunakan Json.NET (paket NewGamesoft.Json NuGet). Jika ini masalahnya, maka Anda harus mencobanya.

Ini memiliki beberapa fitur berikut:

  1. LINQ ke JSON
  2. JsonSerializer untuk dengan cepat mengkonversi objek .NET Anda ke JSON dan kembali lagi
  3. Json.NET secara opsional dapat menghasilkan JSON yang diformat dengan baik dan berindentasi untuk debugging atau tampilan
  4. Atribut seperti JsonIgnore dan JsonProperty dapat ditambahkan ke kelas untuk menyesuaikan cara kelas serial
  5. Kemampuan untuk mengkonversi JSON ke dan dari XML
  6. Mendukung banyak platform: .NET, Silverlight dan Compact Framework

Lihatlah contoh di bawah ini. Dalam contoh ini, JsonConvertkelas digunakan untuk mengonversi objek ke dan dari JSON. Ini memiliki dua metode statis untuk tujuan ini. Mereka adalah SerializeObject(Object obj)dan DeserializeObject<T>(String json):

Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };

string json = JsonConvert.SerializeObject(product);
//{
//  "Name": "Apple",
//  "Expiry": "2008-12-28T00:00:00",
//  "Price": 3.99,
//  "Sizes": [
//    "Small",
//    "Medium",
//    "Large"
//  ]
//}

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

18
Bisakah saya deserialize ke varvariabel tipe, jika saya tidak tahu struktur lengkap dari tujuan saya? Secara khusus, saya mengkonsumsi Rally User Stories, dan saya ingin mengubahnya menjadi objek.
Pedro Dusso

16
@VANDERWEYENJonathan - di browser web modern, JSON.parse (string) dan JSON.stringify (objek) keduanya menangani tanggal sebagai string ISO8601, yang merupakan format yang digambarkan dalam jawaban di atas. Anda mungkin ingin memperbarui standar Anda sebelum orang memutuskan itu tidak relevan. Orang-orang membutuhkan kencan lebih banyak daripada yang mereka butuhkan standar Anda.
Peter Wone

3
@PeterWone: Tidak, JSON.parse('{"Expiry": "2008-12-28T00:00:00"}').Expirymengembalikan string "2008-12-28T00:00:00" , bukan tanggal. dapat berubah menjadi suatu Datemelalui new Date(str), tetapi JSON.parsetahu apa-apa tentang tanggal. Anda harus meneruskan sebuah reviver yang memeriksa setiap nilai string terhadap suatu pola.
TJ Crowder

3
Karena 3,703 detik sama dengan 3s dan 703ms dan pemisahnya adalah titik desimal saya katakan kepada Anda bahwa ini adalah detik hingga tiga tempat desimal.
Peter Wone

38
Mengapa semua orang memiliki masalah seperti dengan termasuk yang relevan require, include, importatau usingpernyataan dalam jawaban mereka. Apakah satu baris itu sakit?
Tomáš Zato - Reinstate Monica

285

Seperti yang dijawab di sini - Deserialize JSON menjadi objek dinamis C #?

Ini cukup sederhana menggunakan Json.NET:

dynamic stuff = JsonConvert.DeserializeObject("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");

string name = stuff.Name;
string address = stuff.Address.City;

Atau menggunakan Newtonsoft.Json.Linq:

dynamic stuff = JObject.Parse("{ 'Name': 'Jon Smith', 'Address': { 'City': 'New York', 'State': 'NY' }, 'Age': 42 }");

string name = stuff.Name;
string address = stuff.Address.City;

13
@ MaxHodges, Anda benar. Saya hanya menggunakan inline "string ajaib" untuk menunjukkan cara mengurai nilai string JSON. Tidak ingin terlihat rumit dengan lolos dari tanda kutip ganda. Dalam kode sebenarnya kita biasanya memiliki string JSON yang diperoleh dari suatu tempat sebagai variabel atau diteruskan sebagai parameter.
Dmitry Pavlov

4
Tanpa .net 4 Anda tidak memiliki kata kunci 'dinamis'. Anda dapat menggunakan 'barang var' untuk deklarasi dan bukannya 'barang.Nama' dan 'barang.Address.Kota' Anda memiliki 'barang ["Nama"]' dan 'barang ["Alamat"] ["Kota"]' secara berurutan .
Fil

1
@Fil Itu memberi Anda nilai tipe object, dan Anda tidak bisa menggunakan pengindeksan pada a object.
Alex

138

Berikut adalah beberapa opsi tanpa menggunakan perpustakaan pihak ketiga:

// For that you will need to add reference to System.Runtime.Serialization
var jsonReader = JsonReaderWriterFactory.CreateJsonReader(Encoding.UTF8.GetBytes(@"{ ""Name"": ""Jon Smith"", ""Address"": { ""City"": ""New York"", ""State"": ""NY"" }, ""Age"": 42 }"), new System.Xml.XmlDictionaryReaderQuotas());

// For that you will need to add reference to System.Xml and System.Xml.Linq
var root = XElement.Load(jsonReader);
Console.WriteLine(root.XPathSelectElement("//Name").Value);
Console.WriteLine(root.XPathSelectElement("//Address/State").Value);

// For that you will need to add reference to System.Web.Helpers
dynamic json = System.Web.Helpers.Json.Decode(@"{ ""Name"": ""Jon Smith"", ""Address"": { ""City"": ""New York"", ""State"": ""NY"" }, ""Age"": 42 }");
Console.WriteLine(json.Name);
Console.WriteLine(json.Address.State);

Lihat tautan untuk informasi lebih lanjut tentang System.Web.Helpers.Json .

Pembaruan : Saat ini cara termudah untuk mendapatkannya Web.Helpersadalah dengan menggunakan paket NuGet .


Jika Anda tidak peduli dengan versi windows sebelumnya, Anda bisa menggunakan kelas Windows.Data.Jsonnamespace:

// minimum supported version: Win 8
JsonObject root = Windows.Data.Json.JsonValue.Parse(jsonString).GetObject();
Console.WriteLine(root["Name"].GetString());
Console.WriteLine(root["Address"].GetObject()["State"].GetString());

Mengapa saya tidak melihat System.Web.Helpers di situs web ASP.NET saya (4,5)? XElement, XPathSelectElement tidak dikenal untuk VisualStudio saya. Bagaimana cara mendidiknya?
Budda

Nah, Anda harus menambahkan referensi untuk perpustakaan yang sesuai (seperti yang ditulis dalam komentar di atas), lihat artikel ini untuk info lebih lanjut. Juga, pertanyaan ini mungkin menarik.
qqbenq

2
Saya menggunakan metode Web.Helpers dijelaskan di sini tetapi mengalami masalah yang dipecahkan oleh posting ini: stackoverflow.com/questions/7066726/…
Alex

1
itu bekerja dengan WPF. Dengan menggunakan namespace berikut menggunakan System.Runtime.Serialization.Json; menggunakan System.Xml.XPath; menggunakan System.Xml.Linq;
Shahid Neermunda


62

Jika .NET 4 tersedia untuk Anda, lihat: http://visitmix.com/writings/the-rise-of-json (archive.org)

Berikut cuplikan dari situs itu:

WebClient webClient = new WebClient();
dynamic result = JsonValue.Parse(webClient.DownloadString("https://api.foursquare.com/v2/users/self?oauth_token=XXXXXXX"));
Console.WriteLine(result.response.user.firstName);

Konsol terakhir itu. Menulis Baris cukup manis ...


Maaf, sepertinya ada yang berubah sejak saya awalnya menjawab. Saya harus melihat-lihat dan melihat perpustakaan mana yang benar ...
ElonU Webdev

7
Kami menantikan Anda menemukan perpustakaan ini. Sunting: apakah ini: dynamicjson.codeplex.com ?
user989056

1
Saya tidak tahu apa yang dimaksud dengan kelas ElonU di sini, tetapi ada "JsonValue" di Windows.Data.Json (yang hanya untuk Windows 8 dan di atas - aneh) dan juga "JsonValue" yang sama di System.Json yang masih dalam pratinjau dan Hanya Tuhan yang tahu apakah itu akan pernah keluar. MS membingungkan saya ketika datang ke Json.
nawfal

35

Solusi asli lain untuk ini, yang tidak memerlukan perpustakaan pihak ke-3 tetapi referensi ke System.Web.Extensions adalah JavaScriptSerializer. Ini bukan fitur bawaan yang baru tetapi sangat tidak dikenal di sana sejak 3.5.

using System.Web.Script.Serialization;

..

JavaScriptSerializer serializer = new JavaScriptSerializer();
objectString = serializer.Serialize(new MyObject());

dan kembali

MyObject o = serializer.Deserialize<MyObject>(objectString)

2
Ini sangat bagus, tetapi membutuhkan comonents web, jadi sayangnya tidak bekerja di .NET 4.0 Client Profile, yang merupakan versi .NET terakhir untuk Windows XP. Pemasangan penuh .NET dimungkinkan, tetapi banyak orang tetap menggunakan Profil Klien. Sebaliknya, System.Runtime.Serialization.Json.DataContractJsonSerializer didukung bahkan dalam Profil Klien.
Al Kepp

3
@ fr34kyn01535: Windows XP memiliki pangsa pasar terbanyak kedua di desktop. Itu relevan.
DonkeyMaster

Ketika saya menggunakan JavaScriptSerializer untuk menghilangkan tanda kutip objek saya, itu berhasil tapi itu membatalkan tanggal saya salah. Itu seharusnya 4/19/2018 12:00 pagi tapi deserialized ke 4/18/2018 08:00 PM. NewtonSoft.Json.JsonConvert deserialized seperti yang diharapkan.
Kaya


16

System.Json bekerja sekarang ...

Instal nuget https://www.nuget.org/packages/System.Json

PM> Install-Package System.Json -Version 4.5.0

Sampel :

// PM>Install-Package System.Json -Version 4.5.0

using System;
using System.Json;

namespace NetCoreTestConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            // Note that JSON keys are case sensitive, a is not same as A.

            // JSON Sample
            string jsonString = "{\"a\": 1,\"b\": \"string value\",\"c\":[{\"Value\": 1}, {\"Value\": 2,\"SubObject\":[{\"SubValue\":3}]}]}";

            // You can use the following line in a beautifier/JSON formatted for better view
            // {"a": 1,"b": "string value","c":[{"Value": 1}, {"Value": 2,"SubObject":[{"SubValue":3}]}]}

            /* Formatted jsonString for viewing purposes:
            {
               "a":1,
               "b":"string value",
               "c":[
                  {
                     "Value":1
                  },
                  {
                     "Value":2,
                     "SubObject":[
                        {
                           "SubValue":3
                        }
                     ]
                  }
               ]
            }
            */

            // Verify your JSON if you get any errors here
            JsonValue json = JsonValue.Parse(jsonString);

            // int test
            if (json.ContainsKey("a"))
            {
                int a = json["a"]; // type already set to int
                Console.WriteLine("json[\"a\"]" + " = " + a);
            }

            // string test
            if (json.ContainsKey("b"))
            {
                string b = json["b"];  // type already set to string
                Console.WriteLine("json[\"b\"]" + " = " + b);
            }

            // object array test
            if (json.ContainsKey("c") && json["c"].JsonType == JsonType.Array)
            {
                // foreach loop test
                foreach (JsonValue j in json["c"])
                {
                    Console.WriteLine("j[\"Value\"]" + " = " + j["Value"].ToString());
                }

                // multi level key test
                Console.WriteLine("json[\"c\"][0][\"Value\"]" + " = " + json["c"][0]["Value"].ToString());
                Console.WriteLine("json[\"c\"][0][\"Value\"]" + " = " + json["c"][1]["Value"].ToString());
                Console.WriteLine("json[\"c\"][1][\"SubObject\"][0][\"SubValue\"]" + " = " + json["c"][1]["SubObject"][0]["SubValue"].ToString());
            }

            Console.WriteLine();
            Console.Write("Press any key to exit.");
            Console.ReadKey();
        }
    }
}

1
Mencoba untuk menemukan contoh cara menggunakan System.Json yang modern telah membawa saya ke sini, setelah hasil yang tak terhitung untuk Json.NET/Newtonsoft.Json/"Newtson.Json "dan iterasi yang lebih lama dari System.Json sejak lama tidak digunakan lagi. Terima kasih untuk ini.
monkey0506

1
Ini sangat membantu saya. Terima kasih banyak.
MAK

10

Gunakan alat ini untuk menghasilkan kelas yang berbasis di json Anda:

http://json2csharp.com/

Dan kemudian gunakan kelas untuk deserialize json Anda. Contoh:

public class Account
{
    public string Email { get; set; }
    public bool Active { get; set; }
    public DateTime CreatedDate { get; set; }
    public IList<string> Roles { get; set; }
}


string json = @"{
  'Email': 'james@example.com',
  'Active': true,
  'CreatedDate': '2013-01-20T00:00:00Z',
  'Roles': [
    'User',
    'Admin'
  ]
}";

Account account = JsonConvert.DeserializeObject<Account>(json);

Console.WriteLine(account.Email);
// james@example.com

Referensi: https://forums.asp.net/t/1992996.aspx?Nested+Json+Deserialization+to+C+object+and+using+that+object https://www.newtonsoft.com/json/help /html/DeserializeObject.htm


9

Coba kode berikut:

HttpWebRequest request = (HttpWebRequest)WebRequest.Create("URL");
JArray array = new JArray();
using (var twitpicResponse = (HttpWebResponse)request.GetResponse())
using (var reader = new StreamReader(twitpicResponse.GetResponseStream()))
{
    JavaScriptSerializer js = new JavaScriptSerializer();
    var objText = reader.ReadToEnd();

    JObject joResponse = JObject.Parse(objText);
    JObject result = (JObject)joResponse["result"];
    array = (JArray)result["Detail"];
    string statu = array[0]["dlrStat"].ToString();
}

Terima kasih, saya ingin bagian ["hasil" + variabel] karena saya ingin menggunakan variabel untuk digunakan di sini yang tidak dapat Anda lakukan dengan mudah dengan JSON.NET.
PHPGuru

Apakah baris ini melakukan sesuatu ... JavaScriptSerializer js = new JavaScriptSerializer (); Terima kasih sebelumnya.
Chris Catignani

9

System.Text.Json

.NET core 3.0 hadir dengan System.Text.Jsonbuilt-in yang artinya Anda dapat membatalkan deserialisasi / serialisasi JSON tanpa menggunakan pustaka pihak ketiga.

Untuk membuat cerita bersambung kelas Anda ke string JSON:

var json = JsonSerializer.Serialize(order);

Untuk membatalkan deserialisasi JSON menjadi kelas yang sangat diketik:

var order = JsonSerializer.Deserialize<Order>(json);

Jadi jika Anda memiliki kelas seperti di bawah ini:

public class Order
{
    public int Id { get; set; }
    public string OrderNumber { get; set; }
    public decimal Balance { get; set; }
    public DateTime Opened { get; set; }
}

var json = JsonSerializer.Serialize(order);
// creates JSON ==>
{
    "id": 123456,
    "orderNumber": "ABC-123-456",
    "balance": 9876.54,
    "opened": "2019-10-21T23:47:16.85",
};

var order = JsonSerializer.Deserialize<Order>(json);
// ==> creates the above class

Satu hal yang perlu diperhatikan adalah bahwa System.Text.Json tidak secara otomatis menangani camelCaseproperti JSON saat menggunakan kode Anda sendiri (namun, itu terjadi ketika menggunakan permintaan MVC / WebAPI dan pengikat model).

Untuk mengatasi ini, Anda harus lulus JsonSerializerOptionssebagai parameter.

JsonSerializerOptions options = new JsonSerializerOptions
{        
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase,  // set camelCase       
    WriteIndented = true                                // write pretty json
};

// pass options to serializer
var json = JsonSerializer.Serialize(order, options);
// pass options to deserializer
var order = JsonSerializer.Deserialize<Order>(json, options);

System.Text.Json juga tersedia untuk .Net Framework dan .Net Standard sebagai paket Nu-get System.Text.Json


1
Bagaimana jika Anda tidak memiliki kelas? Bagaimana jika Anda hanya samar-samar tahu apa yang akan terkandung dalam data json? Atau jika kunci ada sama sekali?
Cherona

@Cherona gunakan JsonDocument.Parse.
haldo

5

Berikut ini dari situs msdn yang menurut saya membantu memberikan beberapa fungsi asli untuk apa yang Anda cari. Harap dicatat itu ditentukan untuk Windows 8. Salah satu contoh dari situs tercantum di bawah ini.

JsonValue jsonValue = JsonValue.Parse("{\"Width\": 800, \"Height\": 600, \"Title\": \"View from 15th Floor\", \"IDs\": [116, 943, 234, 38793]}");
double width = jsonValue.GetObject().GetNamedNumber("Width");
double height = jsonValue.GetObject().GetNamedNumber("Height");
string title = jsonValue.GetObject().GetNamedString("Title");
JsonArray ids = jsonValue.GetObject().GetNamedArray("IDs");

Ini menggunakan namespace Windows.Data.JSON .


6
Bagus, tapi "Minimum klien yang didukung: Windows 8"
watbywbarif

saya pikir tidak ada lagi yang didukung dan sekarang ada newtonsoft json dll icouldnt menemukan windows.data.json
virtouso

3
@ virtouso, seperti yang ditunjukkan oleh watbywbarif, ini sebenarnya agak baru, namun dukungan minimal dari Microsoft , hanya berfungsi di dalam Windows 8.
TargetofGravity

4

Anda dapat menggunakan perluasan berikut

public static class JsonExtensions
{
    public static T ToObject<T>(this string jsonText)
    {
        return JsonConvert.DeserializeObject<T>(jsonText);
    }

    public static string ToJson<T>(this T obj)
    {
        return JsonConvert.SerializeObject(obj);
    } 
}

0

Saya pikir jawaban terbaik yang pernah saya lihat adalah @MD_Sayem_Ahmed.

Pertanyaan Anda adalah "Bagaimana saya bisa mengurai Json dengan C #", tetapi sepertinya Anda ingin memecahkan kode Json. Jika Anda ingin memecahkan kode itu, jawaban Ahmed baik.

Jika Anda mencoba melakukan ini di ASP.NET Web Api, cara termudah adalah membuat objek transfer data yang menyimpan data yang ingin Anda tetapkan:

public class MyDto{
    public string Name{get; set;}
    public string Value{get; set;}
}

Anda cukup menambahkan header aplikasi / json ke permintaan Anda (jika Anda menggunakan Fiddler, misalnya). Anda kemudian akan menggunakan ini di ASP.NET Web API sebagai berikut:

//controller method -- assuming you want to post and return data
public MyDto Post([FromBody] MyDto myDto){
   MyDto someDto = myDto;
   /*ASP.NET automatically converts the data for you into this object 
    if you post a json object as follows:
{
    "Name": "SomeName",
      "Value": "SomeValue"
}
*/
   //do some stuff
}

Ini banyak membantu saya ketika saya bekerja di Web Api dan membuat hidup saya sangat mudah.


0
         string json = @"{
            'Name': 'Wide Web',
            'Url': 'www.wideweb.com.br'}";

        JavaScriptSerializer jsonSerializer = new JavaScriptSerializer();
        dynamic j = jsonSerializer.Deserialize<dynamic>(json);
        string name = j["Name"].ToString();
        string url = j["Url"].ToString();

-1
var result = controller.ActioName(objParams);
IDictionary<string, object> data = (IDictionary<string, object>)new System.Web.Routing.RouteValueDictionary(result.Data);
Assert.AreEqual("Table already exists.", data["Message"]);

2
Anda lebih baik menjelaskan solusi Anda daripada hanya memposting beberapa baris kode. Anda dapat membaca Bagaimana cara menulis jawaban yang baik .
Massimiliano Kraus

Jangan lupa untuk memasukkan System.Webreferensi proyek Anda.
Ohad Cohen

-3
 using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(user)))
 {
    // Deserialization from JSON  
    DataContractJsonSerializer deserializer = new DataContractJsonSerializer(typeof(UserListing))
    DataContractJsonSerializer(typeof(UserListing));
    UserListing response = (UserListing)deserializer.ReadObject(ms);

 }

 public class UserListing
 {
    public List<UserList> users { get; set; }      
 }

 public class UserList
 {
    public string FirstName { get; set; }       
    public string LastName { get; set; } 
 }
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.