Bagaimana saya bisa mengubah nama properti saat membuat serial dengan Json.net?

434

Saya memiliki beberapa data dalam objek C # DataSet. Saya dapat membuat cerita bersambung sekarang menggunakan konverter Json.net seperti ini

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

Namun, ini menggunakan nama properti dari datasaat mencetak ke file .json. Saya ingin mengubah nama properti menjadi sesuatu yang berbeda (katakanlah, ubah 'foo' menjadi 'bar').

Dalam dokumentasi Json.net , di bawah 'Serializing and Deserializing JSON' → 'Serialization Attributes' tertulis "JsonPropertyAttribute ... memungkinkan namanya dikustomisasi". Tetapi tidak ada contoh. Adakah yang tahu cara menggunakan JsonPropertyAttribute untuk mengubah nama properti menjadi sesuatu yang lain?

( Tautan langsung ke dokumentasi )

Dokumentasi Json.net tampaknya jarang. Jika Anda memiliki contoh yang bagus, saya akan mencoba untuk menambahkannya ke dokumentasi resmi. Terima kasih!

culix
sumber
3
FYI, ada contohnya di dokumentasi di bawah Sampel -> Serializing JSON -> JsonPropertyAttribute name . Tidak yakin pada titik mana ditambahkan.
Brian Rogers

Jawaban:

791

Anda bisa menghias properti yang ingin Anda kontrol namanya dengan [JsonProperty]atribut yang memungkinkan Anda menentukan nama yang berbeda:

using Newtonsoft.Json;
// ...

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

Dokumentasi: Atribut Serialisasi

Darin Dimitrov
sumber
1
Apakah ini mengharuskan saya membaca data saya menjadi objek kustom yang saya buat daripada DataSet?
Culix
3
@culix, ya, itu memang perlu menggunakan model. DataSet adalah struktur yang diketik dengan lemah, jadi berbicara tentang nama properti karena itu tidak terlalu logis.
Darin Dimitrov
76
Sebagai singkatan, Anda juga dapat melakukan[JsonProperty("FooBar")]
Bart Verkoeijen
2
@DarinDimitrov apakah ada cara untuk melakukan ini tanpa Json .NET?
CH81
12
Menggunakan model itu mudah, cukup ambil sampel JSON Anda dan tempel ke file .cs kosong menggunakan "Tempel Spesial" -> "Tempel JSON sebagai Kelas". - Ini dibangun untuk Visual Studio. - Dari sana, Anda pada dasarnya hanya perlu mengatur hal-hal sebagai judul huruf / mengubah nama hal untuk menggunakan. Konvensi penamaan NET, dll. (Menggunakan konverter judul kasus untuk yang pertama, dan atribut JsonProperty untuk yang terakhir).
BrainSlugs83
71

Jika Anda tidak memiliki akses ke kelas untuk mengubah properti, atau tidak ingin selalu menggunakan properti ganti nama yang sama, mengubah nama juga dapat dilakukan dengan membuat penyelesai kustom.

Misalnya, jika Anda memiliki kelas yang dipanggil MyCustomObject, yang memiliki properti bernama LongPropertyName, Anda dapat menggunakan penyelesai kustom seperti ini ...

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

Kemudian panggil serialisasi dan berikan resolver:

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

Dan hasilnya akan disingkat menjadi {"Short": "prop value"} alih-alih {"LongPropertyName": "prop value"}

Info lebih lanjut tentang resolver khusus di sini

Pelit
sumber
1
Ini adalah solusi yang lebih baik jika kelas Anda untuk serialisasi dideklarasikan di majelis lain yang menyertakan versi berbeda dari paket Newtonsoft.Json. (bahkan tidak menimbulkan kesalahan). The DefaultContractResolverharus dimasukkan ke dalam majelis yang sama di mana metode JsonConvert.Serialize () digunakan.
Artemious
6

Masih ada cara lain untuk melakukannya, yaitu menggunakan Strategi Penamaan tertentu , yang dapat diterapkan ke kelas atau properti dengan mendekorasi mereka dengan [JSonObject]atau [JsonProperty].

Ada beberapa strategi penamaan yang telah ditentukan CamelCaseNamingStrategy, tetapi Anda dapat menerapkannya sendiri.

Penerapan berbagai strategi penamaan dapat ditemukan di sini: https://github.com/JamesNK/Newtonsoft.Json/tree/master/Src/Newtonsoft.Json/Serialization

JotaBe
sumber
3
Jika Anda dapat, silakan bagikan contoh implementasi NamingStrategy khusus
user1007074
Tentu saja tidak. Anda seharusnya melakukannya sendiri, tetapi saya akan meluangkan waktu untuk memberi tahu Anda bahwa Anda hanya harus mewarisi newtonsoft.com/json/help/html/… Anda dapat melihat implementasi kelas yang ada, dan membuat sendiri.
JotaBe
Terima kasih - saya harus memperbarui komentar saya: pada kenyataannya, berkat kemuliaan GitHub, orang dapat menggunakan salah satu implementasi Newtonsoft sendiri sebagai contoh, katakanlah, yang ini
user1007074
8
@ JotaBe, itu bukan semangat stackoverflow. Dan sebagai seorang programmer yang hanya ingin menyelesaikan pekerjaan saya, terus terang, itu akan menjadi seribu kali lebih baik bagi saya untuk mengangkat kode yang mungkin Anda berikan. Dan Anda akan mendapatkan suara saya juga. Saya memiliki pengalaman coding selama 18 tahun, dan saya diberi peringkat oleh TripleByte sebagai "pakar" dalam c #. Tidak SETIAP masalah perlu dibiarkan sebagai "latihan untuk pembaca". Terkadang kita hanya ingin melakukan pekerjaan kita dan terus maju.
bboyle1234
2
Saya setuju dengan Anda, dan saya biasanya tidak menulis komentar semacam ini. Namun, saya dapat memastikan bahwa, dalam hal ini, melihat kode tertaut jauh lebih baik daripada penjelasan apa pun yang dapat saya berikan. Dan json.net adalah perpustakaan open source yang didokumentasikan dengan sangat baik. Termasuk tautan ke implementasi (contoh sempurna)
JotaBe