在命名空间中找不到 System.Text.Json.JsonReaderException

Posted

技术标签:

【中文标题】在命名空间中找不到 System.Text.Json.JsonReaderException【英文标题】:System.Text.Json.JsonReaderException isn't found in namespace 【发布时间】:2020-09-09 00:15:50 【问题描述】:

我正在将 .NET Framework 4.5 项目转换为 .NET Core 3.1。我的测试曾经使用 Newtonsoft.Json 来检查 json 是否有效,现在我想用内置的 System.Text.Json 来实现它。看来

JsonElement values = JsonDocument.Parse(json).RootElement;

抛出System.Text.Json.JsonReaderException,但我无法捕捉到这一点,因为指向此异常会导致错误

命名空间“System.Text.Json”中不存在类型或命名空间名称“JsonReaderException”(您是否缺少程序集引用?)

我只是想了解如何可能抛出实际上似乎并不存在的东西。

更新#1: 堆栈跟踪:

   at System.Text.Json.ThrowHelper.ThrowJsonReaderException(Utf8JsonReader& json, ExceptionResource resource, Byte nextByte, ReadOnlySpan`1 bytes)
   at System.Text.Json.Utf8JsonReader.ReadSingleSegment()
   at System.Text.Json.Utf8JsonReader.Read()
   at System.Text.Json.JsonDocument.Parse(ReadOnlySpan`1 utf8JsonSpan, Utf8JsonReader reader, MetadataDb& database, StackRowStack& stack)
   at System.Text.Json.JsonDocument.Parse(ReadOnlyMemory`1 utf8Json, JsonReaderOptions readerOptions, Byte[] extraRentedBytes)
   at System.Text.Json.JsonDocument.Parse(ReadOnlyMemory`1 json, JsonDocumentOptions options)
   at System.Text.Json.JsonDocument.Parse(String json, JsonDocumentOptions options)
   at Anonymized..ctor(String json) in Anonymized.cs:line 182
   at Anonymized.<>c__DisplayClass12_0.<TestCreateLogEntryFromJson_IllegalValues>b__0() in Anonymized.cs:line 206
   at NUnit.Framework.Assert.Throws(IResolveConstraint expression, TestDelegate code, String message, Object[] args)

更新 #2: 我去看看是否会有一些我错过的nugets。我发现 System.Text.Json 是一个 nuget(虽然它已经可以访问,但我在测试文件中成功使用了 System.Text.JsonSerializer)。我添加了它,现在我遇到了实际问题:由于它的保护级别,它无法访问。

using System.Text.Json;

namespace System.Text.Json

    internal sealed class JsonReaderException : JsonException
    
        public JsonReaderException(string message, long lineNumber, long bytePositionInLine);
    

但这并不能直接解决,我如何在 Assert.Throws&lt;System.Text.Json.JsonReaderException&gt; 中捕捉到这个?

【问题讨论】:

你能提供堆栈跟踪和 json 示例吗?您是否删除了与 Newtonsoft.Json 相关的所有内容? 您确定JsonReaderException 在命名空间System.Text.Json 下吗?我猜它应该在Newtonsoft.Json 命名空间下,请参考这个LINK。 JsonReaderExceptionNewtonsoft.Json 特定的例外。正如@PavelAnikhouski 提到的那样,您一定仍然对它有一些依赖。 @PavelAnikhouski 在堆栈跟踪之后您是否仍然认为它可能与 Newtonsoft 有关?无效 json 的示例是空字符串。 【参考方案1】:

System.Text.Json.JsonReaderException当前为internal这一事实表明微软可能随时修改或删除该类型,System.Text.Json的用户不应依赖该类的继续存在作为公共JsonException 的子类。事实上,documentation for Utf8JsonReader 仅声明

Utf8JsonReader 遇到无效的 JSON 时,它会抛出一个 JsonException,其中包含行号和行上字节位置等基本错误信息。

JsonReaderException 状态的代码 cmets:

// This class exists because the serializer needs to catch reader-originated exceptions in order to throw JsonException which has Path information.

改为,使用Is.InstanceOf&lt;JsonException&gt;()断言抛出的异常是JsonException

Assert.Throws(Is.InstanceOf<JsonException>(), () => JsonDocument.Parse(json).Dispose());

如果出于某种原因您必须断言所抛出的特定异常类型,您可以利用Assert.Throws() 返回抛出的异常这一事实来检查异常的完整类型名称:

Assert.AreEqual("System.Text.Json.JsonReaderException",
                Assert.Throws(Is.InstanceOf<JsonException>(), () => JsonDocument.Parse(json).Dispose()).GetType().FullName);

或者您可以使用 NUnit 的 custom constraint mechanism 并引入 FullTypeNameConstraint,如下所示:

using NUnit.Framework;
using NUnit.Framework.Constraints;

public class FullTypeNameConstraint : Constraint

    readonly string expectedFullTypeName;

    public FullTypeNameConstraint(string expectedFullTypeName) : base(expectedFullTypeName) => this.expectedFullTypeName = expectedFullTypeName;

    public override string DisplayName => "FullTypeNameOf";

    public override ConstraintResult ApplyTo<TActual>(TActual actual)
    
        var actualTypeName = actual?.GetType().FullName;
        return new ConstraintResult(this, actualTypeName, actualTypeName == expectedFullTypeName);
    


public class Is : NUnit.Framework.Is

    public static FullTypeNameConstraint FullTypeNameOf(string expectedFullTypeName) => new FullTypeNameConstraint(expectedFullTypeName);
   

public static class CustomConstraintExtensions

    public static FullTypeNameConstraint FullTypeNameOf(this ConstraintExpression expression, string expectedFullTypeName)
    
        var constraint = new FullTypeNameConstraint(expectedFullTypeName);
        expression.Append(constraint);
        return constraint;
    
    

然后你就可以做到:

Assert.Throws(Is.FullTypeNameOf("System.Text.Json.JsonReaderException"), () => JsonDocument.Parse(json).Dispose());

但老实说,我不会推荐它。

顺便说一句,JsonDocument 是一次性的,实际上需要进行处理以释放池内存以供重用。

这里是演示小提琴:https://dotnetfiddle.net/0dLxeO。

【讨论】:

谢谢!很好的答案!【参考方案2】:

对于 xUnit,可以使用 Assert.ThrowsAny&lt;JsonException&gt;(action)

【讨论】:

【参考方案3】:

您可以将Newtonsoft.Json.dll 添加到您的项目引用中,这将解决您的问题。

【讨论】:

以上是关于在命名空间中找不到 System.Text.Json.JsonReaderException的主要内容,如果未能解决你的问题,请参考以下文章

在命名空间/头文件中找不到类

链接器在命名空间中找不到函数定义

在 mapActions() 中找不到 vuex 模块命名空间:taskModule/?

在命名空间中找不到 System.Text.Json.JsonReaderException

更改命名空间时在 Laravel 中找不到类“\App\User”

MVC项目中找不到DbContext命名空间