ยกเลิกการทำให้เป็นรูป JSON ด้วย C #


206

ฉันพยายามยกเลิกการ เรียกGraph APIของเพื่อน Facebook ลงในรายการของวัตถุ วัตถุ JSON ดูเหมือนว่า:

{"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);

มันไม่ทำงานเพราะวัตถุดั้งเดิมไม่ถูกต้อง ฉันจะลบล้างสิ่งนี้ได้อย่างไร


3
เขียน deserializer ที่กำหนดเองโดยเฉพาะเพื่อตอบสนอง JSON เช่น ...
ashutosh Raina

2
หรือคุณสามารถใช้Dictionary<string,string>ดูได้ที่: stackoverflow.com/questions/7699972/…
Kakashi

9
เพื่อนของคุณ: json2csharp.com
nawfal

4
จริงๆแล้วสตูดิโอภาพ (ตั้งแต่ปี 2013 หรือปี 2012 ที่ติดตั้งเครื่องมือบนเว็บ) มีฟังก์ชั่นการใช้งานที่แน่นอนในตัว: แก้ไข> วางแบบพิเศษ> วาง JSON เป็นคลาส
floomby

คำตอบ:


264

คุณต้องสร้างโครงสร้างดังนี้:

public class Friends
{

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

public class FacebookFriend
{

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

จากนั้นคุณควรจะสามารถ:

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

ชื่อของชั้นเรียนของฉันเป็นเพียงตัวอย่าง คุณควรใช้ชื่อที่เหมาะสม

เพิ่มการทดสอบตัวอย่าง:

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

ผลิต:

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

3
ใช่มันเป็นสิ่งที่ฉันไม่ต้องการทำสร้างวัตถุใหม่เพื่อเก็บลูก ฉันคิดว่าฉันจะซับสตริง json ที่นำวัตถุดั้งเดิมออกมา ขอบคุณ.

@Kevin Holditch ขอบคุณสำหรับการแก้ไข ฉันพลาดบิตสำคัญไปหนึ่งตัว :)
อิคารัส

2
สิ่งที่ฉันไม่ชอบเกี่ยวกับ System.Web.Script.Serialization.JavaScriptSerializer () นี้คือคุณต้องการประเภท T ที่กำหนดไว้เสมอใน Java มีไลบรารี org.java นี้ (แพ็คเกจ) ที่ยังไม่ระบุชื่อทั้งหมด: "JSONObject [" param "]. JSONarray (5)" ฯลฯ
กีฬา

2
มันเป็นสิ่งสำคัญที่จะต้องทราบว่า setters สำหรับคุณสมบัติ id และชื่อจะต้องออกจากที่สาธารณะ หากถูกตั้งค่าเป็นส่วนตัวหรือได้รับการป้องกันการดีซีเรียลไลซ์เซชั่นจะดำเนินการโดยไม่มีข้อผิดพลาด แต่ข้อมูลทั้งหมดจะเป็นโมฆะ
Isaac Zais

2
@ กีฬาคุณสามารถทำได้ใน C # โดยการดีซีเรียลไลซ์เป็นแบบไดนามิก แต่ประสิทธิภาพจะดีขึ้นมากถ้าคุณทำการดีซีเรียลไลซ์เป็นประเภทที่รู้จัก
PRMan

50

บางครั้งฉันชอบวัตถุแบบไดนามิก:

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

ตัวอย่างหนึ่งของตัวอย่างที่สิ่งนี้มีประโยชน์คือเมื่อวัตถุที่ฉันพยายามที่จะทำการ deserialize มีคุณสมบัติที่เป็นส่วนต่อประสาน
soupy1976

2
คำอธิบายจะอยู่ในลำดับ
ปีเตอร์มอร์เทนเซ่น

ทำไมคุณถึงชอบมากกว่าคำตอบที่ยอมรับโดย @Icarus
ถามคำถาม

@Questioning, deserialising ไปยังคลาสประเภทที่แข็งแรงจะเพิกเฉยต่อคุณสมบัติใด ๆ ที่ไม่ได้อยู่ในคลาสของคุณในขณะที่การดีซีเรียลไลซ์ไปยังออบเจกต์แบบไดนามิกจะส่งคืนออบเจ็กต์ Dynamic .Net แบบยืดหยุ่น (ที่ผมกล่าวว่าบางครั้งไม่ได้มาตรฐาน)
Bishoy ฮันนา

39

วิธีที่ยอดเยี่ยมในการสร้างคลาสเหล่านี้ให้คุณโดยอัตโนมัติคือคัดลอกเอาต์พุต JSON ของคุณและส่งไปที่:

http://json2csharp.com/

มันจะช่วยให้คุณมีจุดเริ่มต้นเพื่อสัมผัสชั้นเรียนของคุณสำหรับ


28

ง่ายมากที่เราสามารถแยกเนื้อหา JSON ด้วยความช่วยเหลือของพจนานุกรมและ JavaScriptSerializer นี่คือตัวอย่างรหัสที่ฉันแยกเนื้อหา JSON จากไฟล์ 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
โซลูชันนี้มีประโยชน์มากหากคุณไม่มีเวลาหรือต้องการสร้างสัญญาข้อมูล โดยเฉพาะอย่างยิ่งหากคุณสนใจคุณสมบัติเพียงไม่กี่อย่างที่ฝังอยู่ในโครงสร้าง JSON ในสถานการณ์เช่นนั้นคุณอาจใช้ชุดข้อความเพื่อนำทางไปยังสิ่งที่คุณต้องการ หมายเหตุ: ชนิดของการดีซีเรียลไลซ์อาจเป็นหนึ่งในสิ่งต่อไปนี้: Dictionary <string, object> หรือ ArrayList (เมื่อโหนดมีโครงสร้างการทำซ้ำ)
Philippe Monnet

1
ฉันได้รับการยกเว้นเวลาทำงานด้วยสิ่งนี้: ไม่มีคอนสตรัคเตอร์ที่ไม่มีพารามิเตอร์กำหนดไว้สำหรับประเภทของ 'System.String' ในบรรทัด Deserialize ของรหัส
RSK

20

Newtonsoft.JSONเป็นทางออกที่ดีสำหรับสถานการณ์ประเภทนี้ นอกจากนี้ยังNewtonsof.JSONจะเร็วกว่าคนอื่น ๆ เช่น,JavaScriptSerializerDataContractJsonSerializer

ในตัวอย่างนี้คุณสามารถทำสิ่งต่อไปนี้:

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

จากนั้นคุณสามารถส่ง jsonData ไปที่JArrayและคุณสามารถใช้การforวนซ้ำเพื่อรับข้อมูลในแต่ละการวนซ้ำ

นอกจากนี้ฉันต้องการเพิ่มบางสิ่ง:

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

การทำงานกับวัตถุแบบไดนามิกและการใช้ Newtonsoft เป็นอันดับเป็นตัวเลือกที่ดี


15

ฉันเห็นด้วยกับอิคารัส (จะแสดงความคิดเห็นถ้าฉันทำได้) แต่แทนที่จะใช้คลาสCustomObjectฉันจะใช้พจนานุกรม (ในกรณีที่ Facebook เพิ่มบางสิ่ง)

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

หรือ

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

3
การใช้ไดนามิกจะทำงานได้ดีขึ้นในเวอร์ชันใหม่ public IList<IDictionary<string, dynmaic>> data { get; set; }
BJury

3

อันดับ:

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

Response.Write(jsonData);

Deserialization ::

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

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

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

Response.Write(res.Name);

3

คุณสามารถใช้ส่วนขยายนี้

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

นี่เป็นอีกไซต์หนึ่งที่จะช่วยให้คุณใช้รหัสทั้งหมดที่คุณต้องการตราบใดที่คุณมีสตริง JSON ที่จัดรูปแบบถูกต้อง:

https://app.quicktype.io/


1

หากคุณใช้. NET Core 3.0 คุณสามารถใช้System.Text.Json (ซึ่งตอนนี้มีอยู่แล้วภายใน) เพื่อยกเลิกการกำหนด JSON

ขั้นตอนแรกคือการสร้างคลาสเพื่อสร้างโมเดล JSON มีเครื่องมือมากมายที่สามารถช่วยได้และมีคำตอบบางส่วนที่นี่

ตัวเลือกบางตัวคือhttp://json2csharp.com , http://app.quicktype.ioหรือใช้ Visual Studio (เมนูแก้ไขวางแบบพิเศษวาง JSON เป็นคลาส )

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

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

จากนั้นคุณสามารถ deserialize โดยใช้:

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

หากคุณต้องการเพิ่มการตั้งค่าเช่นการcamelCaseจัดการจากนั้นให้ส่งการตั้งค่า serializer ไปยังดีซีเรียลไลเซอร์ดังนี้:

var options = new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase };
var person = JsonSerializer.Deserialize<Response>(json, options);
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.