แปลงสตริง JSON เป็นวัตถุ C #


183

กำลังพยายามแปลงสตริง JSON เป็นวัตถุใน C # ใช้กรณีทดสอบที่เรียบง่ายจริงๆ:

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

ปัญหาคือว่า route_list ไม่เคยได้รับการตั้งค่า; มันเป็นวัตถุที่ไม่ได้กำหนด ความคิดใด ๆ


1
@ Greg: ที่จริงผมขอแนะนำให้JavaScriptSerializerมากกว่ารุ่น MS ของมันจะไม่ยอมรับสิ่งอื่น แต่ JSON ที่กำหนดเอง WCF ของการจัดรูปแบบ (เช่นฟิลด์วันที่มีลักษณะเหมือนวัน แต่ไม่ล้อมรอบในวันที่ () ล้มเหลวเข็ญใจ)
แบรดคริสตี้

นอกจากนี้ให้ดูที่การแยกวิเคราะห์ออบเจ็กต์ JSON ด้วย JavascriptSerializer ในบทความ.NETซึ่งจริงๆแล้วเป็นแบบฝึกหัดที่ยอดเยี่ยม
scatmoi

คุณได้รับ JavaScriptSerializer ที่ไหน ไม่รู้จักในโครงการ C # .NET 3.5 ของฉัน
B. Clay Shannon

1
@B Clay Shannon วิธีนี้แก้ไขได้สำหรับฉันstackoverflow.com/questions/7000811/…
Fuzzybear

คำตอบ:


127

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

ตัวอย่างเช่น

  class Test {

      String test; 

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

  }

จากนั้นรหัสการดีซีเรียลไลเซชันของคุณจะเป็น:

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

ข้อมูลเพิ่มเติมสามารถพบได้ในบทช่วยสอนนี้: http://www.codeproject.com/Tips/79435/Deserialize-JSON-with-Csharp.aspx


1
แต่ในการใช้บทความ autoproperties เป็นมูลค่าการกล่าวขวัญเกินไป
Ivan Kochurkin

11
ขออภัยตัวอย่างโค้ดนี้ใช้งานไม่ได้ DeserializeObject ให้ข้อยกเว้น ใช้ var route_list = serializer.Deserialize <Test> ("{\" test \ ": \" some data \ "}"); แทน. นอกจากนี้คุณไม่จำเป็นต้องได้รับ / setTest () และการทดสอบสตริงควรเป็นแบบสาธารณะ ดูเหมือนว่า java มากกว่า C #
dvallejo

ดังที่แดนวัลเลโจกล่าวถึงนี่เป็นวิธีแก้ไขที่ไม่ถูกต้อง ท้ายที่สุด setTest (การทดสอบสตริง) จะไม่ส่งคืนซึ่งเป็นข้อผิดพลาดในการคอมไพล์เช่นกัน
Payam

1
ยังสามารถใช้สิ่งนี้: json_serializer.Deserialize <Test> ("{\" test \ ": \" some data \ "}"); // แทน (ทดสอบ) json_serializer .....
Bashar Abu Shamaa

1
หากคุณไม่แน่ใจเกี่ยวกับรูปแบบสำหรับคลาสอ็อบเจ็กต์ของคุณให้ลองลิงก์นี้ มันแปลสตริง Json ของคุณเป็นคลาสที่เหมาะสม ช่วยฉันทีหนึ่งครั้ง!
jade290

231

หรือคุณสามารถใช้ไลบรารี Newtownsoft.Json ดังต่อไปนี้:

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

Tประเภทวัตถุของคุณตรงกับสตริง JSON ของคุณอยู่ที่ไหน


3
มันง่ายมากและฉันคิดมานานเกี่ยวกับวิธีการทำเช่นนี้
maracuja-juice

58

คุณอาจไม่ต้องการแค่ประกาศ Route_list เป็นobjectประเภท มันไม่มีคุณสมบัติการทดสอบดังนั้นคุณจะไม่ได้วัตถุกลับคืนมาจริงๆ นี่คือหนึ่งในสถานที่เหล่านั้นที่คุณจะดีกว่าการกำหนดชั้นเรียนหรือโครงสร้างหรือใช้ประโยชน์จากคำหลักแบบไดนามิก

หากคุณต้องการให้รหัสนี้ทำงานตามที่คุณมีจริง ๆ คุณจะต้องรู้ว่าวัตถุที่ส่งกลับโดย DeserializeObject เป็นพจนานุกรมทั่วไปของสตริงวัตถุ นี่คือรหัสที่จะทำอย่างนั้น:

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

หากคุณต้องการใช้คำสำคัญแบบไดนามิกคุณสามารถอ่านได้ที่นี่คุณสามารถอ่านวิธีการที่นี่

ถ้าคุณประกาศคลาสหรือ struct คุณสามารถเรียก Deserialize แทน DeserializeObject ดังนี้:

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

สิ่งที่ต้องทำ: json_serializer = new JavaScriptSerializer (); object route_list = (IDictionary <string, object>) json_serializer.DeserializeObject ("{\" ทดสอบ \ ": \" ข้อมูลบางอย่างที่นี่ \ "}"); ยังคงได้รับ 'route_list' ไม่มีอยู่ในบริบทปัจจุบัน
Justin

1
object routes_listอย่าใช้ ใช้varหรือทำซ้ำอย่างชัดเจนด้วยตนเองและประกาศ Route_list เป็น IDictionary <string, object>
mattmc3

31

การใช้วัตถุแบบไดนามิกกับ JavaScriptSerializer

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

//test Result = "some data"

19

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

โซลูชันรหัสบรรทัดเดียว

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

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

15

นี่คือคลาสที่เรียบง่ายฉันปูด้วยกันจากการโพสต์ต่างๆ .... มันถูกทดสอบประมาณ 15 นาที แต่ดูเหมือนว่าจะทำงานเพื่อจุดประสงค์ของฉัน มันใช้JavascriptSerializerในการทำงานซึ่งสามารถอ้างอิงในแอปของคุณโดยใช้ข้อมูลที่มีรายละเอียดในโพสต์นี้นี้

โค้ดด้านล่างสามารถเรียกใช้ใน LinqPad เพื่อทดสอบโดย:

  • คลิกขวาที่แท็บสคริปต์ของคุณใน LinqPad และเลือก "Query Properties"
  • การอ้างอิง "System.Web.Extensions.dll" ใน "การอ้างอิงเพิ่มเติม"
  • การเพิ่ม "เพิ่มเติม Namespace Imports" ของ "System.Web.Script.Serialization"

หวังว่ามันจะช่วย!

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

คุณสามารถบรรลุความต้องการของคุณได้อย่างง่ายดายโดยใช้ห้องสมุด Newtonsoft.Json ฉันกำลังเขียนตัวอย่างหนึ่งตัวอย่างด้านล่างให้ดู

คลาสสำหรับประเภทของวัตถุที่คุณได้รับ:

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

}

รหัส:

static void Main(string[] args)
{

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

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

      Console.ReadKey();
}

นี่เป็นวิธีที่ง่ายมากในการแยกวิเคราะห์ json ของคุณ


11

อย่างที่ tripletdad99 พูด

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

แต่ถ้าคุณไม่ต้องการสร้างวัตถุพิเศษคุณสามารถทำมันด้วยDictionaryแทน

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

นี่คือประโยชน์อย่างเต็มที่เมื่อคุณส่งพารามิเตอร์ไปที่ Url.Action (การกระทำ, คอนโทรลเลอร์, ผลลัพธ์)
Lapenkov Vladimir

8

เพิ่ม ddl นี้เพื่ออ้างอิงถึงโครงการของคุณ: System.Web.Extensions.dll

ใช้เนมสเปซนี้: using 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

คัดลอก Json ของคุณและวางที่กล่องข้อความในjson2csharpและคลิกที่ปุ่มสร้าง

csระดับจะถูกสร้างการใช้งานที่ไฟล์ cs ดังต่อไปนี้

var generatedcsResponce = JsonConvert.DeserializeObject(yourJson);

ในกรณีที่RootObjectมีชื่อของที่สร้างขึ้นcsไฟล์


4

อีกวิธีที่ง่ายและรวดเร็วในการกึ่งอัตโนมัติขั้นตอนเหล่านี้คือ:

  1. ใช้ JSON ที่คุณต้องการที่จะแยกและวางไว้ที่นี่: https://app.quicktype.io/ เปลี่ยนภาษาเป็น C # ในเมนูแบบเลื่อนลง
  2. อัปเดตชื่อที่ด้านบนซ้ายเป็นชื่อคลาสของคุณค่าเริ่มต้นเป็น "ยินดีต้อนรับ"
  3. ใน visual studio ไปที่เว็บไซต์ -> จัดการแพ็คเกจและใช้ NuGet เพื่อเพิ่ม Json.Net จาก Newtonsoft
  4. app.quicktype.io สร้างวิธีการทำให้เป็นอนุกรมขึ้นอยู่กับ Newtonsoft หรือคุณสามารถใช้รหัสเช่น:

    WebClient client = new WebClient ();

    string myJSON = client.DownloadString (" https://URL_FOR_JSON.com/JSON_STUFF ");

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


ลิงก์ใช้ไม่ได้อีกต่อไป
Myles J

ขอบคุณ Myles J ฉันได้อัปเดตเป็นเว็บไซต์ใหม่ที่ดูเหมือนจะทำงานได้ดี
Jason Hitchings

0

แปลงสตริง JSON เป็นวัตถุใน C # ใช้กรณีทดสอบด้านล่าง .. มันใช้งานได้สำหรับฉัน ที่นี่ " MenuInfo " เป็นวัตถุคลาส C # ของฉัน

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

ก่อนอื่นคุณต้องรวมไลบรารีไว้เช่น:

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