Làm cách nào để chuyển đổi đối tượng JSON thành đối tượng C # tùy chỉnh?


247

Có cách nào dễ dàng để điền đối tượng C # của tôi với đối tượng JSON được truyền qua AJAX không?

Đây là Đối tượng JSON được chuyển đến C # WEBMETHOD từ trang bằng JSON.opesify

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

C # WebMetod Nhận đối tượng JSON

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

}

Lớp C # đại diện cho cấu trúc đối tượng của Đối tượng JSON được truyền vào 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
Muốn thêm rằng bạn có thể sử dụng json2csharp.com để tạo các lớp c # cho bạn. Tiết lộ đầy đủ: Tôi đã tạo ra trang web này.
JonathanK


@JonathanK Bạn là vị cứu tinh của tôi!
Matheno

Câu trả lời:


218

Một cách tốt để sử dụng JSON trong C # là với JSON.NET

Bắt đầu nhanh & Tài liệu API từ JSON.NET - Trang web chính thức giúp bạn làm việc với nó.

Một ví dụ về cách sử dụng nó:

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
Điều này hoạt động như một nhà vô địch, nhưng nếu tôi có nhiều mục trong json của tôi và tôi muốn tạo một danh sách đối tượng thì sao?
Djeroen

@Djeroen: Tôi thấy hai cách cho điều đó. Nếu các mục không được nhóm, hãy cố gắng tìm cách phân tách chuỗi, lặp lại quy trình trong một vòng lặp. Nếu chúng được nhóm lại, hãy tạo một đối tượng của các đối tượng
user1011138

1
Tôi thích một lớp lót được đề cập trong các câu trả lời khác .. IMHO.
RayLovless

Có, đây không phải là một cách tiếp cận hay, cách bên dưới sử dụng DeserializeObject sạch hơn nhiều
Andrew

207

Vì tất cả chúng ta đều yêu thích một mã lót

Newtonsoft nhanh hơn java serializer. ... cái này phụ thuộc vào gói NuGet của Newtonsoft, nó phổ biến và tốt hơn bộ nối tiếp mặc định.

Nếu chúng ta có lớp thì sử dụng dưới đây.

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

không có lớp thì dùng động

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

95

Để giữ các tùy chọn của bạn mở, nếu bạn đang sử dụng .NET 3.5 trở lên, đây là một ví dụ được gói gọn, bạn có thể sử dụng trực tiếp từ khung bằng Generics. Như những người khác đã đề cập, nếu đó không chỉ là những đối tượng đơn giản, bạn thực sự nên sử dụng 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;
}

Có thể bạn sẽ cần:

using System.Runtime.Serialization;

using System.Runtime.Serialization.Json;

@ChristianPayne ha! Điểm tốt, có những cái này nên được bọc. Với nhận thức sâu sắc về điều này, chỉ cần sử dụng JSON.NET!
Jammin

2
Nếu lớp DataContractJsonSerializer không hiển thị, bạn phải thêm một tham chiếu đến System.R.78.Serialization bằng cách nhấp chuột phải vào Tài liệu tham khảo trong giải pháp, chọn tab .NET và chọn System.R.78.Serialization
DanKodi

1
Một kịch bản trong đó một phá vỡ. Nếu đối tượng JSON của bạn đại diện cho các thuộc tính với dấu ngoặc đơn, thì hàm này không thành công. ví dụ: nó không thể phân tích {'Chủ đề': 'Gửi email: Nhật ký hoạt động của người dùng web11', 'EmbedAsImage': true} nhưng nó có thể phân tích {"Chủ đề": "Gửi email: Nhật ký hoạt động của người dùng web11", "EmbedAsImage" : đúng}
dreamerkumar

Thêm vào đó, tôi cần trang trí lớp đơn giản của mình với các thuộc tính DataContract và DataMember. Nó sẽ không phân tích mà không có nó.
dreamerkumar

Không giống như Vishal, một lớp POCO hoạt động hoàn hảo với tôi ... +1 vì điều này tránh được sự phụ thuộc vào JSON.NET.
Dunc 12/12/13

54

Với mẫu mã của bạn, bạn không cần phải làm gì khác.

Nếu bạn chuyển chuỗi JSON đó cho phương thức web của mình, nó sẽ tự động phân tích chuỗi JSON và tạo một đối tượng Người dùng được điền làm tham số cho phương thức SaveTeam của bạn.

Nói chung, bạn có thể sử dụng JavascriptSerializerlớp như bên dưới hoặc để linh hoạt hơn, sử dụng bất kỳ khung công tác Json nào khác ngoài đó (Jayrock JSON là một khung tốt) để thao tác JSON dễ dàng.

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

1
Tôi nghĩ rằng bạn phải sử dụng một loại vô số (vì vậy trong ví dụ này Danh sách <Người dùng>)
Dragouf

Làm thế nào chúng ta có thể giải tuần tự hóa nếu nó chứa mô hình chế độ xem phụ
SrinivasN

1
Đối với những người tìm kiếm, bạn cần tham khảo System.Web.Extensionslắp ráp và thêm một using System.Web.Script.Serializationđể có được JavaScriptSerializer, nhưng một khi bạn làm, đây có vẻ là cách sạch nhất để giải tuần tự các jsonchuỗi của bạn vào các lớp cụ thể c #.
Serj Sagan

41

Một giải pháp thực sự đơn giản khác là sử dụng thư viện Newtonsoft.Json:

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

nhưng nếu đối tượng Người dùng có một dữ liệu JSon khác trong thuộc tính, điều này sẽ thất bại ...
gumuruh

@gumuruh Tôi đoán tôi không hiểu câu nói của bạn. Nếu bạn có một thuộc tính phù thủy đối tượng phức tạp là một đối tượng phức tạp khác, chúng cũng sẽ được chuyển đổi, miễn là Chuỗi Json của bạn có dữ liệu chính xác.
Daniel

33

2 ví dụ sau đây sử dụng một trong hai

  1. JavaScriptSerializer trong System.Web.Script.Serialization Hoặc
  2. Json.Decode trong System.Web.Helpers

Ví dụ 1: sử dụng 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
        }
    }
}

Cách sử dụng: Đối tượng JSON đến đối tượng C # tùy chỉnh

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

Ví dụ 2: sử dụng 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
        }
    }
}

Cách sử dụng: Đối tượng JSON đến đối tượng C # tùy chỉnh

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

Mã này yêu cầu thêm không gian tên System.Web.Helpers được tìm thấy trong,

% Chương trình %% \ Microsoft ASP.NET \ Trang web ASP.NET {VERSION} \ Assemblies \ System.Web.Helpers.dll

Hoặc là

% Chương trình tệp (x86)% \ Microsoft ASP.NET \ Trang web ASP.NET {VERSION} \ Assemblies \ System.Web.Helpers.dll

Hi vọng điêu nay co ich!


Đây là một câu trả lời rất hay, nhưng điều khó khăn là với dynamiccác loại, bạn không được kiểm tra loại đúng. Ví dụ: nếu JSON của bạn chứa "Name" : "Ahmed"và bạn gõ nhầm "Tên" trong mã C #, thì đó là lỗi thời gian chạy (bleh).
Jess

Cảm ơn! Vui lòng cập nhật câu trả lời cho biết ví dụ 1, bạn cần tham khảo System.Web.Extensions.dll
Valamas

1
câu trả lời siêu tuyệt vời, kiểu gõ động hoạt động w / json.net v6.0.6 quá!
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);
        }
    }
}

Thêm thông tin vào liên kết sau http://ishareidea.blogspot.in/2012/05/json-conversion.html

Về DataContractJsonSerializer Classbạn có thể đọc ở đây .


5

Sử dụng JavaScriptSerializer () ít nghiêm ngặt hơn so với giải pháp chung được cung cấp: công khai tĩnh T Deserialize (chuỗi json)

Điều đó có thể có ích khi chuyển json đến máy chủ không khớp chính xác với định nghĩa Đối tượng bạn đang cố gắng chuyển đổi sang.



1

JSON.Net là đặt cược tốt nhất của bạn, nhưng tùy thuộc vào hình dạng của các đối tượng và liệu có phụ thuộc vòng tròn hay không, bạn có thể sử dụng JavaScriptSerializer hoặc DataContractSerializer.



1

Trình tuần tự hóa JavaScript: yêu cầu 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);
    }
}

Hợp đồng tuần tự dữ liệu: yêu cầu using System.Runtime.Serialization.Json; - Loại chung T nên được tuần tự hóa nhiều hơn trên Hợp đồng dữ liệu

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

Thay vì gửi như một đối tượng.

Tạo một lớp thuộc tính công khai có thể truy cập và gửi dữ liệu tới Webmethod.

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

sử dụng cùng tên tham số trong cuộc gọi ajax để gửi dữ liệu.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.