Skip to content

Json serialization on RegisteredFunction.Invoke includes members with null value #16144

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
MihaMarkic opened this issue Apr 24, 2018 · 10 comments
Labels
area-blazor Includes: Blazor, Razor Components

Comments

@MihaMarkic
Copy link
Contributor

If I'm not mistaken, I think that serializer includes members having a null value, so if I have a type

class Tubo {
  public string Text { get; set; }
}

and I serialize new Tubo(), I'd get
{ Text: null }
instead of
{}
This is a problem when you don't want to pass properties around.

@MihaMarkic MihaMarkic changed the title Json serialization on RegisteredFunction.Invoke includes member with null value Json serialization on RegisteredFunction.Invoke includes members with null value Apr 24, 2018
@Daddoon
Copy link

Daddoon commented Apr 24, 2018

But then, if any library/component (Javascript/TypeScript) rely on the property existence if doing Interop, removing the property because it is null will return a undefined property, no ?

I think JsonUtil mimick C# consistency about objects. Maybe an overload on Serialize would be a solution for this kind of scenario you are having, totally valid when calling a web api or something like that.

@MihaMarkic
Copy link
Contributor Author

Yes, it's a tricky one. But the usual behavior in web world is to ignore the null properties if I'm not mistaken. Having an option somewhere would be the best way to solve it.

@SteveSandersonMS
Copy link
Member

We're trying to keep JsonUtil as simple as we can, so having opinionated rules about stripping out properties is out of scope. I'd recommend using a different JSON library if you want to control that sort of thing. Hope that's OK.

@MihaMarkic
Copy link
Contributor Author

@SteveSandersonMS Is there a way to substitute the json serialization easily? Possibly per method call.

@Daddoon
Copy link

Daddoon commented Apr 25, 2018

Actually, JsonUtil juste use SimpleJson library.

You may try to call SimpleJson directly from your code, and seeing if it fulfill your requirement in any of his option. Or use Newtonsoft Json.Net if you are able (but maybe overkill).

But SimpleJson seem to be present, as seeing from the JsonUtil source code.

@MihaMarkic
Copy link
Contributor Author

@Daddoon Yes, I know that. But I'd be nice to just switch the serialization provider instead of manually doing it.

@zbecknell
Copy link
Contributor

Could we introduce an interface IJsonUtil and start utilizing that via dependency injection rather than as a static class? That way you could swap out the implementation from SimpleJsonUtil to anything else (your own JsonNetUtil for instance).

@MihaMarkic
Copy link
Contributor Author

@zbecknell Yep.

@SteveSandersonMS
Copy link
Member

SteveSandersonMS commented Apr 26, 2018

Any design we come up with has to work correctly when composing together multiple third-party packages. So we can't have JsonUtil vary its behavior based on your DI config, because then third-party packages that assume certain serialization conventions when making their own JS interop calls would break if you changed it.

Proposal: we could add an extra overload to RegisteredFunction.Invoke as follows:

public static TRes Invoke<TRes>(string identifier, string argsArrayJson)

This will allow you to do your own JSON serialization using whatever library or conventions you want and have it passed through JS interop in the same way. To make usage simpler, you can easily write your own static utility method like:

public static TRes MyAppInvoke<TRes>(string identifier, params object[] args)
{
    var argsJson = DoMyCustomJsonSerialization(args);
    return RegisteredFunction.Invoke<TRes>(identifier, argsJson);
}

Would that cover your requirements?

@MihaMarkic
Copy link
Contributor Author

@SteveSandersonMS You are right on DI - that wouldn't be good.
Yes, it has to be per method.
Another option would be:
public static TRes Invoke<TRes>(IJsonUtil converter, string identifier, params object[] args)
where one would pass its own implemention.

Perhaps both options could be added.

@mkArtakMSFT mkArtakMSFT transferred this issue from dotnet/blazor Oct 27, 2019
@mkArtakMSFT mkArtakMSFT added the area-blazor Includes: Blazor, Razor Components label Oct 27, 2019
@ghost ghost locked as resolved and limited conversation to collaborators Dec 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
area-blazor Includes: Blazor, Razor Components
Projects
None yet
Development

No branches or pull requests

5 participants