ฉันจะเปลี่ยนชื่อพร็อพเพอร์ตี้เมื่อซีเรียลไลซ์กับ Json.net ได้อย่างไร


434

ฉันมีข้อมูลบางอย่างในวัตถุ C # DataSet ฉันสามารถทำให้เป็นอันดับตอนนี้โดยใช้ตัวแปลง Json.net เช่นนี้

DataSet data = new DataSet();
// do some work here to populate 'data'
string output = JsonConvert.SerializeObject(data);

อย่างไรก็ตามสิ่งนี้ใช้ชื่อคุณสมบัติจากdataเมื่อพิมพ์ไปยังไฟล์. json ฉันต้องการเปลี่ยนชื่อคุณสมบัติเป็นชื่ออื่น (พูดเปลี่ยน 'foo' เป็น 'bar')

ในเอกสารประกอบของ Json.netภายใต้ 'Serializing and Deserializing JSON' → 'แอตทริบิวต์การทำให้เป็นอนุกรม' มันบอกว่า "JsonPropertyAttribute ... อนุญาตให้ชื่อถูกปรับแต่ง" แต่ไม่มีตัวอย่าง ไม่มีใครรู้วิธีใช้ JsonPropertyAttribute เพื่อเปลี่ยนชื่อคุณสมบัติเป็นอย่างอื่นหรือไม่

( ลิงก์โดยตรงไปยังเอกสารประกอบ )

เอกสารของ Json.net ดูเหมือนจะกระจัดกระจาย หากคุณมีตัวอย่างที่ยอดเยี่ยมฉันจะลองเพิ่มมันเข้าไปในเอกสารประกอบอย่างเป็นทางการ ขอบคุณ!


3
FYI มีเช่นนี้ในเอกสารประกอบตามตัวอย่าง -> Serializing JSON -> ชื่อ ไม่แน่ใจว่าเพิ่มในจุดใด
Brian Rogers

คำตอบ:


791

คุณสามารถตกแต่งคุณสมบัติที่คุณต้องการควบคุมชื่อด้วยแอ[JsonProperty]ททริบิวต์ที่ช่วยให้คุณสามารถระบุชื่ออื่น:

using Newtonsoft.Json;
// ...

[JsonProperty(PropertyName = "FooBar")]
public string Foo { get; set; }

เอกสาร: คุณสมบัติการทำให้เป็นอนุกรม


1
สิ่งนี้ต้องการให้ฉันอ่านข้อมูลของฉันลงในวัตถุที่กำหนดเองที่ฉันสร้างแทนที่จะเป็นชุดข้อมูลหรือไม่
culix

3
@culix, ใช่มันต้องการการใช้แบบจำลอง ชุดข้อมูลเป็นโครงสร้างที่พิมพ์อย่างอ่อนดังนั้นการพูดคุยเกี่ยวกับชื่อคุณสมบัติจึงไม่สมเหตุสมผล
ดารินทร์ดิมิทรอฟ

76
คุณสามารถทำได้[JsonProperty("FooBar")]
Bart Verkoeijen

2
@DarinDimitrov มีวิธีการทำเช่นนี้โดยไม่ Json .NET?
CH81

12
การใช้แบบจำลองนั้นทำได้ง่ายเพียงแค่นำตัวอย่างของ JSON ของคุณและวางลงในไฟล์. cs ที่ว่างโดยใช้ "วางแบบพิเศษ" -> "วาง JSON เป็นคลาส" - มันสร้างขึ้นใน Visual Studio - จากตรงนั้นคุณเพียงแค่ต้องตั้งค่าเป็นชื่อเรื่อง / เปลี่ยนชื่อเนื้อหาเพื่อใช้การตั้งชื่อ. NET แบบแผนการ ฯลฯ (โดยใช้ตัวแปลงชื่อเรื่องสำหรับอดีตและแอตทริบิวต์ JsonProperty สำหรับหลัง)
BrainSlugs83

71

หากคุณไม่สามารถเข้าถึงคลาสเพื่อเปลี่ยนคุณสมบัติหรือไม่ต้องการใช้คุณสมบัติการเปลี่ยนชื่อเดียวกันเสมอการเปลี่ยนชื่อสามารถทำได้ด้วยการสร้างตัวแก้ไขที่กำหนดเอง

ตัวอย่างเช่นถ้าคุณมีคลาสที่เรียกMyCustomObjectว่ามีคุณสมบัติที่เรียกว่าLongPropertyNameคุณสามารถใช้ตัวแก้ไขที่กำหนดเองเช่นนี้ ...

public class CustomDataContractResolver : DefaultContractResolver
{
  public static readonly CustomDataContractResolver Instance = new CustomDataContractResolver ();

  protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
  {
    var property = base.CreateProperty(member, memberSerialization);
    if (property.DeclaringType == typeof(MyCustomObject))
    {
      if (property.PropertyName.Equals("LongPropertyName", StringComparison.OrdinalIgnoreCase))
      {
        property.PropertyName = "Short";
      }
    }
    return property;
  }
}

จากนั้นเรียกใช้การทำให้เป็นอันดับและจัดหาตัวแก้ไข:

 var result = JsonConvert.SerializeObject(myCustomObjectInstance,
                new JsonSerializerSettings { ContractResolver = CustomDataContractResolver.Instance });

และผลลัพธ์จะสั้นลงเป็น{"Short": "prop value"}แทน{"LongPropertyName": "prop value"}

ข้อมูลเพิ่มเติมเกี่ยวกับตัวแก้ไขที่กำหนดเองที่นี่


1
นี่เป็นวิธีแก้ปัญหาที่ดีกว่าถ้าคลาสของคุณเพื่อทำให้เป็นอนุกรมถูกประกาศในชุดประกอบอื่นที่มีแพ็คเกจ Newtonsoft.Json รุ่นอื่น (อาจไม่ได้เกิดข้อผิดพลาด) DefaultContractResolverจะต้องใส่ในการชุมนุมที่เดียวกันที่ JsonConvert.Serialize () วิธีการที่จะใช้
Artemious

6

ยังมีวิธีการอื่นที่จะทำมันซึ่งมีการใช้โดยเฉพาะอย่างยิ่งNamingStrategyซึ่งสามารถนำไปใช้ในชั้นเรียนหรือสถานที่ให้บริการโดยการตกแต่งพวกเขาด้วยหรือ[JSonObject][JsonProperty]

มีกลยุทธ์การตั้งชื่อที่กำหนดไว้ล่วงหน้าเช่นCamelCaseNamingStrategyแต่คุณสามารถใช้กลยุทธ์ของคุณเองได้

การใช้กลยุทธ์การตั้งชื่อต่าง ๆ สามารถดูได้ที่นี่: https://github.com/JamesNK/Newtonsoft.Json/tree/master/Src/Newtonsoft.Json/Serialization


3
หากคุณสามารถทำได้โปรดแบ่งปันตัวอย่างของการปรับใช้ NamingStrategy ที่กำหนดเอง
user1007074

แน่นอน ... ไม่ คุณควรทำด้วยตัวเอง แต่ฉันจะให้เวลาคุณบอกคุณว่าคุณจะต้องสืบทอดnewtonsoft.com/json/help/html/ ......คุณสามารถดูการใช้คลาสที่มีอยู่แล้วสร้างของคุณเอง
JotaBe

Thanks - ฉันควรได้รับการปรับปรุงความคิดเห็นของฉัน: ในความเป็นจริงขอบคุณความรุ่งโรจน์ที่เป็น GitHub หนึ่งสามารถใช้หนึ่งในการใช้งานของ Newtonsoft เป็นตัวอย่างพูดคนนี้
user1007074

8
@JotaBe นั่นไม่ใช่จิตวิญญาณของ stackoverflow และในฐานะโปรแกรมเมอร์ที่ต้องการทำงานให้สำเร็จตรงไปตรงมามันจะดีกว่าเป็นพันเท่าที่ฉันจะยกรหัสที่คุณอาจให้ไว้ และคุณจะได้รับคะแนนของฉันเช่นกัน ฉันมีประสบการณ์ในการเขียนโค้ด 18 ปีและฉันได้รับการจัดอันดับจาก TripleByte ว่า "ผู้เชี่ยวชาญ" ใน c # ไม่ใช่ปัญหาทุกอย่างที่ต้องถูกทิ้งไว้เป็น "แบบฝึกหัดสำหรับผู้อ่าน" บางครั้งเราแค่ต้องการทำงานและเดินหน้าต่อไป
bboyle1234

2
ฉันเห็นด้วยกับคุณและฉันมักจะไม่แสดงความคิดเห็นแบบนี้ อย่างไรก็ตามฉันสามารถมั่นใจได้ว่าในกรณีนี้การดูรหัสที่เชื่อมโยงนั้นดีกว่าคำอธิบายใด ๆ ที่ฉันสามารถให้ได้ และ json.net เป็นไลบรารีโอเพนซอร์ซที่มีเอกสารที่ดีมาก ลิงก์ที่รวมไปถึงการใช้งาน (ตัวอย่างที่สมบูรณ์แบบ)
JotaBe
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.