Customize serialization for IJSRuntime.InvokeAsync
See original GitHub issueBefore I write anything else… I have already created an issue a while ago with pretty much the same problem (which I will copy to here as well) but with a solution that didn’t really make sense. I now have a concrete idea/solution which is a lot better than what I suggested in my previous request.
Issue (similar to old issue)
Because IJSRuntime.InvokeAsync
now uses System.Text.Json
instead of Newtonsoft.Json
(preview6+) the custom serialization I implemented with Newtonsoft.Json
doesn’t work anymore. Specifically null
values aren’t ignored anymore.
Even though it says in the issue I linked…
Users may use a JSON serializer of their choice.
… the IJSRuntime
doesn’t use Newtonsoft.Json
if you add Newtonsoft.Json
in the ConfigureServices
method using AddNewtonsoftJson
on the IMvcBuilder
.
I have already made a comment in the discussion for this issue describing the issue and what I already tried (back then I didn’t know this wasn’t the default behaviour). In this comment I also link to my SO question where you can find further information on the attempts I’ve made (same as before, I assumed this wasn’t default behaviour).
These issues and questions might mention the need to be able to use Newtonsoft.Json
with IJSRuntime
. This is not anymore the case as I want to migrate all the custom serialization to System.Text.Json
anyway as soon as the API allows all the desired customizations I require.
Request / Idea
Now instead of allowing users to customize what serializer is used (replace System.Text.Json.JsonSerializer
), I only want to talk about the JsonSerializerOptions
(customize System.Text.Json.JsonSerializer
).
I have examined the source code for IJSRuntime
and the corresponding implementation(s). From that I have found out that the base class of all implementations (JSRuntimeBase
) uses the class JsonSerializerOptionsProvider
(see Line 67) which always holds the same JsonSerializerOptions
. This can’t be influenced by a user of the API.
Now how would you allow the user to customize those JsonSerializerOptions
?
It seems like it would be as easy adding another optional parameter to the InvokeAsync
methods of type JsonSerializerOptions
with a default value of null
. For documentation purposes it might be a good idea to make JsonSerializerOptionsProvider
public
instead of internal
so you could say something along the lines of:
if not provided <see cref="JsonSerializerOptionsProvider.DefaultOptions"> will be used.
This seems to already be quite detailed and is of course not up to me to decide, I just wanted to bring up the idea.
I realize that my old request was a bit too broad as well as probably too expensive to implement currently. This however seems much more lightweight and with a clear solution. I think it would be a great addition to this API as it can be a great advantage to be able to customize how the IJSRuntime
serializes your arguments.
The biggest advantage for me (and probably one of the biggest use cases overall) would be that I could set IgnoreNullValues
to true which is of course not the default value.
Issue Analytics
- State:
- Created 4 years ago
- Reactions:15
- Comments:59 (8 by maintainers)
some temporally solution
I wanted to give another shot at Blazor, and I encountered a similar issue when interfacing with a third-party JavaScript library. They were not handling null properties but were handling missing properties.
I would love to have access to the
JsonSerializerOptions
instance used by theJSRuntime
or an attribute that would allow me to decorate my types/properties, telling them to[IgnoreNullOrWhateverTheNameThatYouChoose]
.I spent a few hours digging into your code to find out that despite all of that focus on dependency injection, you decided to
new
theJsonSerializerOptions
in theJSRuntime
constructor and assigned it to an inaccessible property of that abstract class. That class have one or more concretions, but they are all internal, so inaccessible to us mortals (heuuuu… I meant simple application developers).Well, even if
WebAssemblyJSRuntime
was accessible, converting/casting theIJSRuntime
toJSRuntime
(or worst toWebAssemblyJSRuntime
) would not be a super-strong solution.WebAssemblyJSRuntime
issealed
so I could not inherit from it to update the options, which we should not have to do anyway; another not so strong/impossible solution…To fix my problem, I just sent untyped anonymous objects to JavaScript, but that’s not a solution for a real project (mine is a small experiment, so I don’t mind losing the types). It would have been so much easier to just be able to configure the
JsonSerializerOptions
and set theIgnoreNullValues
totrue
. It would also follow your own patterns about how to configure options, making it easier for everyone (i.e. being linear throughout the .Net Core ecosystem).That said, I think that you should focus on better interoperability with JavaScript. There are countless libraries already implemented, and it would be a shame not to be able to use them when needed. Yes, at some point, more and more Blazor libraries will appear, but I believe that it would help kickstart Blazor if we could just use JS stuff easily…
Keep up the good work on making .Net a better place!