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

.NET Framework 4.7下MSTest用System.Text.Json遇ArrayTypeMismatchException

问题:.NET Framework 4.7下使用System.Text.Json自定义转换器时出现ArrayTypeMismatchException

环境与场景

  • .NET Framework 4.7
  • MSTest(所有包已更新)
  • 尝试通过自定义ObjectToInferredTypesConverter,使用System.Text.Json将JSON字符串反序列化为object类型并自动推断具体类型

测试代码

using System.Text.Json;

private static JsonSerializerOptions GetOptions()
{
    var options = new JsonSerializerOptions();
    options.Converters.Add(new ObjectToInferredTypesConverter()); // 错误触发点
    return options;
}

[TestMethod]
public void Read_TrueBoolean_ReturnsTrue()
{
    string json = "true";
    var result = JsonSerializer.Deserialize<object>(json, GetOptions());
    Assert.IsInstanceOfType(result, typeof(bool));
    Assert.IsTrue((bool)result);
}

自定义转换器实现

using System;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace Crashhash.Api.Helpers
{
    public class ObjectToInferredTypesConverter : JsonConverter<object>
    {
        public override object Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
        {
            return reader.TokenType switch
            {
                JsonTokenType.True => true,
                JsonTokenType.False => false,
                JsonTokenType.Number when reader.TryGetInt32(out int i) => i,
                JsonTokenType.Number when reader.TryGetInt64(out long l) => l,
                JsonTokenType.Number when reader.TryGetDouble(out double d) => d,
                JsonTokenType.String when reader.TryGetDateTime(out DateTime datetime) => datetime,
                JsonTokenType.String => reader.GetString()!,
                _ => JsonDocument.ParseValue(ref reader).RootElement.Clone()
            };
        }

        public override void Write(Utf8JsonWriter writer, object objectToWrite, JsonSerializerOptions options)
            => JsonSerializer.Serialize(writer, objectToWrite, objectToWrite.GetType(), options);
    }
}

关键诊断信息

通过反射确认存在程序集版本不匹配:

  • 自定义转换器基类的程序集版本:System.Text.Json.Serialization.JsonConverter, System.Text.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51
  • options.Converters.Add方法接收参数的程序集版本:System.Text.Json.Serialization.JsonConverter, System.Text.Json, Version=9.0.0.7, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51

错误信息

System.ArrayTypeMismatchException: Attempted to access an element as a type incompatible with the array.

堆栈跟踪:

List`1.Add(T item)
ConfigurationList`1.Add(TItem item)
ObjectToInferredTypesConverterTests.GetOptions() line 14
ObjectToInferredTypesConverterTests.Read_TrueBoolean_ReturnsTrue() line 22

对比验证

使用Newtonsoft.Json执行相同逻辑完全正常:

using Newtonsoft.Json;

[TestMethod]
public void example()
{
    string json = "true";
    var result = JsonConvert.DeserializeObject<object>(json);
    Assert.IsInstanceOfType(result, typeof(bool));
    Assert.IsTrue((bool)result);
}

已尝试清理重建解决方案、重装System.Text.Json包,问题未解决。


解决方案与替代方法

1. 修复程序集版本冲突

错误核心是System.Text.Json程序集版本不匹配:自定义转换器依赖9.0.0.0版本,而JsonSerializerOptions使用9.0.0.7版本,导致类型兼容问题。

  • 在项目的app.config或web.config中添加程序集绑定重定向,强制统一版本:
<configuration>
  <runtime>
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
      <dependentAssembly>
        <assemblyIdentity name="System.Text.Json" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
        <bindingRedirect oldVersion="0.0.0.0-9.0.0.7" newVersion="9.0.0.7" />
      </dependentAssembly>
    </assemblyBinding>
  </runtime>
</configuration>
  • 卸载所有相关NuGet包,重新安装指定版本(如9.0.0.7)的System.Text.Json,确保版本统一。

2. 沿用Newtonsoft.Json

Newtonsoft.Json在.NET Framework生态中兼容性更成熟,既然当前逻辑可正常运行,可继续使用该库替代System.Text.Json。

3. 升级框架版本

将项目升级到.NET Framework 4.8或更高版本,该版本对System.Text.Json的支持更完善,版本兼容性问题更少。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 15:53:18