Hinzufügen einer JsonConvertorFactory zu einer Blazor Web Assembly-App

Sep 14 2020

Neu in Blazor, neu in Web Assembly, neu in .NET Core, nicht neu in .NET (seit 1.0).

Ich mache einige erste Schritte, um Blazor zu lernen - ich bin meistens ein Back-End- und Winforms-Entwickler, nicht clientseitig.

Für mein Projekt erstelle ich einen Blazor Web Assembly-Client, der auf einige vorhandene Funktionen zugreift, die ich über Azure Functions 3 bereitgestellt habe. Ich möchte einige POCOs zwischen der Front-End- und der Back-End-App freigeben.

Ich stoße auf "Impedanzfehlanpassungen" zwischen der Blazor-App und der Azure-Funktions-App. Beide Apps (Blazor und Funktionen) sind einfache "Out-of-the-Box" -Anwendungen, die so konfiguriert wurden, wie sie von den neuen Projektvorlagen in VS2019 erstellt wurden.

  • Die App für Azure-Funktionen zielt auf "netcoreapp3.1" ab, während die clientseitige Blazor-App auf "netstandard2.1" abzielt.
  • Azure-Funktionen werden verwendet, Newtonsoft.Jsonwährend Blazor verwendetSystem.Text.Json

Um Objektdefinitionen gemeinsam zu nutzen, habe ich die Klassenbibliothek mit meinen POCOs in netstandard2.1 geändert, und das scheint in Ordnung zu sein. War das die richtige Lösung?

Das Problem, das ich nicht lösen konnte, ist Folgendes: Ein Objekt, das eine enumEigenschaft enthält, wird von der Azure Functions-App zurückgegeben. Die Deserialisierung dieses Objekts schlägt in der Blazor-App fehl, wenn im JSON-Text ein Aufzählungswert gefunden wird.

Wie kann ich Eigenschaften System.Text.Jsondeserialisieren enum?

Ich habe Beispiele zum Hinzufügen eines JsonConvertorFactoryzu ASP.NET Core gesehen, aber es ist nicht klar, wie oder ob diese Beispiele in der Blazor-App gelten. Zum Beispiel hier .

Auf der Newtsoft.JsonSeite werden die POCOs verziert mit dem Newtonsoft.Json.JsonConvertorAttribut. Ich habe versucht, das entsprechende System.Text.JsonKonverterattribut hinzuzufügen , aber diese Klasse wurde nicht gefunden - ist sie System.Text.Jsonnicht Teil von netstandard2.1?

Antworten

2 HenkHolterman Sep 14 2020 at 03:53

Ich habe die Klassenbibliothek mit meinen POCOs in netstandard2.1 geändert und das scheint in Ordnung zu sein. War das die richtige Lösung?

Ja, das ist in Ordnung.

Und ich weiß, dass Sie NewtonSoft zu einer Blazor-App hinzufügen können, es erhöht nur ein wenig die Größe.

Andererseits bin ich mir nicht sicher, ob Azure-Funktionen so stark an NewtonSoft gebunden sind. Arbeiten Sie nicht einfach mit HttpRequest und HttpResponse? Das sollte auch mit System.Text.Json funktionieren.

Sie sollten also auf beiden Seiten dieselbe Json-Bibliothek verwenden können.

Ist System.Text.Json nicht Teil von netstandard2.1?

Nicht 'Teil von', aber es wird 'unterstützt von'. Sie können dies beheben (falls noch erforderlich), indem Sie Ihrem Projekt das richtige Paket hinzufügen.

CarlDaniel Sep 14 2020 at 11:29

Erstens gibt es, soweit ich das beurteilen kann, keinen zentralen Ort, an dem Json-Serialisierungsoptionen in Blazor WebAssembly festgelegt werden können. Ich kann nur sagen, dass Sie überall dort Optionen festlegen müssen, wo Serialisierung / Deserialisierung verwendet wird. Hoffentlich kann mich jemand von dieser Vorstellung abbringen, wenn es etwas gibt das habe ich verpasst (ich gehe davon aus, dass es JsonSerializerOptionsirgendwo eine Standardinstanz von Optionen gibt, aber ich habe sie nicht gefunden).

Hier ist die grundlegende Lösung:

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

Dadurch werden die enumWerte korrekt analysiert.

Jetzt stößt ich auf ein neues Problem. Ich dachte, es wären Nullwerte für NullableWerttypen (z. B. double?), aber ich habe mich geirrt - es ist der NaN-Wert - anscheinend Newstonsoft.Jsonversteht er diesen Wert, während System.Text.Jsondies nicht der Fall ist. Ich werde diesen Fehler in meiner Datenquelle in Betracht ziehen und ihn beheben, um niemals NaN zurückzugeben (deshalb ist die Eigenschaft double?immerhin).

UPDATE Wenn Sie sich den Quellcode ansehen HttpClientJsonExtensions.GetFromJsonAsync, ist klar, dass kein globaler Standard festgelegt werden kann. Die obige Lösung, bei JsonSerializerOptionsjedem Anruf an einen zu übergeben, GetFromJsonAsyncscheint zu diesem Zeitpunkt die richtige Lösung zu sein.