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?

Ola Ström
sumber
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);
MD Sayem Ahmed
sumber
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;
Dmitry Pavlov
sumber
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());
qqbenq
sumber
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 ...

ElonU Webdev
sumber
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)
fr34kyn01535
sumber
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
21

Anda juga dapat melihat DataContractJsonSerializer

Pieter Germishuys
sumber
1
ini lebih baik karena kompatibel dengan .NET 3.5
Mahmoud Fayez
itu juga cukup cepat daripada JavaScriptSerializer,
David
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();
        }
    }
}
Zunair
sumber
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': '[email protected]',
  'Active': true,
  'CreatedDate': '2013-01-20T00:00:00Z',
  'Roles': [
    'User',
    'Admin'
  ]
}";

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

Console.WriteLine(account.Email);
// [email protected]

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

Bruno Pereira
sumber
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();
}
Muhammad Awais
sumber
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

haldo
sumber
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 .

Target dari gravitasi
sumber
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);
    } 
}
Hidayet R. Colkusu
sumber
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.

cr1pto
sumber
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();
Fernando Meneses Gomes
sumber
-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"]);
Jidheesh Rajan
sumber
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; } 
 }
Kobie Williams
sumber