Jac*_*amm 6 .net json.net system.text.json
我不明白为什么 System.Text.Json 不会将这个简单的 JSON 字符串反序列化为我指定的 .NET 类型。我收到Each parameter in the deserialization constructor on type \'MenuItem\' must bind to an object property or field on deserialization. Each parameter name must match with a property or field on the object. The match can be case-insensitive错误消息,即使我已在构造函数中映射了每个属性 \xe2\x80\x94 name、url和permissions\xe2\x80\x94 MenuItem。
using System;\nusing System.Collections.Generic;\nusing System.Text.Json;\nusing System.Text.Json.Serialization;\n\npublic class Program\n{\n    public static void Main()\n    {\n        try\n        {\n            var json = @"\n                [\n                    {\n                        ""name"": ""General Info"",\n                        ""url"": ""/Info"",\n                        ""permissions"": []\n                    },\n                    {\n                        ""name"": ""Settings"",\n                        ""url"": ""/Settings"",\n                        ""permissions"": [\n                            ""Admin""\n                        ]\n                    }\n                ]";\n\n            Console.WriteLine(json);\n            var menu = new Menu(json);\n            Console.WriteLine("Deserialization success");\n        }\n        catch (Exception ex)\n        {\n            Console.WriteLine($"Error: {ex.Message}");\n        }\n    }\n}\n\npublic class Menu\n{\n    public Menu(string json)\n    {\n        var items = JsonSerializer.Deserialize<List<MenuItem>>(json);\n        MenuItems = items.AsReadOnly();\n    }\n\n    public IReadOnlyList<MenuItem> MenuItems { get; }\n}\n\npublic class MenuItem\n{\n    [JsonConstructor]\n    public MenuItem\n        (\n            string name, \n            string url, \n            List<Permission> permissions\n        )\n    {\n        this.Name = name;\n        this.Url = url;\n        this.Permissions = (permissions ?? new List<Permission>()).AsReadOnly();\n    }\n\n    public string Name { get; }\n    public string Url { get; }\n    public IReadOnlyList<Permission> Permissions { get; }\n}\n\npublic enum Permission\n{\n    Admin,\n    FinancialReporting\n}\nRun Code Online (Sandbox Code Playgroud)\n谁能告诉我我做错了什么?
\n我看了你的小提琴并发现了一些问题。在这里工作小提琴
System.Text.Json默认情况下区分大小写(网络应用程序除外)。您可以通过使用序列化器选项中的PropertyNamingPolicy = JsonNamingPolicy.CamelCase或 来解决此问题。PropertyNameCaseInsensitive = true
默认情况下,枚举被序列化为数字。要将枚举名称序列化为字符串,请使用 JsonStringEnumConverter。
您应该添加JsonSerializerOptions解决方案(1)和(2):
var options = new JsonSerializerOptions 
{
    Converters =
    {
        new JsonStringEnumConverter(JsonNamingPolicy.CamelCase)
    },
    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
};
var items = JsonSerializer.Deserialize<List<MenuItem>>(json, options);
Run Code Online (Sandbox Code Playgroud)
第三个问题似乎与构造函数中的 列表的绑定有关Permissions。在构造函数中,您定义一个
List<Permission>权限参数。除非构造函数参数类型与模型属性类型完全匹配,否则我收到您问题中的错误。因此,我更新了构造函数以获取 aIReadOnlyList<Permission>并且它成功反序列化:
[JsonConstructor]
public MenuItem
    (
        string name, 
        string url,
        IReadOnlyList<Permission> permissions
    )
{
    this.Name = name;
    this.Url = url;
    this.Permissions = permissions ?? new List<Permission>().AsReadOnly();
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以将该Permissions属性更改为List<Permission>.
对具有类似问题的问题的回答解释了这实际上是 的限制System.Text.Json,并且当前存在一个开放的github 问题。
这里演示了你的小提琴的工作叉子。
|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           12057 次  |  
        
|   最近记录:  |