如何使用 System.Text.Json 自訂屬性名稱與值
根據預設,JSON 輸出中的屬性名稱和字典索引鍵會保持不變 (包括大小寫)。 列舉值會以數字表示。 屬性會依其定義的順序進行序列化。 不過,您可以透過下列方式自訂這些行為:
- 指定特定的串行化屬性和列舉成員名稱。
- 針對屬性名稱和字典索引鍵,使用內建命名原則,例如駝峰式大小寫、蛇式大小寫或肉串式大小寫。
- 針對屬性名稱和字典索引鍵使用自訂命名原則。
- 使用或不使用命名原則,將列舉值序列化為字串。
- 設定序列化屬性的順序。
注意
Web 預設命名原則為駝峰式大小寫。
提示
您可以使用 AI 輔助來透過 GitHub Copilot 自訂屬性名稱和值。
對於需要特殊處理 JSON 屬性名稱和值的其他案例,您可以實作自訂轉換器。
自訂個別屬性名稱
如果要設定個別屬性 (Property) 的名稱,請使用 [JsonPropertyName] 屬性 (Attribute)。
以下是要序列化的範例類型與產生的 JSON:
public class WeatherForecastWithPropertyName
{
public DateTimeOffset Date { get; set; }
public int TemperatureCelsius { get; set; }
public string? Summary { get; set; }
[JsonPropertyName("Wind")]
public int WindSpeed { get; set; }
}
Public Class WeatherForecastWithPropertyName
Public Property [Date] As DateTimeOffset
Public Property TemperatureCelsius As Integer
Public Property Summary As String
<JsonPropertyName("Wind")>
Public Property WindSpeed As Integer
End Class
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Summary": "Hot",
"Wind": 35
}
此屬性 (Attribute) 所設定的屬性 (Property) 名稱:
- 序列化和還原序列化雙向適用。
- 優先順序高於屬性命名原則。
- 不會影響參數化建構函式的參數名稱比對。
使用內建命名原則
下表顯示內建命名原則,及其如何影響屬性名稱。
命名原則 | 描述 | 原始屬性名稱 | 轉換的屬性名稱 |
---|---|---|---|
CamelCase | 第一個單字會以小寫字元開頭。 後續單字會以大寫字元開頭。 |
TempCelsius |
tempCelsius |
KebabCaseLower* | 單字會以連字號分隔。 所有字元都是小寫。 |
TempCelsius |
temp-celsius |
KebabCaseUpper* | 單字會以連字號分隔。 所有字元都是大寫。 |
TempCelsius |
TEMP-CELSIUS |
SnakeCaseLower* | 單字會以底線分隔。 所有字元都是小寫。 |
TempCelsius |
temp_celsius |
SnakeCaseUpper* | 單字會以底線分隔。 所有字元都是大寫。 |
TempCelsius |
TEMP_CELSIUS |
* 在 .NET 8 版和更新版本中可供使用。
下列範例示範如何藉由將 JsonSerializerOptions.PropertyNamingPolicy 設定為 JsonNamingPolicy.CamelCase,針對所有 JSON 屬性名稱使用駝峰式大小寫:
var serializeOptions = new JsonSerializerOptions
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, serializeOptions);
Dim serializeOptions As JsonSerializerOptions = New JsonSerializerOptions With {
.PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
.WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast, serializeOptions)
以下是要序列化的範例類別與 JSON 輸出:
public class WeatherForecastWithPropertyName
{
public DateTimeOffset Date { get; set; }
public int TemperatureCelsius { get; set; }
public string? Summary { get; set; }
[JsonPropertyName("Wind")]
public int WindSpeed { get; set; }
}
Public Class WeatherForecastWithPropertyName
Public Property [Date] As DateTimeOffset
Public Property TemperatureCelsius As Integer
Public Property Summary As String
<JsonPropertyName("Wind")>
Public Property WindSpeed As Integer
End Class
{
"date": "2019-08-01T00:00:00-07:00",
"temperatureCelsius": 25,
"summary": "Hot",
"Wind": 35
}
命名原則:
- 適用於序列化與還原序列化。
- 由
[JsonPropertyName]
屬性覆寫。 這就是範例中的 JSON 屬性名稱Wind
不是駝峰式大小寫的原因。
注意
內建命名原則皆不支援代理字組的字母。 如需詳細資訊,請參閱 dotnet/執行階段問題 90352。
使用自訂 JSON 屬性命名原則
如果要使用自訂 JSON 屬性命名原則,可建立衍生自 JsonNamingPolicy 的類別,並覆寫 ConvertName 方法,如下列範例所示:
using System.Text.Json;
namespace SystemTextJsonSamples
{
public class UpperCaseNamingPolicy : JsonNamingPolicy
{
public override string ConvertName(string name) =>
name.ToUpper();
}
}
Imports System.Text.Json
Namespace SystemTextJsonSamples
Public Class UpperCaseNamingPolicy
Inherits JsonNamingPolicy
Public Overrides Function ConvertName(name As String) As String
Return name.ToUpper()
End Function
End Class
End Namespace
然後,將 JsonSerializerOptions.PropertyNamingPolicy 屬性設定為命名原則類別的執行個體:
var options = new JsonSerializerOptions
{
PropertyNamingPolicy = new UpperCaseNamingPolicy(),
WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);
Dim options As JsonSerializerOptions = New JsonSerializerOptions With {
.PropertyNamingPolicy = New UpperCaseNamingPolicy,
.WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast1, options)
以下是要序列化的範例類別與 JSON 輸出:
public class WeatherForecastWithPropertyName
{
public DateTimeOffset Date { get; set; }
public int TemperatureCelsius { get; set; }
public string? Summary { get; set; }
[JsonPropertyName("Wind")]
public int WindSpeed { get; set; }
}
Public Class WeatherForecastWithPropertyName
Public Property [Date] As DateTimeOffset
Public Property TemperatureCelsius As Integer
Public Property Summary As String
<JsonPropertyName("Wind")>
Public Property WindSpeed As Integer
End Class
{
"DATE": "2019-08-01T00:00:00-07:00",
"TEMPERATURECELSIUS": 25,
"SUMMARY": "Hot",
"Wind": 35
}
JSON 屬性命名原則:
- 適用於序列化與還原序列化。
- 由
[JsonPropertyName]
屬性覆寫。 這就是範例中 JSON 屬性名稱Wind
不是大寫的原因。
使用字典索引鍵的命名原則
如果要序列化物件的屬性是 Dictionary<string,TValue>
類型,則可以使用命名原則來轉換 string
索引鍵,例如駝峰式大小寫。 若要這樣做,請將 JsonSerializerOptions.DictionaryKeyPolicy 設定為您想要的命名原則。 下列範例使用 CamelCase
命名原則:
var options = new JsonSerializerOptions
{
DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
WriteIndented = true
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);
Dim options As JsonSerializerOptions = New JsonSerializerOptions With {
.DictionaryKeyPolicy = JsonNamingPolicy.CamelCase,
.WriteIndented = True
}
jsonString = JsonSerializer.Serialize(weatherForecast, options)
使用具有機碼值組 TemperatureRanges
和 "ColdMinTemp", 20
且名為 "HotMinTemp", 40
的字典來將物件序列化會產生 JSON 輸出,如下列範例所示:
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Summary": "Hot",
"TemperatureRanges": {
"coldMinTemp": 20,
"hotMinTemp": 40
}
}
字典索引鍵的命名原則僅適用於序列化。 如果您還原序列化字典,即使將 JsonSerializerOptions.DictionaryKeyPolicy 設定為非預設命名原則,索引鍵也會符合 JSON 檔案。
以字串表示列舉
根據預設,會將列舉序列化為數字。 若要將列舉名稱序列化為字串,請使用 JsonStringEnumConverter 或 JsonStringEnumConverter<TEnum> 轉換器。 只有原生 AOT 執行階段才支援 JsonStringEnumConverter<TEnum>。
例如,假設您需要將下列具有列舉的類別序列化:
public class WeatherForecastWithEnum
{
public DateTimeOffset Date { get; set; }
public int TemperatureCelsius { get; set; }
public Summary? Summary { get; set; }
}
public enum Summary
{
Cold, Cool, Warm, Hot
}
Public Class WeatherForecastWithEnum
Public Property [Date] As DateTimeOffset
Public Property TemperatureCelsius As Integer
Public Property Summary As Summary
End Class
Public Enum Summary
Cold
Cool
Warm
Hot
End Enum
如果摘要是 Hot
,則根據預設,序列化的 JSON 會有數值 3:
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Summary": 3
}
下列範例程式碼會將列舉名稱 (而非數值) 序列化,並將名稱轉換為駝峰式大小寫:
options = new JsonSerializerOptions
{
WriteIndented = true,
Converters =
{
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
}
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);
options = New JsonSerializerOptions With {
.WriteIndented = True
}
options.Converters.Add(New JsonStringEnumConverter(JsonNamingPolicy.CamelCase))
jsonString = JsonSerializer.Serialize(weatherForecast, options)
產生的 JSON 類似下列範例:
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Summary": "hot"
}
內建的 JsonStringEnumConverter 也可以將字串值還原序列化。 它可以使用或不使用指定的命名原則來運作。 下列範例示範如何使用 CamelCase
來還原序列化:
options = new JsonSerializerOptions
{
Converters =
{
new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
}
};
weatherForecast = JsonSerializer.Deserialize<WeatherForecastWithEnum>(jsonString, options)!;
options = New JsonSerializerOptions
options.Converters.Add(New JsonStringEnumConverter(JsonNamingPolicy.CamelCase))
weatherForecast = JsonSerializer.Deserialize(Of WeatherForecastWithEnum)(jsonString, options)
JsonConverterAttribute
您也可以指定要使用的轉換器,方法是將列舉標註為 JsonConverterAttribute。 下列範例示範如何使用 JsonStringEnumConverter<TEnum> 屬性來指定 JsonConverterAttribute (在 .NET 8 和更新版本中提供)。 例如,假設您需要將下列具有列舉的類別序列化:
public class WeatherForecastWithPrecipEnum
{
public DateTimeOffset Date { get; set; }
public int TemperatureCelsius { get; set; }
public Precipitation? Precipitation { get; set; }
}
[JsonConverter(typeof(JsonStringEnumConverter<Precipitation>))]
public enum Precipitation
{
Drizzle, Rain, Sleet, Hail, Snow
}
下列範例程式碼會序列化列舉名稱,而不是數值:
var options = new JsonSerializerOptions
{
WriteIndented = true,
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);
產生的 JSON 看起來像這樣:
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Precipitation": "Sleet"
}
自定義列舉成員名稱
從 .NET 9 開始,您可以針對串行化為字串的類型,自定義個別列舉成員的名稱。 若要自定義列舉成員名稱,請使用 JsonStringEnumMemberName 屬性來標註它。
例如,假設您需要串行化具有具有自定義成員名稱列舉的下列類別:
public class WeatherForecastWithEnumCustomName
{
public DateTimeOffset Date { get; set; }
public int TemperatureCelsius { get; set; }
public CloudCover? Sky { get; set; }
}
[JsonConverter(typeof(JsonStringEnumConverter))]
public enum CloudCover
{
Clear,
[JsonStringEnumMemberName("Partly cloudy")]
Partial,
Overcast
}
下列範例程式碼會序列化列舉名稱,而不是數值:
var options = new JsonSerializerOptions
{
WriteIndented = true,
};
jsonString = JsonSerializer.Serialize(weatherForecast, options);
產生的 JSON 看起來像這樣:
{
"Date": "2019-08-01T00:00:00-07:00",
"TemperatureCelsius": 25,
"Sky": "Partly cloudy"
}
來源產生
若要搭配來源產生使用轉換器,請參閱將列舉欄位序列化為字串。
設定序列化屬性的順序
根據預設,屬性會依其類別中定義的順序進行序列化。
[JsonPropertyOrder]
屬性 (Attribute) 可讓您在序列化期間,指定 JSON 輸出中的屬性 (Property) 順序。
Order
屬性的預設值為零。 將 Order
設定為正數,以將屬性放置於具有預設值的屬性之後。 負數的 Order
會將屬性放置於具有預設值的屬性之前。 屬性會依從最低 Order
值到最高值的順序寫入。 以下是範例:
using System.Text.Json;
using System.Text.Json.Serialization;
namespace PropertyOrder
{
public class WeatherForecast
{
[JsonPropertyOrder(-5)]
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
[JsonPropertyOrder(-2)]
public int TemperatureF { get; set; }
[JsonPropertyOrder(5)]
public string? Summary { get; set; }
[JsonPropertyOrder(2)]
public int WindSpeed { get; set; }
}
public class Program
{
public static void Main()
{
var weatherForecast = new WeatherForecast
{
Date = DateTime.Parse("2019-08-01"),
TemperatureC = 25,
TemperatureF = 25,
Summary = "Hot",
WindSpeed = 10
};
var options = new JsonSerializerOptions { WriteIndented = true };
string jsonString = JsonSerializer.Serialize(weatherForecast, options);
Console.WriteLine(jsonString);
}
}
}
// output:
//{
// "Date": "2019-08-01T00:00:00",
// "TemperatureF": 25,
// "TemperatureC": 25,
// "WindSpeed": 10,
// "Summary": "Hot"
//}
使用 Github Copilot 自訂屬性名稱和順序
您可以在 IDE 中使用 GitHub Copilot 產生程式碼,以自訂序列化屬性的名稱和順序。 您可以自訂提示,以搭配符合您需求的屬性名稱和值輸出 JSON 字串。
下列範例示範如何使用 Copilot 修改現有的程式碼,在序列化為 JSON 時自訂屬性名稱和順序。
將下列 C# 範例程式碼新增至編輯器中的程式碼檔案
Example.cs
。 在 Visual Studio 中,您可以使用 C# 主控台應用程式專案來試用此範例。using System.Text.Json; public class Person { public string? FirstName { get; set; } public string? LastName { get; set; } public int Age { get; set; } public string? Country { get; set; } } public class Program { public static void Main() { var person = new Person { FirstName = "John", LastName = "Doe", Age = 30, Country = "USA" }; string jsonString = JsonSerializer.Serialize(person); Console.WriteLine(jsonString); } }
Example.cs
程式碼會執行下列動作:- 建立
Person
類別的執行個體,並初始化其屬性與值。 - 使用
person
將JsonSerializer.Serialize
物件序列化為 JSON 字串。 - 將下列 JSON 字串列印至主控台:
{"FirstName":"John","LastName":"Doe","Age":30,"Country":"USA"}
- 建立
在 Copilot Chat 中,輸入下列提示來修改程式碼,以自訂 JSON 序列化輸出的名稱和順序。
#Example.cs modify code to use System.Text.Json to customize property names and order of JSON output from serialization. Set property names: FirstName to first_name, LastName to last_name. Set order to: Country, FirstName, LastName, Age. Provide customized serialization output.
GitHub Copilot 是由 AI 驅動的,因此可能會有意外和錯誤的情況發生。 如需詳細資訊,請參閱 Copilot 常見問題。
深入瞭解 GitHub Copilot 在 Visual Studio 中 和 GitHub Copilot 在 VS Code 中。