C#.NET如何反序列化键名唯一、结构一致的非数组JSON为C#对象列表
解决方案
错误原因
你的报错原因确实是JSON根节点为对象(键值对结构,大括号包裹),而非C# List<T> 对应的JSON数组(中括号包裹),类型不匹配导致反序列化失败。
修复步骤
1. 补全缺失的模型定义
你当前代码缺少Navigation类定义,先补充:
public class Navigation { public string Text { get; set; } [JsonPropertyName("section")] public string SectionKey { get; set; } }
2. 调整反序列化逻辑
不需要额外的Document包装类,直接将JSON根节点反序列化为Dictionary<string, Section>,字典的键就是JSON根节点的属性名(如preface、table-of-contents),值就是对应的Section对象:
// 修改服务类的GetDocuments方法 public IEnumerable<Section> GetDocuments() { using (var jsonFileReader = File.OpenText(JsonFileName)) { var sectionDict = JsonSerializer.Deserialize<Dictionary<string, Section>>( jsonFileReader.ReadToEnd(), new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); // 可选:如果需要在Section中保留对应的键名,可以给Section加SectionKey属性后赋值 // foreach (var kv in sectionDict) // { // kv.Value.SectionKey = kv.Key; // } return sectionDict.Values; } }
3. 修改Razor Page后台代码
调整Documents属性的类型:
public class IndexModel : PageModel { private readonly ILogger<IndexModel> _logger; public JsonFileService DocumentService; // 类型改为IEnumerable<Section> public IEnumerable<Section> Documents { get; private set; } public IndexModel(ILogger<IndexModel> logger, JsonFileService documentService) { _logger = logger; DocumentService = documentService; } public void OnGet() { Documents = DocumentService.GetDocuments(); } }
4. 调整Razor视图遍历逻辑
@foreach (var section in Model.Documents) { <h3>@section.Title</h3> @* 渲染正文内容 *@ @foreach (var paragraph in section.Content) { <p>@paragraph</p> } @* 渲染导航链接 *@ <div> @foreach (var nav in section.Navigations) { <a asp-page="Index" asp-route-section="@nav.SectionKey">@nav.Text</a> } </div> }
内容的提问来源于stack exchange,提问作者Ryan
相关产品推荐
相关产品推荐

