Giải trừ JSON bằng C #


206

Tôi đang cố gắng giải tuần tự API API của một người bạn trên Facebook lệnh gọi vào danh sách các đối tượng. Đối tượng JSON trông giống như:

{"data":[{"id":"518523721","name":"ftyft"},
         {"id":"527032438","name":"ftyftyf"},
         {"id":"527572047","name":"ftgft"},
         {"id":"531141884","name":"ftftft"},
         {"id":"532652067","name"...

List<EFacebook> facebooks = new JavaScriptSerializer().Deserialize<List<EFacebook>>(result);

Nó không hoạt động, vì đối tượng nguyên thủy không hợp lệ. Làm thế nào tôi có thể giải trừ điều này?


3
viết một trình giải nén tùy chỉnh đặc biệt để phục vụ cho json như vậy ...
ashutosh raina

2
hoặc bạn có thể sử dụng Dictionary<string,string>, hãy xem: stackoverflow.com/questions/7699972/iêu
Kakashi

9
Bạn của bạn: json2csharp.com
nawfal

4
Trên thực tế, các studio trực quan (kể từ năm 2013 hoặc 2012 với các công cụ web được cài đặt) có chức năng chính xác này được tích hợp sẵn: Chỉnh sửa> Dán đặc biệt> Dán JSON dưới dạng lớp
floomby

Câu trả lời:


264

Bạn cần tạo một cấu trúc như thế này:

public class Friends
{

    public List<FacebookFriend> data {get; set;}
}

public class FacebookFriend
{

    public string id {get; set;}
    public string name {get; set;}
}

Sau đó, bạn sẽ có thể làm:

Friends facebookFriends = new JavaScriptSerializer().Deserialize<Friends>(result);

Tên của các lớp học của tôi chỉ là một ví dụ. Bạn nên sử dụng tên thích hợp.

Thêm một bài kiểm tra mẫu:

string json =
    @"{""data"":[{""id"":""518523721"",""name"":""ftyft""}, {""id"":""527032438"",""name"":""ftyftyf""}, {""id"":""527572047"",""name"":""ftgft""}, {""id"":""531141884"",""name"":""ftftft""}]}";

Friends facebookFriends = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<Friends>(json);

foreach(var item in facebookFriends.data)
{
    Console.WriteLine("id: {0}, name: {1}", item.id, item.name);
}

Sản xuất:

id: 518523721, name: ftyft
id: 527032438, name: ftyftyf
id: 527572047, name: ftgft
id: 531141884, name: ftftft

3
Yeh, đó là điều tôi không muốn làm, tạo ra một đối tượng mới để giữ trẻ. Tôi nghĩ tôi sẽ xâu chuỗi json lấy ra vật thể nguyên thủy. Cảm ơn bạn.

@Kevin Holditch cảm ơn vì đã sửa. Tôi đã bỏ lỡ một bit quan trọng :)
Icarus

2
Điều tôi không thích ở System.Web.Script.Serialization.JavaScriptSerializer () này là bạn luôn cần một loại T. được xác định. Trong Java có thư viện org.java (gói) vẫn ẩn danh: "JSONObject [" param "]. JSONarray (5)" vv
thể thao

2
Điều quan trọng cần lưu ý là các setters cho thuộc tính id và name phải được để công khai. Nếu chúng được đặt ở chế độ riêng tư hoặc được bảo vệ, quá trình khử lưu huỳnh sẽ thực hiện không có lỗi nhưng tất cả dữ liệu sẽ không có giá trị.
Isaac Zais

2
@sports, bạn có thể làm điều đó trong C # bằng cách khử lưu động thành một động, nhưng hiệu suất sẽ tốt hơn nhiều nếu bạn giải tuần tự hóa thành một loại đã biết.
PRman

50

Đôi khi tôi thích các đối tượng động:

public JsonResult GetJson()
{
  string res;
  WebClient client = new WebClient();

  // Download string
  string value = client.DownloadString("https://api.instagram.com/v1/users/000000000/media/recent/?client_id=clientId");

  // Write values
  res = value;
  dynamic dyn = JsonConvert.DeserializeObject(res);
  var lstInstagramObjects = new List<InstagramModel>();

  foreach(var obj in dyn.data)
  {
    lstInstagramObjects.Add(new InstagramModel()
    {
      Link = (obj.link != null) ? obj.link.ToString() : "",
      VideoUrl = (obj.videos != null) ? obj.videos.standard_resolution.url.ToString() : "",
      CommentsCount = int.Parse(obj.comments.count.ToString()),
      LikesCount = int.Parse(obj.likes.count.ToString()),
      CreatedTime = new System.DateTime(1970, 1, 1, 0, 0, 0, 0).AddSeconds((double.Parse(obj.created_time.ToString()))),
      ImageUrl = (obj.images != null) ? obj.images.standard_resolution.url.ToString() : "",
      User = new InstagramModel.UserAccount()
             {
               username = obj.user.username,
               website = obj.user.website,
               profile_picture = obj.user.profile_picture,
               full_name = obj.user.full_name,
               bio = obj.user.bio,
               id = obj.user.id
             }
    });
  }

  return Json(lstInstagramObjects, JsonRequestBehavior.AllowGet);
}

Một ví dụ về một trường hợp trong đó điều này hữu ích là khi đối tượng tôi đang cố gắng giải tuần tự hóa có chứa một thuộc tính là giao diện
soupy1976

2
Một lời giải thích sẽ theo thứ tự.
Peter Mortensen

Tại sao bạn thích điều này hơn câu trả lời được chấp nhận bởi @Icarus?
Câu hỏi

@Questioning, khử lưu huỳnh cho các lớp loại mạnh sẽ bỏ qua bất kỳ thuộc tính nào không có trong các lớp của bạn, trong khi việc khử lưu trữ đối với các đối tượng động sẽ chỉ trả về đối tượng .Net linh hoạt cho bất kỳ thuộc tính mới nào được tạo trong tương lai mà không yêu cầu cập nhật các lớp của bạn. (như tôi đã nói, đôi khi không chuẩn)
Bishoy Hanna

38

Một cách tuyệt vời để tự động tạo các lớp này cho bạn là sao chép đầu ra JSON của bạn và ném nó vào đây:

http://json2csharp.com/

Nó sẽ cung cấp cho bạn một điểm khởi đầu để liên lạc với các lớp học của bạn để giải trừ.


28

Rất dễ dàng, chúng tôi có thể phân tích nội dung JSON với sự trợ giúp của từ điển và JavaScriptSerializer. Đây là mã mẫu mà tôi phân tích nội dung JSON từ tệp ashx.

var jss = new JavaScriptSerializer();
string json = new StreamReader(context.Request.InputStream).ReadToEnd();
Dictionary<string, string> sData = jss.Deserialize<Dictionary<string, string>>(json);
string _Name = sData["Name"].ToString();
string _Subject = sData["Subject"].ToString();
string _Email = sData["Email"].ToString();
string _Details = sData["Details"].ToString();

3
Giải pháp này rất hữu ích nếu bạn không có thời gian hoặc không cần tạo hợp đồng dữ liệu. Đặc biệt là nếu bạn chỉ quan tâm đến một vài thuộc tính được chôn sâu trong cấu trúc JSON. Trong tình huống đó, bạn có thể sử dụng một loạt các câu lệnh để điều hướng đến những gì bạn cần. Lưu ý: kiểu để deserialize cũng có thể là một trong những điều sau đây: Dictionary <string, object> hoặc ArrayList (khi một nút có cấu trúc lặp lại).
Philippe Monnet

1
Tôi nhận được một ngoại lệ thời gian chạy với điều này: Không có hàm tạo không tham số nào được xác định cho loại 'System.String' trên dòng mã Deserialize.
RSK

20

Newtonsoft.JSONlà một giải pháp tốt cho các loại tình huống. Cũng Newtonsof.JSONnhanh hơn những người khác, chẳng hạn như JavaScriptSerializer,DataContractJsonSerializer .

Trong mẫu này, bạn có thể như sau:

var jsonData = JObject.Parse("your JSON data here");

Sau đó, bạn có thể truyền jsonData tới JArray, và bạn có thể sử dụng mộtfor vòng lặp để lấy dữ liệu ở mỗi lần lặp.

Ngoài ra, tôi muốn thêm một cái gì đó:

for (int i = 0; (JArray)jsonData["data"].Count; i++)
{
    var data = jsonData[i - 1];
}

Làm việc với đối tượng động và sử dụng tuần tự hóa Newtonsoft là một lựa chọn tốt.


15

Tôi đồng ý với Icarus (sẽ nhận xét nếu tôi có thể), nhưng thay vì sử dụng lớp CustomObject , tôi sẽ sử dụng Từ điển (trong trường hợp Facebook thêm một cái gì đó).

private class MyFacebookClass
{
    public IList<IDictionary<string, string>> data { get; set; }
}

hoặc là

private class MyFacebookClass
{
    public IList<IDictionary<string, object>> data { get; set; }
}

3
Sử dụng năng động hoạt động tốt hơn trong các phiên bản mới. public IList<IDictionary<string, dynmaic>> data { get; set; }
BJury

3

Tuần tự hóa:

// Convert an object to JSON string format
string jsonData = JsonConvert.SerializeObject(obj);

Response.Write(jsonData);

Giải trừ ::

Để khử lưu huỳnh một đối tượng động

  string json = @"{
      'Name': 'name',
      'Description': 'des'
    }";

var res = JsonConvert.DeserializeObject< dynamic>(json);

Response.Write(res.Name);

3

Bạn có thể sử dụng tiện ích mở rộng này

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

1

Đây là một trang web khác sẽ giúp bạn với tất cả các mã bạn cần miễn là bạn có sẵn một chuỗi JSON được định dạng chính xác:

https://app.quicktype.io/


1

Nếu bạn đang sử dụng .NET Core 3.0, bạn có thể sử dụng System.Text.Json (hiện đã được tích hợp sẵn) để giải tuần tự hóa JSON.

Bước đầu tiên là tạo các lớp để mô hình hóa JSON. Có nhiều công cụ có thể giúp với điều này, và một số câu trả lời ở đây liệt kê chúng.

Một số tùy chọn là http://json2csharp.com , http://app.quicktype.io hoặc sử dụng Visual Studio (menu Chỉnh sửaDán Đặc biệtDán JSON làm lớp ).

public class Person
{
    public string Id { get; set; }
    public string Name { get; set; }
}

public class Response
{
    public List<Person> Data { get; set; }
}

Sau đó, bạn có thể giải tuần tự hóa bằng cách sử dụng:

var people = JsonSerializer.Deserialize<Response>(json);

Nếu bạn cần thêm cài đặt, chẳng hạn như camelCasexử lý, sau đó chuyển cài đặt serializer vào trình giải nén như thế này:

var options = new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
var person = JsonSerializer.Deserialize<Response>(json, options);
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.