如何在PowerShell中将JSON响应反序列化为自定义强类型对象
问题根源
你遇到的报错本质是三个核心问题:
- 类型自动转换不支持:
Invoke-RestMethod默认返回的是PSCustomObject类型的对象/数组,PowerShell不会自动将这类对象递归转换为你自定义的类实例,也无法直接将普通数组转为System.Collections.Generic.List<T>泛型集合。 - 类定义语法问题:你提供的类是C#语法,无法直接在PowerShell中生效,需要调整为PowerShell原生类写法。
- 属性名匹配问题:JSON根节点下的数组键为大写开头的
Events,需要和自定义类的属性名保持一致避免潜在的匹配异常。
解决方法
方法1:PowerShell原生手动转换(无需引入第三方依赖)
首先修正你的类定义为PowerShell原生语法:
class DataType { [string] $key [string] $dataName } class DataTypeList { [string] $key [string] $name [string] $localeKey } class Event { [string] $key [string] $name [string] $localeKey [DataType] $DataType [System.Collections.Generic.List[DataTypeList]] $DataTypeList } class Root { [System.Collections.Generic.List[Event]] $Events }
之后编写转换逻辑遍历对象赋值:
# 获取接口响应 $responseRaw = Invoke-RestMethod -Uri "<API Link>" # 初始化根对象 $root = [Root]::new() $root.Events = [System.Collections.Generic.List[Event]]::new() # 遍历转换每个Event对象 foreach ($eventRaw in $responseRaw.Events) { # 转换DataType属性 $dataType = [DataType]::new() $dataType.key = $eventRaw.DataType.key $dataType.dataName = $eventRaw.DataType.dataName # 转换DataTypeList集合 $dataTypeList = [System.Collections.Generic.List[DataTypeList]]::new() foreach ($itemRaw in $eventRaw.DataTypeList) { $dtlItem = [DataTypeList]::new() $dtlItem.key = $itemRaw.key $dtlItem.name = $itemRaw.name $dtlItem.localeKey = $itemRaw.localeKey $dataTypeList.Add($dtlItem) } # 组装Event对象加入根集合 $eventObj = [Event]::new() $eventObj.key = $eventRaw.key $eventObj.name = $eventRaw.name $eventObj.localeKey = $eventRaw.localeKey $eventObj.DataType = $dataType $eventObj.DataTypeList = $dataTypeList $root.Events.Add($eventObj) }
此时$root就是符合你定义的Root类型的对象。
方法2:使用序列化类库直接反序列化(和C#用法一致)
如果你希望像C#里JsonConvert.DeserializeObject<Root>(json)一样一行代码完成转换,可以使用.NET内置的序列化类库,不需要手动写转换逻辑:
# 注意这里用Invoke-WebRequest获取原始JSON字符串,不要用Invoke-RestMethod $webResp = Invoke-WebRequest -Uri "<API Link>" $rawJson = $webResp.Content # PowerShell 7+ 可以直接用内置的System.Text.Json $root = [System.Text.Json.JsonSerializer]::Deserialize($rawJson, [Root]) # 如果你用的是Windows PowerShell 5.1,可以引入Newtonsoft.Json实现同样效果 # Add-Type -Path "你的Newtonsoft.Json.dll路径" # $root = [Newtonsoft.Json.JsonConvert]::DeserializeObject($rawJson, [Root])
内容的提问来源于stack exchange,提问作者Adam
相关产品推荐
相关产品推荐

