Bagaimana cara global mengatur opsi default untuk System.Text.Json.JsonSerializer?

12

UPDATE [2019-12-23]: Karena sebagian input komunitas vokal masalah ini telah ditambahkan ke peta jalan untuk .NET 5.0.

UPDATE [2019-10-10]: Jika tertarik melihat perilaku ini diterapkan untukSystem.Text.Json.JsonSerializerpergilah ke masalah GitHub terbuka yang ditunjukkan oleh Chris Yungmann dan timbang.


Alih-alih ini:

JsonSerializerOptions options = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
    // etc.
};
JsonSerializer.Deserialize<SomeObject>(someJsonString, options);

Saya ingin melakukan sesuatu seperti ini:

// This property is a pleasant fiction
JsonSerializer.DefaultSettings = new JsonSerializerOptions
{
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
    // etc.
};

// This uses my options
JsonSerializer.Deserialize<SomeObject>(someJsonString); 

// And somewhere else in the same codebase...
// This also uses my options
JsonSerializer.Deserialize<SomeOtherObject>(someOtherJsonString); 

Harapannya adalah tidak harus melalui contoh JsonSerializerOptionsuntuk kasus kami yang paling umum, dan menimpa pengecualian, bukan aturan.

Seperti yang ditunjukkan dalam tanya jawab ini , ini adalah fitur yang berguna Json.Net. Aku melihat ke dalam dokumentasi untuk System.Text.Jsonserta repo GitHub ini untuk NET Core. Dan yang ini .

Tampaknya tidak ada analog untuk mengelola standar serialisasi JSON di .NET Core 3. Atau apakah saya mengabaikannya?

Trevor Reid
sumber
There doesn't seem to be an analog for managing JSON serialization defaults in Core-3- apakah Anda berbicara tentang permintaan masuk dan keluar dari API Anda? atau permintaan dan tanggapan terhadap sumber daya lain?
ps2goat
@ ps2goat Saya tidak yakin saya mengerti pertanyaan Anda. Masalahnya di sini adalah (de) serialisasi string JSON. Mereka bisa datang dari sejumlah sumber.
Trevor Reid
Saya bertanya karena ada tempat khusus selama startup untuk input dan output formatters (mis., Untuk pengikatan model)
ps2goat
Ah, mengerti. Dalam hal itu saya pikir kasus kami akan jatuh di bawah "sumber daya lain." @ ps2goat
Trevor Reid
Sangat menyedihkan, sampai .net core 3.1, masih belum ada serializer json yang baik.
Lelucon Huang

Jawaban:

4

Tidak, JsonSerializerOptionstidak memaparkan opsi default . Jika Anda menggunakan kerangka kerja web tertentu, mungkin ada cara untuk menentukan (tidak) pengaturan serialisasi melalui itu. Kalau tidak, saya sarankan untuk membuat metode kenyamanan Anda sendiri.

Lihat juga masalah terbuka ini .

Chris Yungmann
sumber
3

Anda dapat membuat metode ekstensi. Ini sebuah contoh

Saya menggunakan metode terpisah vs harus membangun pengaturan khusus, sehingga semua pengaturan akan berada di satu tempat dan mudah digunakan kembali.

public static class DeserializeExtensions
{
    private static JsonSerializerOptions defaultSerializerSettings = new JsonSerializerOptions();

    // set this up how you need to!
    private static JsonSerializerOptions featureXSerializerSettings = new JsonSerializerOptions();


    public static T Deserialize<T>(this string json)
    {       
        return JsonSerializer.Deserialize<T>(json, defaultSerializerSettings);
    }

    public static T DeserializeCustom<T>(this string json, JsonSerializerOptions settings)
    {
        return JsonSerializer.Deserialize<T>(json, settings);
    }

    public static T DeserializeFeatureX<T>(this string json)
    {
        return JsonSerializer.Deserialize<T>(json, featureXSerializerSettings);
    }
}

Kemudian Anda menyebutnya sebagai metode pada string, apakah literal atau variabel.

    Car result = @"{""Wheels"": 4, ""Doors"": 2}".DeserializeFeatureX<Car>();
ps2goat
sumber
Ah, Anda adalah jawaban tergantung Json.Net lain, saya pikir. Pertanyaan ini tentang System.Text.Json.JsonSerializerNET Core-3.0 tanpa dependensi tambahan. Terima kasih.
Trevor Reid
2
Itulah keindahan abstraksi. Tidak ada perubahan kode di luar kelas ekstensi ini! Saya baru saja memperbarui ke built in System.Text.Json.JsonSerializer. Konsepnya persis sama. Saya memperbarui tautan contoh.
ps2goat
2

Sebuah solusi telah diusulkan oleh GitHub pengguna andre-ss6 sebagai berikut:

((JsonSerializerOptions)typeof(JsonSerializerOptions)
    .GetField("s_defaultOptions", 
        System.Reflection.BindingFlags.Static |
        System.Reflection.BindingFlags.NonPublic).GetValue(null))
    .PropertyNameCaseInsensitive = true;
Trevor Reid
sumber
-1

(Jika Anda pernah beralih menggunakan Json.NET)

Saya lebih suka dan merekomendasikan untuk bersikap eksplisit dan meneruskan pengaturan ke semua panggilan, tetapi Anda dapat mengatur default dengan DefaultSettings .

JsonConvert.DefaultSettings = () => MySuperJsonSerializerSettings;

lalu

var json = JsonConvert.SerializeObject(o1);
var o2 = JsonConvert.DeserializeObject(x);
tymtam
sumber
Jawaban dan tautan oleh @tymtam ini berlaku untuk Json.Net. Pertanyaan ini menyangkut perilaku simialr di System.Text.Jsonmana serialisasi JSON dipanggang ke .NET Core 3.0. Terima kasih telah meluangkan waktu untuk merespons.
Trevor Reid