Bahasa
Catatan
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba masuk atau mengubah direktori.
Akses ke halaman ini memerlukan otorisasi. Anda dapat mencoba mengubah direktori.
Jenis yang tidak dapat diubah adalah jenis yang mencegah Anda mengubah properti atau nilai bidang objek apa pun setelah dibuat. Jenisnya mungkin rekaman data, tidak memiliki properti atau kolom publik, memiliki properti hanya-baca, atau memiliki properti dengan setter privat atau hanya-init. System.String adalah contoh jenis yang tidak dapat diubah. System.Text.Json menyediakan berbagai cara agar Anda dapat mendeserialisasi JSON ke jenis yang tidak dapat diubah.
Konstruktor dengan parameter
Secara default, System.Text.Json menggunakan konstruktor tanpa parameter publik default. Namun, Anda dapat memerintahkannya untuk menggunakan konstruktor berparameter, yang memungkinkan deserialisasi kelas atau struct yang tidak dapat diubah.
Untuk kelas, jika satu-satunya konstruktor adalah yang berparameter, konstruktor tersebut akan digunakan.
Untuk struct, atau kelas dengan beberapa konstruktor, tentukan yang akan digunakan dengan menerapkan atribut [JsonConstructor]. Ketika atribut tidak digunakan, konstruktor tanpa parameter publik selalu digunakan jika ada.
Contoh berikut menggunakan atribut
[JsonConstructor]:using System.Text.Json; using System.Text.Json.Serialization; namespace ImmutableTypes { public struct Forecast { public DateTime Date { get; } public int TemperatureC { get; } public string Summary { get; } [JsonConstructor] public Forecast(DateTime date, int temperatureC, string summary) => (Date, TemperatureC, Summary) = (date, temperatureC, summary); } public class Program { public static void Run() { string json = """ { "date":"2020-09-06T11:31:01.923395-07:00", "temperatureC":-1, "summary":"Cold" } """; Console.WriteLine($"Input JSON: {json}"); var options = JsonSerializerOptions.Web; Forecast forecast = JsonSerializer.Deserialize<Forecast>(json, options); Console.WriteLine($"forecast.Date: {forecast.Date}"); Console.WriteLine($"forecast.TemperatureC: {forecast.TemperatureC}"); Console.WriteLine($"forecast.Summary: {forecast.Summary}"); string roundTrippedJson = JsonSerializer.Serialize<Forecast>(forecast, options); Console.WriteLine($"Output JSON: {roundTrippedJson}"); } } } // Produces output like the following example: // //Input JSON: { "date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"summary":"Cold"} //forecast.Date: 9 / 6 / 2020 11:31:01 AM //forecast.TemperatureC: -1 //forecast.Summary: Cold //Output JSON: { "date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"summary":"Cold"}Imports System.Text.Json Imports System.Text.Json.Serialization Namespace ImmutableTypes Public Structure Forecast Public ReadOnly Property [Date] As Date Public ReadOnly Property TemperatureC As Integer Public ReadOnly Property Summary As String <JsonConstructor> Public Sub New([Date] As Date, TemperatureC As Integer, Summary As String) Me.Date = [Date] Me.TemperatureC = TemperatureC Me.Summary = Summary End Sub End Structure Public NotInheritable Class Program Public Shared Sub Main() Dim json As String = "{""date"":""2020-09-06T11:31:01.923395-07:00"",""temperatureC"":-1,""summary"":""Cold""}" Console.WriteLine($"Input JSON: {json}") Dim forecast1 As Forecast = JsonSerializer.Deserialize(Of Forecast)(json, JsonSerializerOptions.Web) Console.WriteLine($"forecast.Date: {forecast1.[Date]}") Console.WriteLine($"forecast.TemperatureC: {forecast1.TemperatureC}") Console.WriteLine($"forecast.Summary: {forecast1.Summary}") Dim roundTrippedJson As String = JsonSerializer.Serialize(forecast1, JsonSerializerOptions.Web) Console.WriteLine($"Output JSON: {roundTrippedJson}") End Sub End Class End Namespace ' Produces output like the following example: ' 'Input JSON: { "date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"summary":"Cold"} 'forecast.Date: 9 / 6 / 2020 11:31:01 AM 'forecast.TemperatureC: -1 'forecast.Summary: Cold 'Output JSON: { "date":"2020-09-06T11:31:01.923395-07:00","temperatureC":-1,"summary":"Cold"}Dalam .NET 7 dan versi yang lebih lama, atribut
[JsonConstructor]hanya dapat digunakan dengan konstruktor publik.
Nama parameter konstruktor berparameter harus cocok dengan nama dan jenis properti. Pencocokan dilakukan tanpa memperhatikan huruf besar/kecil, dan parameter konstruktor harus sesuai dengan nama properti aktual meskipun Anda menggunakan [JsonPropertyName] untuk mengubah nama properti. Dalam contoh berikut, nama untuk properti TemperatureC diubah menjadi celsius di JSON, tetapi parameter konstruktor masih bernama temperatureC:
using System.Text.Json;
using System.Text.Json.Serialization;
namespace ImmutableTypesCtorParms
{
public readonly struct Forecast
{
public DateTime Date { get; }
[JsonPropertyName("celsius")]
public int TemperatureC { get; }
public string Summary { get; }
[JsonConstructor]
public Forecast(DateTime date, int temperatureC, string summary) =>
(Date, TemperatureC, Summary) = (date, temperatureC, summary);
}
public class Program
{
public static void Run()
{
string json = """
{
"date":"2020-09-06T11:31:01.923395-07:00",
"celsius":-1,
"summary":"Cold"
}
""";
Console.WriteLine($"Input JSON: {json}");
var options = JsonSerializerOptions.Web;
Forecast forecast = JsonSerializer.Deserialize<Forecast>(json, options);
Console.WriteLine($"forecast.Date: {forecast.Date}");
Console.WriteLine($"forecast.TemperatureC: {forecast.TemperatureC}");
Console.WriteLine($"forecast.Summary: {forecast.Summary}");
string roundTrippedJson =
JsonSerializer.Serialize<Forecast>(forecast, options);
Console.WriteLine($"Output JSON: {roundTrippedJson}");
}
}
}
// Produces output like the following example:
//
//Input JSON: { "date":"2020-09-06T11:31:01.923395-07:00","celsius":-1,"summary":"Cold"}
//forecast.Date: 9 / 6 / 2020 11:31:01 AM
//forecast.TemperatureC: -1
//forecast.Summary: Cold
//Output JSON: { "date":"2020-09-06T11:31:01.923395-07:00","celsius":-1,"summary":"Cold"}
Selain [JsonPropertyName], atribut berikut mendukung deserialisasi dengan konstruktor berparameter:
Catatan
Rekaman juga didukung untuk serialisasi dan deserialisasi, seperti yang ditunjukkan dalam contoh berikut:
using System.Text.Json;
namespace Records
{
public record Forecast(DateTime Date, int TemperatureC)
{
public string? Summary { get; init; }
};
public class Program
{
public static void Run()
{
Forecast forecast = new(DateTime.Now, 40)
{
Summary = "Hot!"
};
string forecastJson = JsonSerializer.Serialize<Forecast>(forecast);
Console.WriteLine(forecastJson);
Forecast? forecastObj = JsonSerializer.Deserialize<Forecast>(forecastJson);
Console.WriteLine(forecastObj);
}
}
}
// Produces output like the following example:
//
//{ "Date":"2020-10-21T15:26:10.5044594-07:00","TemperatureC":40,"Summary":"Hot!"}
//Forecast { Date = 10 / 21 / 2020 3:26:10 PM, TemperatureC = 40, Summary = Hot! }
Anda dapat menerapkan salah satu atribut ke nama properti, menggunakan target property: pada atribut . Untuk informasi selengkapnya tentang catatan posisi, lihat artikel tentang merekam dalam referensi bahasa C#.
Anggota tidak publik dan pengakses properti
Anda dapat mengaktifkan penggunaan aksesor non-publik pada properti dengan menggunakan atribut [JsonInclude], seperti yang ditunjukkan dalam contoh berikut:
using System.Text.Json;
using System.Text.Json.Serialization;
namespace NonPublicAccessors
{
public class Forecast
{
public DateTime Date { get; init; }
[JsonInclude]
public int TemperatureC { get; private set; }
[JsonInclude]
public string? Summary { private get; set; }
};
public class Program
{
public static void Run()
{
string json = """
{
"Date":"2020-10-23T09:51:03.8702889-07:00",
"TemperatureC":40,
"Summary":"Hot"
}
""";
Console.WriteLine($"Input JSON: {json}");
Forecast forecastDeserialized = JsonSerializer.Deserialize<Forecast>(json)!;
Console.WriteLine($"Date: {forecastDeserialized.Date}");
Console.WriteLine($"TemperatureC: {forecastDeserialized.TemperatureC}");
json = JsonSerializer.Serialize<Forecast>(forecastDeserialized);
Console.WriteLine($"Output JSON: {json}");
}
}
}
// Produces output like the following example:
//
//Input JSON: { "Date":"2020-10-23T09:51:03.8702889-07:00","TemperatureC":40,"Summary":"Hot"}
//Date: 10 / 23 / 2020 9:51:03 AM
//TemperatureC: 40
//Output JSON: { "Date":"2020-10-23T09:51:03.8702889-07:00","TemperatureC":40,"Summary":"Hot"}
Imports System.Text.Json
Imports System.Text.Json.Serialization
Namespace NonPublicAccessors
Public Class Forecast
Public Property [Date] As Date
Private _temperatureC As Integer
<JsonInclude>
Public Property TemperatureC As Integer
Get
Return _temperatureC
End Get
Private Set(Value As Integer)
_temperatureC = Value
End Set
End Property
Private _summary As String
<JsonInclude>
Public Property Summary As String
Private Get
Return _summary
End Get
Set(Value As String)
_summary = Value
End Set
End Property
End Class
Public NotInheritable Class Program
Public Shared Sub Main()
Dim json As String = "{""Date"":""2020-10-23T09:51:03.8702889-07:00"",""TemperatureC"":40,""Summary"":""Hot""}"
Console.WriteLine($"Input JSON: {json}")
Dim forecastDeserialized As Forecast = JsonSerializer.Deserialize(Of Forecast)(json)
Console.WriteLine($"Date: {forecastDeserialized.[Date]}")
Console.WriteLine($"TemperatureC: {forecastDeserialized.TemperatureC}")
json = JsonSerializer.Serialize(forecastDeserialized)
Console.WriteLine($"Output JSON: {json}")
End Sub
End Class
End Namespace
' Produces output like the following example:
'
'Input JSON: { "Date":"2020-10-23T09:51:03.8702889-07:00","TemperatureC":40,"Summary":"Hot"}
'Date: 10 / 23 / 2020 9:51:03 AM
'TemperatureC: 40
'Output JSON: { "Date":"2020-10-23T09:51:03.8702889-07:00","TemperatureC":40,"Summary":"Hot"}
Dengan menyertakan properti yang memiliki setter privat, Anda tetap dapat mendeserialisasi properti tersebut.
Di .NET 8 dan versi yang lebih baru, Anda juga dapat menggunakan atribut [JsonInclude] untuk memasukkan anggota non-publik ke dalam kontrak serialisasi untuk tipe yang diberikan.
Nota
Dalam mode pembuatan sumber, Anda tidak dapat menyerialkan anggota private atau menggunakan aksesor private dengan memberikan anotasi atribut [JsonInclude] pada mereka. Dan Anda hanya dapat membuat serialisasi anggota internal atau menggunakan aksesor internal jika mereka berada dalam rakitan yang sama dengan JsonSerializerContextyang dihasilkan.
Properti baca-saja
Di .NET 8 dan versi lebih baru, properti baca-saja, atau yang tidak memiliki setter privat maupun publik, juga dapat dideserialisasi. Meskipun Anda tidak dapat mengubah instans yang dirujuk oleh properti, jika tipe properti bersifat dapat diubah, Anda dapat memodifikasinya. Misalnya, Anda dapat menambahkan elemen ke daftar. Untuk mendeserialisasi properti baca-saja, Anda perlu mengatur perilaku penanganan pembuatan objeknya ke mengisi alih-alih menggantikan. Misalnya, Anda dapat membuat anotasi properti dengan atribut JsonObjectCreationHandlingAttribute.
class A
{
[JsonObjectCreationHandling(JsonObjectCreationHandling.Populate)]
public List<int> Numbers1 { get; } = new List<int>() { 1, 2, 3 };
}
Untuk informasi selengkapnya, lihat Mengisi properti yang diinisialisasi.