วิธีการแปลงวัตถุ JSON เป็นวัตถุ C # แบบกำหนดเอง


247

มีวิธีง่ายๆในการเติม C # Object ของฉันด้วยวัตถุ JSON ผ่าน AJAX?

นี่คืออ็อบเจ็กต์ JSON ที่ส่งไปยัง C # WEBMETHOD จากหน้าเว็บโดยใช้ JSON.stringify

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

C # WebMetod ที่รับวัตถุ JSON

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

}

C # Class ที่แสดงถึงโครงสร้างวัตถุของ JSON Object ที่ส่งผ่านไปยัง WebMethod

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

69
ต้องการเพิ่มว่าคุณสามารถใช้json2csharp.comเพื่อสร้างคลาส c # ของคุณให้คุณ การเปิดเผยแบบเต็ม: ฉันสร้างเว็บไซต์นี้ขึ้นแล้ว
JonathanK


@ JonathanK คุณเป็นผู้ช่วยให้รอดของฉัน!
Matheno

คำตอบ:


218

วิธีที่ดีในการใช้ JSON ใน C # คือกับJSON.NET

เริ่มต้นอย่างรวดเร็ว & เอกสาร APIจาก JSON.NET - เว็บไซต์อย่างเป็นทางการช่วยให้คุณทำงานกับมันได้

ตัวอย่างของวิธีใช้:

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);
 }

5
สิ่งนี้ใช้ได้เหมือนแชมป์ แต่ถ้าฉันมีหลายรายการใน json ของฉันและฉันต้องการสร้างรายการวัตถุ
Djeroen

@Deroero: ฉันเห็นสองวิธีนี้ หากรายการไม่ได้ถูกจัดกลุ่มพยายามหาวิธีที่จะแยกสตริงและทำซ้ำกระบวนการในวง หากพวกเขาถูกจัดกลุ่มทำวัตถุของวัตถุ
1011138

1
ฉันชอบ liners หนึ่งที่กล่าวถึงในคำตอบอื่น ๆ .. IMHO
RayLoveless

ใช่นี่ไม่ใช่วิธีที่ดีวิธีหนึ่งที่ใช้ DeserializeObject ด้านล่างนั้นสะอาดกว่ามาก
Andrew

209

เนื่องจากเราทุกคนรักหนึ่ง liners รหัส

Newtonsoft เร็วกว่า java script serializer ... อันนี้ขึ้นอยู่กับแพ็คเกจ Newtonsoft NuGet ซึ่งเป็นที่นิยมและดีกว่า serializer เริ่มต้น

ถ้าเรามีคลาสให้ใช้ด้านล่าง

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

ไม่มีคลาสจากนั้นใช้ไดนามิก

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

95

เพื่อให้ตัวเลือกของคุณเปิดอยู่หากคุณใช้. NET 3.5 หรือใหม่กว่านี่คือตัวอย่างสรุปที่คุณสามารถใช้โดยตรงจากเฟรมเวิร์กโดยใช้ Generics อย่างที่คนอื่น ๆ พูดถึงถ้าไม่ใช่แค่วัตถุธรรมดา ๆ คุณควรใช้ 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;
}

คุณจะต้องการ:

using System.Runtime.Serialization;

using System.Runtime.Serialization.Json;

@ChristianPayne ฮ่า! จุดดีใช่สิ่งเหล่านี้ควรถูกห่อ ด้วยการมองย้อนกลับไปที่สิ่งนี้เพียงแค่ใช้ JSON.NET!
Jammin

2
หากไม่สามารถมองเห็นคลาส DataContractJsonSerializer ได้คุณต้องเพิ่มการอ้างอิงถึง System.Runtime.Serialization โดยคลิกขวาที่การอ้างอิงในการแก้ปัญหาเลือกแท็บ. NET และเลือก System.Runtime.Serialization
DanKodi

1
สถานการณ์หนึ่งที่หนึ่งนี้แบ่ง หากอ็อบเจ็กต์ JSON ของคุณแทนคุณสมบัติด้วยเครื่องหมายคำพูดเดี่ยวฟังก์ชันนี้จะล้มเหลว เช่นไม่สามารถแยกวิเคราะห์ {'หัวเรื่อง': 'การส่งอีเมล: บันทึกกิจกรรมของผู้ใช้เว็บ 11', 'EmbedAsImage': true} แต่สามารถแยกวิเคราะห์ {"หัวเรื่อง": "การส่งอีเมล: บันทึกกิจกรรมผู้ใช้เว็บ 11", "EmbedAsImage" : true}
dreamerkumar

นอกจากนี้ฉันต้องตกแต่งคลาสที่เรียบง่ายด้วยแอตทริบิวต์ DataContract และ DataMember มันจะไม่แจงโดยไม่มีมัน
dreamerkumar

ซึ่งแตกต่างจาก Vishal คลาส POCO ทำงานได้อย่างสมบูรณ์แบบสำหรับฉัน ... +1 เพราะนี่เป็นการหลีกเลี่ยงการพึ่งพา JSON.NET
Dunc

54

เมื่อรับตัวอย่างโค้ดคุณไม่จำเป็นต้องทำอะไรอีก

หากคุณส่งสตริง JSON นั้นไปยังวิธีการทางเว็บของคุณสตริงดังกล่าวจะวิเคราะห์สตริง JSON โดยอัตโนมัติและสร้างวัตถุผู้ใช้ที่มีประชากรเป็นพารามิเตอร์สำหรับวิธีการ SaveTeam ของคุณ

โดยทั่วไปแล้วคุณสามารถใช้JavascriptSerializerคลาสดังต่อไปนี้หรือเพื่อความยืดหยุ่นมากขึ้นใช้เฟรมเวิร์ก Json ที่หลากหลาย (Jayrock JSON เป็นคลาสที่ดี) เพื่อการจัดการ JSON ที่ง่าย

 JavaScriptSerializer jss= new JavaScriptSerializer();
 User user = jss.Deserialize<User>(jsonResponse); 

1
ฉันคิดว่าคุณต้องใช้ประเภทจำนวนนับไม่ถ้วน (ในตัวอย่างนี้ List <User>)
Dragouf

เราจะทำการ deserialize ได้อย่างไรถ้ามันมีโมเดลย่อยของมุมมอง
SrinivasNaidu

1
สำหรับผู้ที่มองหาคุณจำเป็นต้องอ้างอิงSystem.Web.Extensionsแอสเซมบลีและเพิ่มที่using System.Web.Script.Serializationจะได้รับJavaScriptSerializerแต่เมื่อคุณทำสิ่งนี้ดูเหมือนจะเป็นวิธีที่สะอาดที่สุดในการกำจัดjsonสตริงของคุณลงในคลาส c #
Serj Sagan

41

อีกทางออกที่ง่ายจริงๆใช้ห้องสมุด Newtonsoft.Json:

User user = JsonConvert.DeserializeObject<User>(jsonString);

แต่ถ้าวัตถุผู้ใช้มีข้อมูล JSon อื่นในคุณสมบัติสิ่งนี้จะล้มเหลว ...
gumuruh

@ gumuruh ฉันเดาว่าฉันไม่เข้าใจคำสั่งของคุณ หากคุณมีคุณสมบัติแม่มดวัตถุที่ซับซ้อนเป็นวัตถุที่ซับซ้อนอื่นพวกเขาจะถูกแปลงตราบใดที่ Json String ของคุณมีข้อมูลที่ถูกต้อง
แดเนียล

33

ตัวอย่าง 2 ตัวอย่างต่อไปนี้ใช้ประโยชน์จากทั้งสองอย่าง

  1. JavaScriptSerializerภายใต้System.Web.Script.Serializationหรือ
  2. Json.Decodeภายใต้System.Web.Helpers

ตัวอย่างที่ 1:ใช้ 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
        }
    }
}

การใช้งาน:วัตถุ JSON ไปยังวัตถุ 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; }
    }
}

ตัวอย่างที่ 2:ใช้ 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
        }
    }
}

การใช้งาน:วัตถุ JSON ไปยังวัตถุ 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; }
    }
}

รหัสนี้ต้องการการเพิ่มเนมสเปซ System.Web.Helpers ที่พบใน

% ProgramFiles% \ Microsoft เว็บเพจ ASP.NET \ ASP.NET {VERSION} \ Assemblies \ System.Web.Helpers.dll

หรือ

% ProgramFiles (x86) เว็บเพจ ASP.NET \ ASP.NET% \ Microsoft {VERSION} \ Assemblies \ System.Web.Helpers.dll

หวังว่านี่จะช่วยได้!


นี่เป็นคำตอบที่ดีมาก แต่สิ่งที่ยุ่งยากก็คือกับdynamicประเภทคุณจะไม่ได้รับการตรวจสอบประเภทที่แท้จริง ตัวอย่างเช่นหาก JSON ของคุณมี"Name" : "Ahmed"และคุณพิมพ์ "ชื่อ" ผิดพลาดในรหัส C # ของคุณนั่นเป็นข้อผิดพลาดรันไทม์ (bleh)
Jess

ขอบคุณ! โปรดอัปเดตคำตอบเพื่อระบุว่าสำหรับตัวอย่างที่ 1 คุณจะต้องอ้างอิง System.Web.Extensions.dll
Valamas

1
คำตอบที่ยอดเยี่ยมสุด ๆ การพิมพ์แบบไดนามิกทำงานด้วย 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);
        }
    }
}

ข้อมูลเพิ่มเติมไปที่ลิงค์ต่อไปนี้ http://ishareidea.blogspot.in/2012/05/json-conversion.html

เกี่ยวกับDataContractJsonSerializer Classคุณสามารถอ่านได้ที่นี่


5

การใช้ JavaScriptSerializer () มีความเข้มงวดน้อยกว่าโซลูชันทั่วไปที่เสนอ: public static T Deserialize (string json)

ซึ่งอาจเป็นประโยชน์เมื่อส่ง json ไปยังเซิร์ฟเวอร์ที่ไม่ตรงกับข้อกำหนด Object ที่คุณพยายามแปลง



1

JSON.Net เป็นทางออกที่ดีที่สุดของคุณ แต่ขึ้นอยู่กับรูปร่างของวัตถุและไม่ว่าจะมีการพึ่งพาแบบวงกลมคุณสามารถใช้ JavaScriptSerializer หรือ DataContractSerializer



1

JavaScript Serializer: ต้องการ 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);
    }
}

Data Contract Serializer: ต้องการusing System.Runtime.Serialization.Json; - ประเภททั่วไป T ควรเป็นอนุกรมเพิ่มเติมเกี่ยวกับสัญญาข้อมูล

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);
        }
    }
}

0

แทนที่จะส่งเป็นเพียงวัตถุ

สร้างคลาสสาธารณะของคุณสมบัติที่สามารถเข้าถึงได้และส่งข้อมูลไปยัง Webmethod

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

ใช้ชื่อพารามิเตอร์เดียวกันในการโทร ajax เพื่อส่งข้อมูล

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.