Bagaimana Mengonversi objek JSON ke objek Kustom C #?

247

Apakah ada cara mudah untuk mengisi objek C # saya dengan objek JSON yang dilewatkan melalui AJAX?

Ini adalah Objek JSON yang diteruskan ke C # WEBMETHOD dari halaman menggunakan JSON.stringify

{
    "user": {
        "name": "asdf",
        "teamname": "b",
        "email": "c",
        "players": ["1", "2"]
    }
}

C # WebMetod Yang menerima Objek JSON

[WebMethod]
public static void SaveTeam(Object user)
{

}

C # Kelas yang mewakili struktur objek JSON Object yang diteruskan ke WebMethod

public class User
{
    public string name { get; set; }
    public string teamname { get; set; }
    public string email { get; set; }
    public Array players { get; set; }
}
MHop
sumber
69
Ingin menambahkan bahwa Anda dapat menggunakan json2csharp.com untuk menghasilkan kelas c # untuk Anda. Pengungkapan penuh: Saya memang membuat situs ini.
JonathanK
@ JonathanK Kau penyelamatku!
Matheno

Jawaban:

218

Cara yang baik untuk menggunakan JSON di C # adalah dengan JSON.NET

Mulai Cepat & Dokumentasi API dari JSON.NET - Situs resmi membantu Anda bekerja dengannya.

Contoh cara menggunakannya:

public class User
{
    public User(string json)
    {
        JObject jObject = JObject.Parse(json);
        JToken jUser = jObject["user"];
        name = (string) jUser["name"];
        teamname = (string) jUser["teamname"];
        email = (string) jUser["email"];
        players = jUser["players"].ToArray();
    }

    public string name { get; set; }
    public string teamname { get; set; }
    public string email { get; set; }
    public Array players { get; set; }
}

// Use
private void Run()
{
    string json = @"{""user"":{""name"":""asdf"",""teamname"":""b"",""email"":""c"",""players"":[""1"",""2""]}}";
    User user = new User(json);

    Console.WriteLine("Name : " + user.name);
    Console.WriteLine("Teamname : " + user.teamname);
    Console.WriteLine("Email : " + user.email);
    Console.WriteLine("Players:");

    foreach (var player in user.players)
        Console.WriteLine(player);
 }
AndreyAkinshin
sumber
5
Ini berfungsi seperti jagoan, tetapi bagaimana jika saya memiliki beberapa item di json saya dan saya ingin membuat daftar objek?
Djeroen
@ Djeroen: Saya melihat dua cara untuk itu. Jika item tidak dikelompokkan cobalah untuk menemukan cara untuk membagi string dan ulangi proses dalam satu lingkaran. Jika mereka dikelompokkan membuat objek objek
user1011138
1
Saya lebih suka satu liner yang disebutkan dalam jawaban lain .. IMHO.
Ray tanpa cinta
Ya ini bukan pendekatan yang bagus, yang di bawah ini menggunakan DeserializeObject jauh lebih bersih
Andrew
208

Karena kita semua suka kode satu baris

Newtonsoft lebih cepat dari serializer skrip java. ... yang satu ini bergantung pada paket Newtonsoft NuGet, yang populer dan lebih baik daripada serializer default.

jika kita memiliki kelas maka gunakan di bawah ini.

Mycustomclassname oMycustomclassname = Newtonsoft.Json.JsonConvert.DeserializeObject<Mycustomclassname>(jsonString);

tidak ada kelas lalu gunakan dinamis

var oMycustomclassname = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(jsonString);
MSTdev
sumber
95

Agar opsi Anda tetap terbuka, jika Anda menggunakan .NET 3.5 atau yang lebih baru, berikut ini adalah contoh lengkap yang dapat Anda gunakan langsung dari framework menggunakan Generics. Seperti yang telah disebutkan orang lain, jika bukan hanya objek sederhana, Anda harus benar-benar menggunakan JSON.net.

public static string Serialize<T>(T obj)
{
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
    MemoryStream ms = new MemoryStream();
    serializer.WriteObject(ms, obj);
    string retVal = Encoding.UTF8.GetString(ms.ToArray());
    return retVal;
}

public static T Deserialize<T>(string json)
{
    T obj = Activator.CreateInstance<T>();
    MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json));
    DataContractJsonSerializer serializer = new DataContractJsonSerializer(obj.GetType());
    obj = (T)serializer.ReadObject(ms);
    ms.Close();
    return obj;
}

Kamu akan membutuhkan:

using System.Runtime.Serialization;

using System.Runtime.Serialization.Json;
Jammin
sumber
@ChristianPayne ha! Poin bagus, ya ini harus dibungkus. Dengan melihat ke belakang melihat ini, cukup gunakan JSON.NET!
Jammin
2
Jika kelas DataContractJsonSerializer tidak terlihat, Anda harus menambahkan referensi ke System.Runtime.Serialisasi dengan mengklik kanan pada Referensi dalam solusi, pilih tab .NET dan pilih System.Runtime.Serialization
DanKodi
1
Satu skenario di mana ini rusak. Jika objek JSON Anda mewakili properti dengan tanda kutip tunggal, fungsi ini gagal. mis. itu tidak dapat mem-parsing {'Subjek': 'Mengirim email: Log Aktivitas Pengguna Web11', 'EmbedAsImage': true} tetapi ia dapat mem-parsing {"Subjek": "Mengirim Email: Log Aktivitas Pengguna Web11", "EmbedAsImage" : true}
dreamerkumar
Ditambah lagi, saya perlu mendekorasi kelas sederhana saya dengan atribut DataContract dan DataMember. Itu tidak akan diuraikan tanpa itu.
dreamerkumar
Tidak seperti Vishal, kelas POCO bekerja dengan sempurna untuk saya ... +1 karena ini menghindari ketergantungan pada JSON.NET.
Dunc
54

Dengan contoh kode Anda, Anda tidak perlu melakukan hal lain.

Jika Anda meneruskan string JSON itu ke metode web Anda, itu akan secara otomatis mengurai string JSON dan membuat objek Pengguna yang terisi sebagai parameter untuk metode SaveTeam Anda.

Namun secara umum, Anda dapat menggunakan JavascriptSerializerkelas seperti di bawah ini, atau untuk lebih banyak fleksibilitas, gunakan salah satu dari berbagai kerangka kerja Json di luar sana (Jayrock JSON adalah yang bagus) untuk manipulasi JSON yang mudah.

 JavaScriptSerializer jss= new JavaScriptSerializer();
 User user = jss.Deserialize<User>(jsonResponse); 
womp
sumber
1
Saya pikir Anda harus menggunakan tipe ienumerable (jadi dalam contoh ini Daftar <User>)
Dragouf
Bagaimana kita deserialize jika berisi model tampilan sub
SrinivasNaidu
1
Bagi mereka yang mencari, Anda perlu referensi System.Web.Extensionsperakitan dan menambahkan using System.Web.Script.Serializationuntuk mendapatkan di JavaScriptSerializer, tetapi begitu Anda melakukannya, ini sepertinya cara terbersih untuk membatalkan deserialisasi jsonstring Anda ke dalam kelas c # beton.
Serj Sagan
41

Solusi Sungguh sederhana lainnya adalah menggunakan perpustakaan Newtonsoft.Json:

User user = JsonConvert.DeserializeObject<User>(jsonString);
Daniel
sumber
tetapi jika objek Pengguna memiliki data JSon lain di properti, ini akan gagal ...
gumuruh
@gumuruh saya kira saya tidak mengerti pernyataan Anda. Jika Anda memiliki properti penyihir objek kompleks adalah objek kompleks lain, mereka juga akan dikonversi, selama Json String Anda memiliki data dengan benar.
Daniel
33

2 contoh berikut memanfaatkan keduanya

  1. JavaScriptSerializer di bawah System.Web.Script.Serialization Atau
  2. Json.Decode di bawah System.Web.Helpers

Contoh 1: menggunakan System.Web.Script.Serialization

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Script.Serialization;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void Test()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            dynamic jsonObject = serializer.Deserialize<dynamic>(json);

            dynamic x = jsonObject["user"]; // result is Dictionary<string,object> user with fields name, teamname, email and players with their values
            x = jsonObject["user"]["name"]; // result is asdf
            x = jsonObject["user"]["players"]; // result is object[] players with its values
        }
    }
}

Penggunaan: objek JSON ke objek Kustom C #

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Script.Serialization;
using System.Linq;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void TestJavaScriptSerializer()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            User user = new User(json);
            Console.WriteLine("Name : " + user.name);
            Console.WriteLine("Teamname : " + user.teamname);
            Console.WriteLine("Email : " + user.email);
            Console.WriteLine("Players:");
            foreach (var player in user.players)
                Console.WriteLine(player);
        }
    }

    public class User {
        public User(string json) {
            JavaScriptSerializer serializer = new JavaScriptSerializer();
            var jsonObject = serializer.Deserialize<dynamic>(json);
            name = (string)jsonObject["user"]["name"];
            teamname = (string)jsonObject["user"]["teamname"];
            email = (string)jsonObject["user"]["email"];
            players = jsonObject["user"]["players"];
        }

        public string name { get; set; }
        public string teamname { get; set; }
        public string email { get; set; }
        public Array players { get; set; }
    }
}

Contoh 2: menggunakan System.Web.Helpers

using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Helpers;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void TestJsonDecode()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            dynamic jsonObject = Json.Decode(json);

            dynamic x = jsonObject.user; // result is dynamic json object user with fields name, teamname, email and players with their values
            x = jsonObject.user.name; // result is asdf
            x = jsonObject.user.players; // result is dynamic json array players with its values
        }
    }
}

Penggunaan: objek JSON ke objek Kustom C #

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Web.Helpers;
using System.Linq;

namespace Tests
{
    [TestClass]
    public class JsonTests
    {
        [TestMethod]
        public void TestJsonDecode()
        {
            var json = "{\"user\":{\"name\":\"asdf\",\"teamname\":\"b\",\"email\":\"c\",\"players\":[\"1\",\"2\"]}}";
            User user = new User(json);
            Console.WriteLine("Name : " + user.name);
            Console.WriteLine("Teamname : " + user.teamname);
            Console.WriteLine("Email : " + user.email);
            Console.WriteLine("Players:");
            foreach (var player in user.players)
                Console.WriteLine(player);
        }
    }

    public class User {
        public User(string json) {
            var jsonObject = Json.Decode(json);
            name = (string)jsonObject.user.name;
            teamname = (string)jsonObject.user.teamname;
            email = (string)jsonObject.user.email;
            players = (DynamicJsonArray) jsonObject.user.players;
        }

        public string name { get; set; }
        public string teamname { get; set; }
        public string email { get; set; }
        public Array players { get; set; }
    }
}

Kode ini membutuhkan penambahan namespace System.Web.Helpers ditemukan di,

% ProgramFiles% \ Microsoft ASP.NET \ ASP.NET Halaman Web {VERSION} \ Assemblies \ System.Web.Helpers.dll

Atau

% ProgramFiles (x86)% \ Microsoft ASP.NET \ ASP.NET Web Pages {VERSION} \ Assemblies \ System.Web.Helpers.dll

Semoga ini membantu!


sumber
Ini adalah jawaban yang sangat bagus, tetapi yang sulit adalah bahwa dengan dynamictipe, Anda tidak mendapatkan pengecekan tipe yang benar. Misalnya, jika JSON Anda berisi "Name" : "Ahmed"dan Anda salah ketik "Nama" dalam kode C # Anda, itu adalah kesalahan runtime (bleh).
Jess
Terima kasih! Harap perbarui jawaban untuk menyatakan bahwa untuk Contoh 1, Anda perlu merujuk System.Web.Extensions.dll
Valamas
1
jawaban super hebat, pengetikan dinamis juga berfungsi dengan json.net v6.0.6!
stackuser83
7
public static class Utilities
{
    public static T Deserialize<T>(string jsonString)
    {
        using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(jsonString)))
        {    
            DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T));
            return (T)serializer.ReadObject(ms);
        }
    }
}

Informasi lebih lanjut pergi ke tautan berikut http://ishareidea.blogspot.in/2012/05/json-conversion.html

Tentang DataContractJsonSerializer ClassAnda bisa baca di sini .

Pengembang Syam
sumber
5

Menggunakan JavaScriptSerializer () kurang ketat dari solusi umum yang ditawarkan: public static T Deserialize (string json)

Itu mungkin berguna ketika meneruskan json ke server yang tidak cocok dengan definisi objek yang ingin Anda konversi.

Ioannis Suarez
sumber
1

JSON.Net adalah taruhan terbaik Anda, tetapi, tergantung pada bentuk objek dan apakah ada dependensi melingkar, Anda bisa menggunakan JavaScriptSerializer atau DataContractSerializer.

Sky Sanders
sumber
1

JavaScript Serializer: membutuhkan using System.Web.Script.Serialization;

public class JavaScriptSerializerDeSerializer<T>
{
    private readonly JavaScriptSerializer serializer;

    public JavaScriptSerializerDeSerializer()
    {
        this.serializer = new JavaScriptSerializer();
    }

    public string Serialize(T t)
    {
        return this.serializer.Serialize(t);
    }

    public T Deseralize(string stringObject)
    {
        return this.serializer.Deserialize<T>(stringObject);
    }
}

Serializer Kontrak Data: memerlukan using System.Runtime.Serialization.Json; - Tipe T generik harus lebih bersambung pada Kontrak Data

public class JsonSerializerDeserializer<T> where T : class
{
    private readonly DataContractJsonSerializer jsonSerializer;

    public JsonSerializerDeserializer()
    {
        this.jsonSerializer = new DataContractJsonSerializer(typeof(T));
    }

    public string Serialize(T t)
    {
        using (var memoryStream = new MemoryStream())
        {
            this.jsonSerializer.WriteObject(memoryStream, t);
            memoryStream.Position = 0;
            using (var sr = new StreamReader(memoryStream))
            {
                return sr.ReadToEnd();
            }
        }
    }

    public T Deserialize(string objectString)
    {
        using (var ms = new MemoryStream(System.Text.ASCIIEncoding.ASCII.GetBytes((objectString))))
        {
            return (T)this.jsonSerializer.ReadObject(ms);
        }
    }
}
BTE
sumber
0

Alih-alih mengirim hanya sebagai objek.

Buat kelas publik properti yang dapat diakses dan mengirim data ke metode Web.

[WebMethod]
public static void SaveTeam(useSomeClassHere user)
{
}

menggunakan nama parameter yang sama dalam panggilan ajax untuk mengirim data.

Praveen Kumar Rejeti
sumber