You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ASP.NET POST控制器中嵌套JSON列表反序列化为Object问题

解决ASP.NET中嵌套KeyValue结构反序列化问题

问题分析

你当前的控制器接收List(Of KeyValueClass(Of String, Object))类型参数,原始类型值(如数字)能正常反序列化,但LinkedIDs对应的Value被解析为Object,无法自动转换为List(Of KeyValuePair(Of String, Integer))。核心原因是Object类型无明确类型信息,JSON序列化器无法推断嵌套数组的具体类型。

解决方案

方案1:改用强类型模型(推荐)

直接定义匹配JSON结构的强类型模型,避免使用Object,让序列化器自动处理类型映射:

' 定义嵌套的KeyValue类
Public Class KeyValuePairModel(Of TKey, TValue)
    Public Property Key As TKey
    Public Property Value As TValue
End Class

' 定义完整的输入模型
Public Class InputCommandModel
    Public Property CardCode As Integer
    Public Property PersonID As Integer
    Public Property LinkedIDs As List(Of KeyValuePairModel(Of String, Integer))
End Class

修改控制器方法:

<HttpPost>
Function InputCommand(model As InputCommandModel) As IActionResult
    ' 这里LinkedIDs已正确反序列化为List(Of KeyValuePairModel(Of String, Integer))
    ' 如需转换为KeyValuePair集合,可使用:
    Dim linkedIDPairs = model.LinkedIDs.Select(Function(kv) New KeyValuePair(Of String, Integer)(kv.Key, kv.Value)).ToList()
    ' 业务逻辑处理
    Return Ok()
End Function

方案2:自定义JSON转换器(保留原模型结构)

如果必须保留List(Of KeyValueClass(Of String, Object))的结构,可通过自定义JSON转换器识别嵌套的KeyValue数组并转换为目标类型。

以Newtonsoft.Json为例:

  1. 定义转换器:
Imports Newtonsoft.Json
Imports System.Collections.Generic
Imports System.Linq

Public Class NestedKeyValueListConverter
    Inherits JsonConverter(Of Object)

    Public Overrides Function ReadJson(reader As JsonReader, objectType As Type, existingValue As Object, serializer As JsonSerializer) As Object
        ' 判断当前JSON节点是否为数组
        If reader.TokenType = JsonToken.StartArray Then
            ' 反序列化为嵌套的KeyValueClass集合,再转换为KeyValuePair列表
            Dim nestedList = serializer.Deserialize(Of List(Of KeyValueClass(Of String, Integer)))(reader)
            Return nestedList.Select(Function(kv) New KeyValuePair(Of String, Integer)(kv.Key, kv.Value)).ToList()
        End If
        ' 非数组类型按默认逻辑反序列化
        Return serializer.Deserialize(reader)
    End Function

    Public Overrides Sub WriteJson(writer As JsonWriter, value As Object, serializer As JsonSerializer)
        serializer.Serialize(writer, value)
    End Function

    Public Overrides Function CanConvert(objectType As Type) As Boolean
        Return objectType = GetType(Object)
    End Function
End Class
  1. 在KeyValueClass的Value属性上标记转换器:
Public Class KeyValueClass(Of TKey, TValue)
    Public Property Key As TKey
    <JsonConverter(GetType(NestedKeyValueListConverter))>
    Public Property Value As TValue
End Class

以System.Text.Json为例:

  1. 定义转换器:
Imports System.Text.Json
Imports System.Text.Json.Serialization
Imports System.Collections.Generic
Imports System.Linq

Public Class NestedKeyValueListConverter
    Inherits JsonConverter(Of Object)

    Public Overrides Function Read(reader As Utf8JsonReader, typeToConvert As Type, options As JsonSerializerOptions) As Object
        If reader.TokenType = JsonTokenType.StartArray Then
            Dim nestedList = JsonSerializer.Deserialize(Of List(Of KeyValueClass(Of String, Integer)))(reader, options)
            Return nestedList.Select(Function(kv) New KeyValuePair(Of String, Integer)(kv.Key, kv.Value)).ToList()
        End If
        Return JsonSerializer.Deserialize(reader, typeToConvert, options)
    End Function

    Public Overrides Sub Write(writer As Utf8JsonWriter, value As Object, options As JsonSerializerOptions)
        JsonSerializer.Serialize(writer, value, options)
    End Function
End Class
  1. 在Startup中全局注册转换器:
services.AddControllers()
    .AddJsonOptions(Sub(options)
                       options.JsonSerializerOptions.Converters.Add(New NestedKeyValueListConverter())
                   End Sub)

方案3:手动类型转换(应急方案)

如果不想修改模型或添加转换器,可在控制器中手动将Object转换为目标类型:

<HttpPost>
Function InputCommand(Input As List(Of KeyValueClass(Of String, Object))) As IActionResult
    Dim linkedIDsItem = Input.FirstOrDefault(Function(kv) kv.Key = "LinkedIDs")
    If linkedIDsItem IsNot Nothing Then
        ' 手动反序列化Object为List(Of KeyValuePair(Of String, Integer))
        Dim linkedIDsJson = JsonConvert.SerializeObject(linkedIDsItem.Value)
        Dim linkedIDs = JsonConvert.DeserializeObject(Of List(Of KeyValuePair(Of String, Integer)))(linkedIDsJson)
        ' 使用linkedIDs处理业务逻辑
    End If
    Return Ok()
End Function

内容的提问来源于stack exchange,提问作者Machshevet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 21:32:35