根據預設,JSON 輸出中的屬性名稱和索引鍵(包括大小寫)保持不變。 列舉值會以數字表示。 屬性會依其定義的順序進行序列化。 不過,您可以透過下列方式自訂這些行為:
- 指定特定的序列化屬性和列舉成員名稱。
- 針對屬性名稱和字典鍵,使用內建命名原則,例如駝峰式命名法、蛇形命名法或連字命名法。
- 針對屬性名稱和字典索引鍵使用自訂命名原則。
- 使用或不使用命名原則,將列舉值序列化為字串。
- 設定序列化屬性的順序。
注意
Web 預設命名原則為駝峰式大小寫。
提示
您可以使用 AI 協助來 建立具有自訂串行化屬性的物件。
對於需要特殊處理 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
}
此屬性設置的屬性名稱:
- 序列化和還原序列化雙向適用。
- 優先順序高於屬性命名原則。
- 不會影響參數化建構函式的參數名稱比對。
使用內建命名原則
下表顯示內建式命名原則及其對屬性名稱的影響。
| 命名原則 | 描述 | 原始屬性名稱 | 轉換的屬性名稱 |
|---|---|---|---|
| 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"
//}
使用 AI 自訂屬性名稱串行化的方式
您可以使用 GitHub Copilot 之類的 AI 工具,將變更模式套用至程式代碼串行化的方式。
假設您的類別宣告具有下列 PascalCasing屬性,且專案的 JSON 標準為 snake_casing。 您可以使用 AI 將必要的 [JsonPropertyName] 屬性新增至類別中的每個屬性。 您可以使用 Copilot 透過聊天提示進行這些變更,如下所示:
Update #ClassName:
when the property name contains more than one word,
change the serialized property name to use underscores between words.
Use built-in serialization attributes.
以下是包含簡單類別之範例的更完整版本。
Take this C# class:
public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public int TemperatureF { get; set; }
public string? Summary { get; set; }
public int WindSpeed { get; set; }
}
When the property name contains more than one word,
change the serialized property name to use underscores between words.
Use built-in serialization attributes.
在應用之前查看 Copilot 的建議。
如需 GitHub Copilot 的詳細資訊,請參閱 GitHub 的 常見問題集。
另請參閱
- System.Text.Json 概觀
- 如何將 JSON 序列化及還原序列化
- Visual Studio 中的 GitHub Copilot
- VS Code 中的 GitHub Copilot