1
votes

System.Text.Json.JsonReaderException est introuvable dans l'espace de noms

Je convertis un projet .NET Framework 4.5 en .NET Core 3.1. Mes tests utilisaient Newtonsoft.Json pour vérifier si json est valide et maintenant je voudrais implémenter la même chose avec le System.Text.Json intégré. Il semble que

using System.Text.Json;

namespace System.Text.Json
{
    internal sealed class JsonReaderException : JsonException
    {
        public JsonReaderException(string message, long lineNumber, long bytePositionInLine);
    }
}

jette System.Text.Json.JsonReaderException , mais je ne peux pas l'attraper car pointer vers cette exception entraîne une erreur

Le type ou le nom d'espace de noms 'JsonReaderException' n'existe pas dans l'espace de noms 'System.Text.Json' (vous manquez une référence d'assembly?)

Je voudrais simplement comprendre comment est-il possible que quelque chose qui ne semble pas réellement exister puisse être jeté.

Mise à jour n ° 1: Stacktrace:

   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)

Mise à jour n ° 2: Je suis allé voir s'il y aurait des pépites qui me manquaient. J'ai trouvé System.Text.Json en tant que nuget (bien qu'il soit déjà accessible, j'ai utilisé System.Text.JsonSerializer avec succès dans le fichier de test). Je l'ai ajouté et maintenant j'obtiens le problème réel: il est inaccessible en raison de son niveau de protection.

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

Cela ne résout cependant pas directement, comment puis-je attraper cela dans Assert.Throws<System.Text.Json.JsonReaderException> ?


4 commentaires

Pouvez-vous une trace de pile et un échantillon json? Avez-vous supprimé tout ce qui concerne Newtonsoft.Json ?


Êtes-vous sûr que JsonReaderException trouve sous l'espace de noms System.Text.Json ? Je suppose que cela devrait être sous l' Newtonsoft.Json noms Newtonsoft.Json , veuillez vous référer à ce LIEN .


JsonReaderException est une exception spécifique à Newtonsoft.Json . Vous devez toujours avoir des dépendances dessus, comme l'a mentionné @PavelAnikhouski.


@PavelAnikhouski Pensez-vous toujours que cela pourrait être lié à Newtonsoft après ce stacktrace? Un exemple de json invalide serait une chaîne vide.


3 Réponses :


-2
votes

Vous pouvez ajouter Newtonsoft.Json.dll à vos références de projet pour résoudre votre problème.


0 commentaires

2
votes

Le fait que System.Text.Json.JsonReaderException soit actuellement internal indique que Microsoft peut modifier ou supprimer ce type à tout moment, et les utilisateurs de System.Text.Json ne doivent pas dépendre de l'existence continue de cette classe en tant que sous-classe du public JsonException . En effet, la documentation d' Utf8JsonReader indique uniquement que

Lorsque Utf8JsonReader rencontre un JSON non valide, il lève une JsonException avec des informations d'erreur de base telles que le numéro de ligne et la position de l'octet sur la ligne.

Et les commentaires de code pour l'état JsonReaderException :

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

Au lieu de cela , affirmez que l'exception levée est une JsonException en utilisant Is.InstanceOf<JsonException>()

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;
    }
}    

Si, pour une raison quelconque, vous devez affirmer le type d'exception spécifique qui a été levé, vous pouvez vérifier le nom de type complet de l'exception en tirant parti du fait que Assert.Throws() renvoie l'exception levée:

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

Ou vous pouvez utiliser le mécanisme de contrainte personnalisé de NUnit et introduire une FullTypeNameConstraint comme suit:

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

Et puis vous pourrez faire:

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

Mais honnêtement, je ne le recommanderais pas.

En JsonDocument , JsonDocument est jetable et doit en fait être supprimé pour libérer de la mémoire en pool pour une réutilisation.

Démo violon ici: https://dotnetfiddle.net/0dLxeO .


1 commentaires

Merci! Très bonne réponse!



0
votes

Pour xUnit, on peut utiliser Assert.ThrowsAny<JsonException>(action)


0 commentaires