简体   繁体   中英

Adding a JsonConvertorFactory to a Blazor Web Assembly App

New to Blazor, new to Web Assembly, new to .NET Core, not new to .NET (since 1.0).

I'm taking some first steps into learning Blazor - I'm mostly a back-end and winforms dev, not client-side.

For my project, I'm building a Blazor Web Assembly client that accesses some existing functionality that I have deployed through Azure Functions 3. I'd like to share some POCOs between the front-end and back-end app.

I'm running into "impedance mismatches" between the Blazor app and the Azure functions app. Both apps (Blazor and Functions) are basic "out of the box" apps, configured the way the new project templates in VS2019 created them.

  • Azure functions app targets "netcoreapp3.1" while the Blazor client side app targets "netstandard2.1"
  • Azure Functions uses Newtonsoft.Json while Blazor uses System.Text.Json

In order to share object definitions, I changed the class library containing my POCOs to netstandard2.1 and that seems to be OK. Was this the correct solution?

The problem I haven't been able to overcome is this: an object that contains an enum property is returned from the Azure Functions app. Deserialization of this object fails in the Blazor app when an enum value is encountered in the JSON text.

How can I get System.Text.Json to deserialize enum properties?

I've seen examples of how to add a JsonConvertorFactory to ASP.NET Core, but it's not clear how or if those examples apply inside the Blazor app. For example, here .

On the Newtsoft.Json side, the POCOs are decorated with the Newtonsoft.Json.JsonConvertor attribute. I tried adding the corresponding System.Text.Json convertor attribute, but that class wasn't found - is System.Text.Json not part of netstandard2.1?

I changed the class library containing my POCOs to netstandard2.1 and that seems to be OK. Was this the correct solution?

Yes that is fine.

And I know you can add NewtonSoft to a Blazor app, it just adds a little to the size.

And on the other side, I'm not sure Azure Functions are tied to NewtonSoft so strongly, don't you just work with HttpRequest and HttpResponse? That ought to work with System.Text.Json as well.

So you should be able to use the same Json lib on both sides.

is System.Text.Json not part of netstandard2.1?

Not 'part of' but it is 'supported on'. You can resolve this (if still required) by adding the right package to your project.

First, near as I can tell, there's no central place to to set Json serialization options in Blazor WebAssembly - best I can tell, you need to set options everywhere serialization/deserialization is used - hopefully someone can disabuse me of that notion if there's something that I've missed (I'm assuming that there is a default instance of JsonSerializerOptions options somewhere, but I haven't found it).

Here's the basic solution:

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

That gets the enum values parsed correctly.

Running into a new problem now. I thought it was null values for Nullable value types (eg double? ), but I was wrong - it's the NaN value - apparently Newstonsoft.Json understands that value while System.Text.Json does not. I'm going to consider that a bug in my data source and fix it to never return NaN (that's why the property is double? afterall).

UPDATE Looking at the source code for HttpClientJsonExtensions.GetFromJsonAsync it's clear that there is no global default that can be set. The above solution of passing in a JsonSerializerOptions to every call to GetFromJsonAsync appears to be the correct solution at this time.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM