.NET 小技巧 - 禁止 JSON 包含無法對映的屬性
1 |
讀者 Galaxy952 分享一則實際經驗:JSON 反序列化時,若出現對映型別上沒有的屬性一般都會選擇無視,但某些資安政策認為 JSON 反序列化容忍未被定義的屬性是一種風險。故詢問 .NET 要如何偵測 JSON 有多餘的屬性參數並回傳錯誤。
舉例來說,若我們的物件有 Id 及 Name 兩個屬性,若傳入 JSON 內容如下(多了 NoSuchProp),程式必須拋出例外並拒絕反序列化:
{
"Id": 32767,
"Name": "Jeffrey",
"NoSuchProp": "No mapping for this property"
}
先寫一小段程式驗證標準行為,分別用 Json.NET 跟 System.Text.Json 反序化這段多了 NoSuchProp 的 JSON 內容,二者都會無視 NoSuchProp 完成轉換。
using Newtonsoft.Json;
var json = @"{
""Id"": 32767,
""Name"": ""Jeffrey"",
""NoSuchProp"": ""No mapping for this property""
}";
try
{
var userJsonNet = JsonConvert.DeserializeObject<User>(json);
Console.WriteLine("Json.NET deserialized the object successfully");
}
catch (Exception ex)
{
Console.WriteLine("Json.NET ERROR-" + ex.Message);
}
try
{
var userTextJson = System.Text.Json.JsonSerializer.Deserialize<User>(json);
Console.WriteLine("System.Text.Json deserialized the object successfully");
}
catch (Exception ex)
{
Console.WriteLine("System.Text.Json ERROR-" + ex.Message);
}
class User {
public int Id {get; set;}
public string Name {get; set;}
}
要解決這個問題,Json.NET 可在 JsonSerializationOptions 加上 MissingMemberHandling.Error 設定;System.Text.Json 則是在 .NET 8 開始加入 JsonUnmappedMemberHandlingAttribute 標註物件不允許 JSON 包含未對映屬性。(若尚末升級 .NET 6 ,可考慮自己實作)
using System.Text.Json.Serialization;
using Newtonsoft.Json;
var json = @"{
""Id"": 32767,
""Name"": ""Jeffrey"",
""NoSuchProp"": ""No mapping for this property""
}";
try
{
var userJsonNet = JsonConvert.DeserializeObject<User>(json, new JsonSerializerSettings {
MissingMemberHandling = MissingMemberHandling.Error
});
Console.WriteLine("Json.NET deserialized the object successfully");
}
catch (Exception ex)
{
Console.WriteLine("Json.NET ERROR-" + ex.Message);
}
try
{
var userTextJson = System.Text.Json.JsonSerializer.Deserialize<User>(json);
Console.WriteLine("System.Text.Json deserialized the object successfully");
}
catch (Exception ex)
{
Console.WriteLine("System.Text.Json ERROR-" + ex.Message);
}
[JsonUnmappedMemberHandling(JsonUnmappedMemberHandling.Disallow)]
class User
{
public int Id { get; set; }
public string Name { get; set; }
}
修改後,Json.NET 及 System.Text.Json 便會因 JSON 多了 NoSuchProp 無法反序列化,搞定。
Guidelines on avoiding unmapped properties in JSON using Json.NET and System.Text.Json.
Comments
# by Galaxy952
謝謝黑大的詳解,我再來去修改程式測試。