使用Newtonsoft.Json反序列化JSON对象为字典失败,如何解决?
问题分析与解决方案
报错原因
你指定的目标类型Dictionary(Of String, List(Of String))要求JSON中每个键对应的值是数组(如["val1","val2"]),但你的JSON里locations和default都是嵌套对象(键值对结构),类型不匹配导致序列化失败。
第一步:修正JSON语法错误
原JSON中Template4后面多了一个多余的逗号,会导致解析异常,先修正为:
{"locations":{"Template1": "/c/temp/test1","Template2": "/c/temp/test2","Template3": "/c/temp/test3","Template4": "/c/temp/test4"},"default":{"repTempUrl": {"us": "Template1","de": "Template2"}}}
解决方案1:使用动态类型(完全动态场景)
如果不需要强类型,直接用ExpandoObject实现动态键值访问:
Imports Newtonsoft.Json Imports System.IO Imports System.Dynamic ' 读取并反序列化 Dim json = File.ReadAllText("c:\temp\test.json") Dim response = JsonConvert.DeserializeObject(Of ExpandoObject)(json) ' 示例访问 Dim template1Path = response("locations")("Template1") ' 获取"/c/temp/test1" Dim usDefaultTemplate = response("default")("repTempUrl")("us") ' 获取"Template1"
解决方案2:嵌套Dictionary类型(兼顾动态键与类型安全)
根据JSON结构,使用嵌套的Dictionary类型精准匹配:
Imports Newtonsoft.Json Imports System.IO Imports System.Collections.Generic ' 读取并反序列化 Dim json = File.ReadAllText("c:\temp\test.json") Dim rootDict = JsonConvert.DeserializeObject(Of Dictionary(Of String, Object))(json) ' 提取locations(动态键值对) Dim locations = JsonConvert.DeserializeObject(Of Dictionary(Of String, String))(rootDict("locations").ToString()) ' 提取repTempUrl(动态键值对) Dim defaultObj = JsonConvert.DeserializeObject(Of Dictionary(Of String, Object))(rootDict("default").ToString()) Dim repTempUrl = JsonConvert.DeserializeObject(Of Dictionary(Of String, String))(defaultObj("repTempUrl").ToString()) ' 示例访问 Console.WriteLine(locations("Template3")) ' 输出"/c/temp/test3" Console.WriteLine(repTempUrl("de")) ' 输出"Template2"
解决方案3:强类型+Dictionary(推荐,兼顾结构与动态键)
定义匹配的类结构,其中需要动态键的字段用Dictionary类型:
Imports Newtonsoft.Json Imports System.IO Imports System.Collections.Generic ' 定义类结构 Public Class DefaultConfig Public Property repTempUrl As Dictionary(Of String, String) End Class Public Class RootConfig Public Property locations As Dictionary(Of String, String) Public Property [default] As DefaultConfig ' default是VB关键字,需用方括号转义 End Class ' 反序列化 Dim json = File.ReadAllText("c:\temp\test.json") Dim config = JsonConvert.DeserializeObject(Of RootConfig)(json) ' 示例访问 Console.WriteLine(config.locations("Template4")) ' 输出"/c/temp/test4" Console.WriteLine(config.[default].repTempUrl("us")) ' 输出"Template1"
内容的提问来源于stack exchange,提问作者Mark Mullen
相关产品推荐
相关产品推荐

