LostBeard / SpawnDev.BlazorJS

Full Blazor WebAssembly and Javascript interop. Supports all Javascript data types and web browser APIs.
https://blazorjs.spawndev.com
MIT License
111 stars 7 forks source link

[Feature request] Add possibility to configure System.Text.Json #6

Closed Martin521 closed 1 year ago

Martin521 commented 1 year ago

My simple F# demo project is working, but I get stuck if I use F# types that are not supported out of the box by System.Text.Json. I would need to add a custom F# converter such as Fsharp.SystemTextJson.

Would you consider adding a way to do that?

E.g. just making the getter of RuntimeJsonSerializerOptions public; or add a service AddJsonOptions like the MVC controllers do (see here and here).

LostBeard commented 1 year ago

Is this issue specific to using BlazorJS and/or WebWorkers, or is it more a Blazor WASM issue? I ask because my library may not be the best place to implement that feature. This seems like something F# Bolero WASM needs even without my libs.

As you may know, the value of the property "BlazorJSRuntime.RuntimeJsonSerializerOptions" does not belong to my code. My code uses reflection to obtain the "JsonSerializerOptions" property from "Microsoft.JSInterop.JSRuntime". Microsoft has intentionally blocked access to it and modifying it can cause issues. That said...

I understand why you want access to it, but it may be better asking the DotNet team to add that ability to Blazor WASM. I would +1 that request. I will admit, it may take them a long time to implement it but it does seem important for F# Bolero WASM so they may fast track it.

Not sure if you are also aware that you can use F# types with your custom converters without modifying the JSRuntime serializer options. (I feel like you probably know this.)

Dealing with JSON | Bolero: F# in WebAssembly

open System.Text.Json
open System.Text.Json.Serialization

[<JsonFSharpConverter>]
type Example = { x: string }
JsonSerializer.Serialize({x = "Bolero" })

I am not against implementing this. Just wanted to add this ^ first.

LostBeard commented 1 year ago

All set. The repo and Nugets have been updated (version 2.1.13). I added the extension method "AddJSRuntimeJsonOptions" to IServiceCollection. Below is a modified "Startup.fs" from your Demo app. Hope this helps.

open Microsoft.AspNetCore.Components.WebAssembly.Hosting
open Microsoft.Extensions.DependencyInjection
open ComputeService
open SpawnDev.BlazorJS
open SpawnDev.BlazorJS.WebWorkers
open System.Text.Json.Serialization

module Program =

    [<EntryPoint>]
    let Main args =
        let builder = WebAssemblyHostBuilder.CreateDefault(args)
        builder.RootComponents.Add<Main.MyApp>("#main")

        builder.Services
            .AddJSRuntimeJsonOptions(fun o -> o.Converters.Add(JsonFSharpConverter()))
            .AddBlazorJSRuntime()
            .AddWebWorkerService() 
            .AddSingleton<IMyComputeService, MyComputeService>()
        |> ignore

        builder.Build().BlazorJSRunAsync() |> ignore
        0

I noticed you had both "SpawnDev.BlazorJS" and "SpawnDev.BlazorJS.WebWorkers" Nugets as dependencies in your Demo project. You do not need to have "SpawnDev.BlazorJS" when you are using "SpawnDev.BlazorJS.WebWorkers" because it will be automatically included as a dependency of WebWorkers. Makes versioning/updating easier. (Just my opinion.)

Martin521 commented 1 year ago

Perfect. Thanks!!