Chuyển đổi chuỗi JSON thành đối tượng C #


183

Cố gắng chuyển đổi một chuỗi JSON thành một đối tượng trong C #. Sử dụng một trường hợp thử nghiệm thực sự đơn giản:

JavaScriptSerializer json_serializer = new JavaScriptSerializer();
object routes_list = json_serializer.DeserializeObject("{ \"test\":\"some data\" }");

Vấn đề là Rout_list không bao giờ được đặt; nó là một đối tượng không xác định. Có ý kiến ​​gì không?


1
@Greg: Tôi thực sự khuyên dùng JavaScriptSerializerphiên bản của MS vì nó sẽ không chấp nhận bất cứ điều gì khác ngoài định dạng JSON tùy chỉnh của WCF (ví dụ: các trường ngày trông giống như ngày nhưng không bị bao vây trong DATE () thất bại thảm hại)
Brad Christie

Ngoài ra, hãy xem các đối tượng JSON phân tích cú pháp này với JavascriptSerializer trong bài viết .NET , đây thực sự là một hướng dẫn tuyệt vời.
scatmoi

Bạn lấy JavaScriptSerializer ở đâu? Nó không được nhận dạng trong dự án C # .NET 3.5 của tôi.
B. Clay Shannon

1
@B. Clay Shannon Điều này đã giải quyết nó cho tôi stackoverflow.com/questions/7000811/ từ
Fuzzybear 27/2/2015

Câu trả lời:


127

Có vẻ như bạn đang cố gắng khử lưu huỳnh thành một đối tượng thô. Bạn có thể tạo một lớp đại diện cho đối tượng mà bạn đang chuyển đổi. Điều này sẽ hữu ích nhất trong trường hợp bạn đang xử lý các đối tượng lớn hơn hoặc Chuỗi JSON.

Ví dụ:

  class Test {

      String test; 

      String getTest() { return test; }
      void setTest(String test) { this.test = test; }

  }

Sau đó, mã khử lưu huỳnh của bạn sẽ là:

   JavaScriptSerializer json_serializer = new JavaScriptSerializer();
   Test routes_list = 
          (Test)json_serializer.DeserializeObject("{ \"test\":\"some data\" }");

Thông tin chi tiết có thể được tìm thấy trong hướng dẫn này: http://www.codeproject.com/Tips/79435/Deserialize-JSON-with-Csharp.aspx


1
Nhưng trong bài viết tự động nhọn được sử dụng. Nó cũng đáng được đề cập.
Ivan Kochurkin

11
Xin lỗi, nhưng mẫu mã này không hoạt động. DeserializeObject đưa ra một ngoại lệ. Sử dụng var Rout_list = serializer.Deserialize <Test> ("{\" test \ ": \" một số dữ liệu \ "}"); thay thế. Ngoài ra, bạn không cần get / setTest () và kiểm tra chuỗi, nên công khai. Điều này trông giống như java hơn C #.
dvallejo

như Dan Vallejo đã đề cập, đây là một giải pháp không chính xác. Rốt cuộc, setTest (Kiểm tra chuỗi) không trả về, đó cũng là lỗi biên dịch.
Payam

1
Cũng có thể sử dụng điều này: json_serializer.Deserialize <Test> ("{\" test \ ": \" một số dữ liệu \ "}"); // thay vì (Kiểm tra) json_serializer .....
Bashar Abu Shamaa

1
Nếu bạn không chắc chắn về định dạng cho đối tượng lớp của mình, hãy thử liên kết này . Nó dịch chuỗi Json của bạn thành các lớp đúng. Tiết kiệm cho tôi rất nhiều thời gian!
jade290

228

Hoặc, bạn có thể sử dụng thư viện Newtownsoft.Json như sau:

using Newtonsoft.Json;
...
var result = JsonConvert.DeserializeObject<T>(json);

Trong trường hợp Tlà loại đối tượng của bạn phù hợp với chuỗi JSON của bạn.


3
Thật dễ dàng và tôi đã suy nghĩ rất lâu về cách làm điều này.
maracuja-

58

Bạn có thể không muốn chỉ khai báo Rout_list là một objectloại. Nó không có thuộc tính .test, vì vậy bạn thực sự sẽ không lấy lại một đối tượng đẹp. Đây là một trong những nơi mà bạn sẽ tốt hơn khi xác định một lớp hoặc một cấu trúc, hoặc sử dụng từ khóa động.

Nếu bạn thực sự muốn mã này hoạt động như bạn có, bạn sẽ cần biết rằng đối tượng được trả về bởi DeserializeObject là một từ điển chung của chuỗi, đối tượng. Đây là mã để làm theo cách đó:

var json_serializer = new JavaScriptSerializer();
var routes_list = (IDictionary<string, object>)json_serializer.DeserializeObject("{ \"test\":\"some data\" }");
Console.WriteLine(routes_list["test"]);

Nếu bạn muốn sử dụng từ khóa động, bạn có thể đọc cách ở đây .

Nếu bạn khai báo một lớp hoặc struct, bạn có thể gọi Deserialize thay vì DeserializeObject như vậy:

class MyProgram {
    struct MyObj {
        public string test { get; set; }
    }

    static void Main(string[] args) {
        var json_serializer = new JavaScriptSerializer();
        MyObj routes_list = json_serializer.Deserialize<MyObj>("{ \"test\":\"some data\" }");
        Console.WriteLine(routes_list.test);

        Console.WriteLine("Done...");
        Console.ReadKey(true);
    }
}

Đang làm: json_serializer = new JavaScriptSerializer (); object Rout_list = (IDadata <string, object>) json_serializer.DeserializeObject ("{\" test \ ": \" một số dữ liệu ở đây \ "}"); Vẫn nhận được 'Rout_list' không tồn tại trong bối cảnh hiện tại.
Justin

1
Đừng sử dụng object routes_list. Sử dụng varhoặc lặp lại một cách rõ ràng chính bạn và khai báo Rout_list dưới dạng IDadata <string, object>.
mattmc3

31

Sử dụng đối tượng động với JavaScriptSerializer.

JavaScriptSerializer serializer = new JavaScriptSerializer(); 
dynamic item = serializer.Deserialize<object>("{ \"test\":\"some data\" }");
string test= item["test"];

//test Result = "some data"

19

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.

giải pháp mã một dòng.

var myclass = Newtonsoft.Json.JsonConvert.DeserializeObject<dynamic>(Jsonstring);

Myclass oMyclass = Newtonsoft.Json.JsonConvert.DeserializeObject<Myclass>(Jsonstring);

15

Đây là một lớp đơn giản tôi đã tổng hợp lại từ nhiều bài viết khác nhau .... Nó đã được thử nghiệm trong khoảng 15 phút, nhưng dường như hoạt động cho mục đích của tôi. Nó sử dụng JavascriptSerializerđể thực hiện công việc, có thể được tham chiếu trong ứng dụng của bạn bằng cách sử dụng thông tin chi tiết trong bài đăng này .

Mã dưới đây có thể được chạy trong LinqPad để kiểm tra nó bằng cách:

  • Nhấp chuột phải vào tab tập lệnh của bạn trong LinqPad và chọn "Thuộc tính truy vấn"
  • Tham khảo "System.Web.Extensions.dll" trong "Tài liệu tham khảo bổ sung"
  • Thêm một "Nhập khẩu không gian tên bổ sung" của "System.Web.Script.Serialization".

Hy vọng nó giúp!

void Main()
{
  string json = @"
  {
    'glossary': 
    {
      'title': 'example glossary',
        'GlossDiv': 
        {
          'title': 'S',
          'GlossList': 
          {
            'GlossEntry': 
            {
              'ID': 'SGML',
              'ItemNumber': 2,          
              'SortAs': 'SGML',
              'GlossTerm': 'Standard Generalized Markup Language',
              'Acronym': 'SGML',
              'Abbrev': 'ISO 8879:1986',
              'GlossDef': 
              {
                'para': 'A meta-markup language, used to create markup languages such as DocBook.',
                'GlossSeeAlso': ['GML', 'XML']
              },
              'GlossSee': 'markup'
            }
          }
        }
    }
  }

  ";

  var d = new JsonDeserializer(json);
  d.GetString("glossary.title").Dump();
  d.GetString("glossary.GlossDiv.title").Dump();  
  d.GetString("glossary.GlossDiv.GlossList.GlossEntry.ID").Dump();  
  d.GetInt("glossary.GlossDiv.GlossList.GlossEntry.ItemNumber").Dump();    
  d.GetObject("glossary.GlossDiv.GlossList.GlossEntry.GlossDef").Dump();   
  d.GetObject("glossary.GlossDiv.GlossList.GlossEntry.GlossDef.GlossSeeAlso").Dump(); 
  d.GetObject("Some Path That Doesnt Exist.Or.Another").Dump();   
}


// Define other methods and classes here

public class JsonDeserializer
{
  private IDictionary<string, object> jsonData { get; set; }

  public JsonDeserializer(string json)
  {
    var json_serializer = new JavaScriptSerializer();

    jsonData = (IDictionary<string, object>)json_serializer.DeserializeObject(json);
  }

  public string GetString(string path)
  {
    return (string) GetObject(path);
  }

  public int? GetInt(string path)
  {
    int? result = null;

    object o = GetObject(path);
    if (o == null)
    {
      return result;
    }

    if (o is string)
    {
      result = Int32.Parse((string)o);
    }
    else
    {
      result = (Int32) o;
    }

    return result;
  }

  public object GetObject(string path)
  {
    object result = null;

    var curr = jsonData;
    var paths = path.Split('.');
    var pathCount = paths.Count();

    try
    {
      for (int i = 0; i < pathCount; i++)
      {
        var key = paths[i];
        if (i == (pathCount - 1))
        {
          result = curr[key];
        }
        else
        {
          curr = (IDictionary<string, object>)curr[key];
        }
      }
    }
    catch
    {
      // Probably means an invalid path (ie object doesn't exist)
    }

    return result;
  }
}

14

Bạn có thể thực hiện yêu cầu của mình một cách dễ dàng bằng cách sử dụng thư viện Newtonsoft.Json. Tôi đang viết ra một ví dụ dưới đây để xem xét nó.

Lớp cho loại đối tượng bạn nhận được:

public class User
{
    public int ID { get; set; }
    public string Name { get; set; }

}

Mã số:

static void Main(string[] args)
{

      string json = "{\"ID\": 1, \"Name\": \"Abdullah\"}";

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

      Console.ReadKey();
}

đây là một cách rất đơn giản để phân tích json của bạn.


11

Như tripletdad99 đã nói

var result = JsonConvert.DeserializeObject<T>(json);

nhưng nếu bạn không muốn để tạo ra một đối tượng thêm bạn có thể làm cho nó với Dictionarythay

var result = JsonConvert.DeserializeObject<Dictionary<string, string>>(json_serializer);

Điều này là hữu ích, sau đó bạn chuyển tham số cho Url.Action (hành động, bộ điều khiển, kết quả)
Lapenkov Vladimir

8

thêm ddl này để tham chiếu đến dự án của bạn: System.Web.Extensions.dll

sử dụng không gian tên này: sử dụng System.Web.Script.Serialization;

public class IdName
{
    public int Id { get; set; }
    public string Name { get; set; }
}


   string jsonStringSingle = "{'Id': 1, 'Name':'Thulasi Ram.S'}".Replace("'", "\"");
   var entity = new JavaScriptSerializer().Deserialize<IdName>(jsonStringSingle);

   string jsonStringCollection = "[{'Id': 2, 'Name':'Thulasi Ram.S'},{'Id': 2, 'Name':'Raja Ram.S'},{'Id': 3, 'Name':'Ram.S'}]".Replace("'", "\"");
   var collection = new JavaScriptSerializer().Deserialize<IEnumerable<IdName>>(jsonStringCollection);

6

Sao chép Json của bạn và dán vào hộp văn bản trên json2csharp và nhấp vào nút Tạo.

Một lớp cs sẽ được tạo sử dụng tệp cs đó như dưới đây

var generatedcsResponce = JsonConvert.DeserializeObject(yourJson);

Trong trường hợp RootObjectlà tên của tạo cs tập tin;


4

Một cách nhanh chóng và dễ dàng khác để tự động hóa các bước này là:

  1. lấy JSON mà bạn muốn phân tích và dán nó vào đây: https://app.quicktype.io/ . Thay đổi ngôn ngữ thành C # trong trình đơn thả xuống.
  2. Cập nhật tên ở trên cùng bên trái thành tên lớp của bạn, nó mặc định là "Chào mừng".
  3. Trong phòng thu trực quan, hãy truy cập Trang web -> Quản lý Gói và sử dụng NuGet để thêm Json.Net từ Newtonsoft.
  4. app.quicktype.io đã tạo ra các phương thức tuần tự hóa dựa trên Newtonsoft. Ngoài ra, bây giờ bạn có thể sử dụng mã như:

    Máy khách WebClient = WebClient mới ();

    chuỗi myJSON = client.DoadString (" https://URL_FOR_JSON.com/JSON_STUFF ");

    var myClass = Newtonsoft.Json.JsonConvert.DeserializeObject (myJSON);


Liên kết không còn hiệu lực
Myles J

Cảm ơn Myles J, tôi đã cập nhật lên một trang web mới có vẻ hoạt động tốt.
Jason Hitchings

0

Chuyển đổi một chuỗi JSON thành một đối tượng trong C #. Sử dụng trường hợp kiểm tra dưới đây .. nó làm việc cho tôi. Ở đây " MenuInfo " là đối tượng lớp C # của tôi.

JsonTextReader reader = null;
try
{
    WebClient webClient = new WebClient();
    JObject result = JObject.Parse(webClient.DownloadString("YOUR URL"));
    reader = new JsonTextReader(new System.IO.StringReader(result.ToString()));
    reader.SupportMultipleContent = true;
}
catch(Exception)
{}

JsonSerializer serializer = new JsonSerializer();
MenuInfo menuInfo = serializer.Deserialize<MenuInfo>(reader);

0

Đầu tiên bạn phải bao gồm thư viện như:

using System.Runtime.Serialization.Json;

DataContractJsonSerializer desc = new DataContractJsonSerializer(typeof(BlogSite));
string json = "{\"Description\":\"Share knowledge\",\"Name\":\"zahid\"}";

using (var ms = new MemoryStream(ASCIIEncoding.ASCII.GetBytes(json)))
{
    BlogSite b = (BlogSite)desc.ReadObject(ms);
    Console.WriteLine(b.Name);
    Console.WriteLine(b.Description);
}
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.