.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
相关产品推荐
相关产品推荐

