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

ASP.NET MVC中VirtualStock多类型JSON序列化异常解决问询

解决ASP.NET MVC中返回Json时System.Text.Json不支持System.Object类型的异常

这个问题的核心原因很明确:你用Newtonsoft.Json成功完成了反序列化,但ASP.NET Core默认的Json()方法使用的是System.Text.Json,而System.Text.Json在处理object类型的属性时,无法正确识别它既可能是字符串又可能是复杂对象的情况,错误地将其当作集合处理,从而抛出了NotSupportedException。

下面给你三种可行的解决方案,按推荐程度排序:

方法一:让ASP.NET Core改用Newtonsoft.Json序列化返回结果(最推荐)

既然你已经在反序列化时使用了Newtonsoft.Json,直接让ASP.NET Core统一使用它来处理序列化,既能保持配置一致性,又能避免System.Text.Json的兼容性问题:

  1. 首先安装对应的NuGet包:
Install-Package Microsoft.AspNetCore.Mvc.NewtonsoftJson

或者用.NET CLI:

dotnet add package Microsoft.AspNetCore.Mvc.NewtonsoftJson
  1. 在项目的服务配置中替换默认的Json序列化器:
    • 如果你用的是.NET 6+的Program.cs:
    builder.Services.AddControllersWithViews()
        .AddNewtonsoftJson(options =>
        {
            // 这里可以和你反序列化时的配置保持一致
            options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
            options.SerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore;
            // 其他你需要的Newtonsoft.Json配置都可以加在这里
        });
    
    • 如果你用的是旧版的Startup.cs:
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddControllersWithViews()
            .AddNewtonsoftJson(options =>
            {
                options.SerializerSettings.NullValueHandling = NullValueHandling.Ignore;
                options.SerializerSettings.MissingMemberHandling = MissingMemberHandling.Ignore;
            });
    }
    

这样配置后,Controller中的Json()方法就会使用Newtonsoft.Json来序列化结果,它能完美处理object属性既为字符串又为复杂对象的场景,和你反序列化时的逻辑完全一致。

方法二:为System.Text.Json编写自定义转换器

如果你不想切换到NewtonsoftJson,可以为VirtualStock属性编写一个自定义的JsonConverter,让System.Text.Json能正确识别两种类型:

  1. 先定义VirtualStock的对象类型:
public class VirtualStockObject
{
    public string Value { get; set; }
    public bool IsAssigned { get; set; }
}
  1. 编写自定义转换器:
public class VirtualStockConverter : JsonConverter<object>
{
    public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        // 由于你已经用NewtonsoftJson做反序列化,这里的Read方法可以不用太关注
        if (reader.TokenType == JsonTokenType.String)
        {
            return reader.GetString();
        }
        else if (reader.TokenType == JsonTokenType.StartObject)
        {
            return JsonSerializer.Deserialize<VirtualStockObject>(ref reader, options);
        }
        return null;
    }

    public override void Write(Utf8JsonWriter writer, object value, JsonSerializerOptions options)
    {
        // 序列化时判断值的类型,分别处理
        if (value is string stringValue)
        {
            writer.WriteStringValue(stringValue);
        }
        else if (value is VirtualStockObject objValue)
        {
            JsonSerializer.Serialize(writer, objValue, options);
        }
        else
        {
            writer.WriteNullValue();
        }
    }
}
  1. 在模型的VirtualStock属性上标记这个转换器:
[JsonConverter(typeof(VirtualStockConverter))]
public object? VirtualStock { get; set; }

这样System.Text.Json在序列化时就能正确识别VirtualStock的两种类型,不会再抛出异常。

方法三:修改模型为自定义联合类型(适合需要业务处理的场景)

如果你的业务逻辑需要区分VirtualStock是字符串还是对象,可以定义一个专门的类型来封装这两种情况:

public class VirtualStockWrapper
{
    public string? StringValue { get; set; }
    public VirtualStockObject? ObjectValue { get; set; }

    // 辅助属性判断当前是哪种类型
    public bool IsStringType => StringValue != null;
}

// 之前定义的VirtualStockObject
public class VirtualStockObject
{
    public string Value { get; set; }
    public bool IsAssigned { get; set; }
}

然后修改模型中的属性:

public VirtualStockWrapper? VirtualStock { get; set; }

接着你需要在反序列化时用Newtonsoft.Json的自定义转换器来将原始的字符串或对象映射到这个Wrapper类中,这个方法相对复杂,适合需要对两种类型做不同业务处理的场景。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 18:32:35