Ajout d'un JsonConvertorFactory à une application d'assemblage Web Blazor

Sep 14 2020

Nouveau sur Blazor, nouveau sur Web Assembly, nouveau sur .NET Core, pas nouveau sur .NET (depuis 1.0).

Je fais mes premiers pas dans l'apprentissage de Blazor - je suis principalement un développeur back-end et winforms, pas côté client.

Pour mon projet, je construis un client Blazor Web Assembly qui accède à certaines fonctionnalités existantes que j'ai déployées via Azure Functions 3. J'aimerais partager des POCO entre l'application frontale et principale.

Je rencontre des «incompatibilités d'impédance» entre l'application Blazor et l'application Azure functions. Les deux applications (Blazor et Functions) sont des applications de base «prêtes à l'emploi», configurées de la manière dont les nouveaux modèles de projet dans VS2019 les ont créées.

  • L'application Azure Functions cible «netcoreapp3.1» tandis que l'application côté client Blazor cible «netstandard2.1»
  • Azure Functions utilise Newtonsoft.Jsontandis que Blazor utiliseSystem.Text.Json

Afin de partager les définitions d'objets, j'ai changé la bibliothèque de classes contenant mes POCO en netstandard2.1 et cela semble être OK. Était-ce la bonne solution?

Le problème que je n'ai pas pu résoudre est le suivant: un objet qui contient une enumpropriété est renvoyé par l'application Azure Functions. La désérialisation de cet objet échoue dans l'application Blazor lorsqu'une valeur d'énumération est rencontrée dans le texte JSON.

Comment puis-je System.Text.Jsondésérialiser les enumpropriétés?

J'ai vu des exemples sur la façon d'ajouter un JsonConvertorFactoryà ASP.NET Core, mais on ne sait pas comment ou si ces exemples s'appliquent à l'intérieur de l'application Blazor. Par exemple, ici .

Sur le Newtsoft.Jsoncôté, les POCO sont décorés de l' Newtonsoft.Json.JsonConvertorattribut. J'ai essayé d'ajouter l' System.Text.Jsonattribut de convertisseur correspondant , mais cette classe n'a pas été trouvée - System.Text.Jsonne fait pas partie de netstandard2.1?

Réponses

2 HenkHolterman Sep 14 2020 at 03:53

J'ai changé la bibliothèque de classes contenant mes POCO en netstandard2.1 et cela semble être OK. Était-ce la bonne solution?

Oui c'est bien.

Et je sais que vous pouvez ajouter NewtonSoft à une application Blazor, cela ajoute juste un peu à la taille.

Et de l'autre côté, je ne suis pas sûr qu'Azure Functions soit si étroitement lié à NewtonSoft, ne travaillez-vous pas simplement avec HttpRequest et HttpResponse? Cela devrait également fonctionner avec System.Text.Json.

Vous devriez donc pouvoir utiliser la même bibliothèque Json des deux côtés.

System.Text.Json ne fait-il pas partie de netstandard2.1?

Ne fait pas partie de mais il est «pris en charge sur». Vous pouvez résoudre ce problème (si nécessaire) en ajoutant le bon package à votre projet.

CarlDaniel Sep 14 2020 at 11:29

Tout d'abord, autant que je sache, il n'y a pas de place centrale pour définir les options de sérialisation Json dans Blazor WebAssembly - mieux que je sache, vous devez définir des options partout où la sérialisation / désérialisation est utilisée - j'espère que quelqu'un pourra me désabuser de cette notion s'il y a quelque chose que j'ai manqué (je suppose qu'il existe une instance par défaut d' JsonSerializerOptionsoptions quelque part, mais je ne l'ai pas trouvée).

Voici la solution de base:

          var jso = new System.Text.Json.JsonSerializerOptions()
          {
              PropertyNameCaseInsensitive = true
          };
          jso.Converters.Add(new System.Text.Json.Serialization.JsonStringEnumConverter());

          var sc = await Http.GetFromJsonAsync<YourResultType>(yourUrl, jso);

Cela obtient les enumvaleurs correctement analysées.

Vous rencontrez un nouveau problème maintenant. Je pensais que c'était des valeurs nulles pour les Nullabletypes de valeur (par exemple double?), mais je me suis trompé - c'est la valeur NaN - Newstonsoft.Jsoncomprend apparemment cette valeur alors que ce System.Text.Jsonn'est pas le cas. Je vais considérer qu'il s'agit d'un bogue dans ma source de données et le corriger pour ne jamais retourner NaN (c'est pourquoi la propriété est après tout double?).

MISE À JOUR En regardant le code source, HttpClientJsonExtensions.GetFromJsonAsyncil est clair qu'aucune valeur par défaut globale ne peut être définie. La solution ci-dessus consistant à passer un JsonSerializerOptionsà chaque appel GetFromJsonAsyncsemble être la bonne solution pour le moment.