Skip to content
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

Epic: Support System.Text.Json #2243

Open
1 task
RicoSuter opened this issue Jun 15, 2019 · 72 comments
Open
1 task

Epic: Support System.Text.Json #2243

RicoSuter opened this issue Jun 15, 2019 · 72 comments

Comments

@RicoSuter
Copy link
Owner

RicoSuter commented Jun 15, 2019

A: Use System.Text.Json in generated C# models (DTOs):

B: Use System.Text.Json in JSON Schema generator (also used to generate OpenAPI model schemas):

Out of scope:

  • Use System.Text.Json to serialize schemas, documents, etc.

Tasks:

  • Document new property SerializerOptions
@JoFrMueller
Copy link

We're currently moving internal libraries towards System.Text.Json and wonder what the plans for NSwag are regarding migration?

Dazinator makes 2316 sound like you would loose interoperability by not being able to use data contracts anymore. Could you perhaps comment on this and your planned schedule regarding System.Text.Json? Thanks a lot!

@RicoSuter
Copy link
Owner Author

RicoSuter commented Dec 12, 2019

Do you need A or B?

@JoFrMueller
Copy link

JoFrMueller commented Dec 13, 2019

We don't care about data contracts currently. So:

  • A: System.Text.Json <-- Waiting impatiently.
  • B: DataContract <-- More interesting from an academic/wider point of view...

@skorunka
Copy link

Hello, how does it look with A?

@RicoSuter
Copy link
Owner Author

No work done yet, but A is the one which is feasible to implement already. B is not possible because no metadata is exposed.

@8VAid8
Copy link

8VAid8 commented Mar 31, 2020

@RicoSuter Do you have any progress with A? I've checked a client behavior with replaced Newtonsoft by System.Text.Json. It works.

@stefanluchian
Copy link

stefanluchian commented Apr 7, 2020

I can hardly wait to use the asynchronous deserialization (DeserializeAsync) from System.Text.Json.
It would be very handy to be able to choose between Newtonsoft and System.Text.Json for the generation of C# client.

@Jacko1394
Copy link

I'd also love to see optional support for System.Text.Json :D

@dubtar
Copy link

dubtar commented May 7, 2020

While this is in progress, is there a workaround to serialize enums as string? In my .net core 3.1 project with nswag.aspnetcore 13.4.2 it does not recognize services.AddJsonOptions(c=>c.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()))) and adding services.AddOpenApiDocument(c => c.DefaultEnumHandling = NJsonSchema.Generation.EnumHandling.String); break data class fields casing: id becomes Id.

@jnovick
Copy link

jnovick commented May 7, 2020

Any update on this?

@8VAid8
Copy link

8VAid8 commented May 8, 2020

I didn't want to wait and just made a simple Newtonsoft -> System.Text.Json converter (it has planty bugs, i guess, but works for me) for my Blazor project. @Jacko1394 you can try this way while the feature implementation is in progress.

@RicoSuter
Copy link
Owner Author

RicoSuter commented May 8, 2020

@8VAid8 Thanks for sharing your solution - we should support that out-of-the-box as a "generator template style", this is tracked mainly here:

RicoSuter/NJsonSchema#1013

@RicoSuter
Copy link
Owner Author

@dubtar @jnovick System.Text.Json support in the schema generator has been greatly improved, see RicoSuter/NJsonSchema#1014 (NSwag v13.5.0)

@dubtar
Copy link

dubtar commented May 12, 2020

Yep, thanks a ton! 13.5.0 resolved my issues - now typescript clients work for me with enums as string.

@electricessence
Copy link

You could simply inject the serializer agnostically:
https://www.nuget.org/packages/Open.Serialization.Json/

@SommerEngineering
Copy link

Thanks alot @RicoSuter 🙂 It works now out-of-the-box within my blazor wasm client.

@loganmarshall1
Copy link

Thanks alot @RicoSuter 🙂 It works now out-of-the-box within my blazor wasm client.

Hi there my friend! was wonder if you'd please share your steps to generate a c# open api NSwag client for blazor wasm? My understanding this that Newtonsoft.Json isn't supported on blazor wasm, would love to get your guidance on what worked best for you in your success story.

Thanks for you time, please let me know 👍

@loganmarshall1
Copy link

Hi @RicoSuter

Hope you're having a good day.

I appreciate all the help all your tools and code do with the community. I've used nswag studio on 6 of my projects over the past several years and they do make life better and easier. 👍

Wondering if System.Text.Json will be supported this year? I'm currently hand writing the c# client because blazor wasm doesn't support Newtonsoft. I'm on the fence right now of switching to GRPC for API Layer, with one of the many reasons being the client generation works with blazor wasm. https://blog.stevensanderson.com/2020/01/15/2020-01-15-grpc-web-in-blazor-webassembly/

Please let me know, thanks again!

@jeremyVignelles
Copy link
Collaborator

Implementing STJ has a lot of implications for NSwag and for the generated code (things that don't deserialize the same way...). Given the task of implementing that in NJsonSchema and NSwag, and checking that nothing breaks, I wouldn't be surprised if it took some time to be implemented.

On my side, I'm planning to create a new C# code generator built for the modern C#, and see how things goes. This would be a separate project.

@Jacko1394
Copy link

Is Newtonsoft not supported on Blazor Wasm? Because it's worked fine in my project.
I used this NSwag C# client generator to build a typed client (referencing Newtonsoft) and it worked in my blazorwasm app for months no issues.

The desire for System.Text.Json support was more one of preference; it's Microsoft supported and more performant, also with a much smaller dll than Newtonsoft, which is important for web load times.

I've since migrated my project to use gRPC as others have suggested and I would strongly recommend this myself.
gRPC has smaller payloads (binary) and also de/serializes faster as well.

Marc Gravell has fantastic gRPC libraries that allow for code-first C# approach to gRPC, there's no need to even understand .proto file definitions.

@loganmarshall1
Copy link

loganmarshall1 commented Jan 5, 2021 via email

@thebynggroup
Copy link

Hi Everyone, Does anyone know if there's a open api c# client generator that has no Newtonsoft dependancy? meaning it uses System.Text.Json?

@RicoSuter
Copy link
Owner Author

the default JsonSerializerOptions are very strict and won't work in all cases

Because the openapi spec clearly defines how json is serialized/deserialized ideally you should not even be able to change it as it would mean the code gen is buggy - but i know that there are sometimes changes needed, eg if even the spec is wrong

@crobibero
Copy link

I 100% agree- but Newtonsoft.Json was very flexible and not everything that it supported is currently / will be supported with System.Text.Json. One big example is displaying enums. In order to return them as a string instead of their int representation we need to add the JsonStringEnumConverter to the converters list

@RicoSuter
Copy link
Owner Author

In order to return them as a string instead of their int representation we need to add the JsonStringEnumConverter to the converters list

this is already automatically generated - as the spec would not comply with the spec otherwise

@crobibero
Copy link

Sorry, I forgot how we generate the client. Now that I've looked again I can see that all I had to do was add the converts to the nswag.json. If we could keep that option the converter will work great for my use.

Specifically- we need to send Guids without dashes for legacy purposes, but System.Text.Json only supports the "proper" Guid format.

@aureole82
Copy link

Could somebody tell me what's the progress of DateTime/DateTimeOffset within generated models like this:

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "10.4.4.0 (Newtonsoft.Json v11.0.0.0)")]
public partial class ContactRequest 
{
    /// <summary>Date of birth of the contact person, e.g. "1999-12-31".</summary>
    [System.Text.Json.Serialization.JsonPropertyName("birthday")]
    [System.ComponentModel.DataAnnotations.Required(AllowEmptyStrings = true)]
    [System.Text.Json.Serialization.JsonConverter(typeof(DateFormatConverter))]
    public System.DateTimeOffset Birthday { get; set; }
...
}

[System.CodeDom.Compiler.GeneratedCode("NJsonSchema", "13.11.2.0 (NJsonSchema v10.4.4.0 (Newtonsoft.Json v11.0.0.0))")]
internal class DateFormatConverter : Newtonsoft.Json.Converters.IsoDateTimeConverter
{
    public DateFormatConverter()
    {
        DateTimeFormat = "yyyy-MM-dd";
    }
}

@gregsdennis
Copy link

gregsdennis commented Sep 2, 2021

@RicoSuter, I realize that you have NJsonSchema, and that it's currently being updated, but I'd like to offer my library JsonSchema.Net (Nuget | Github | Docs) as a replacement JSON Schema provider.

It was built ground-up on top of System.Text.Json and it has fully supported draft 2020-12 (the latest) since the spec was released, including the $dynamicRef / $dynamicAnchor keywords as well as vocabularies. (Being part of the JSON Schema team gives me a jump on updating my library.) If you'd like, you can test it at https://json-everything.net/.

Using my library provides other benefits as well:

  • My focus being on JSON Schema means that you could concentrate your efforts on the OpenAPI/Swagger needs.
  • My users could easily use NSwag, and your users get the latest validation logic as well as System.Test.Json support.
  • Draft 2020-12 was developed in close cooperation with the OpenAPI spec maintainers for v3.1. Using my validator will make updating this library easier.

(I wish I had found this issue sooner, but I thought I'd open the discussion anyway.)

@loganmarshall1
Copy link

Hi Everyone! I would love to ONLY use System.Text.Json instead of newtonsoft on my blazor wasm standalone pwa apps.

The only reason I have to have newtonsoft as a nuget dependacy is because I love NSwag studio api client generator so much! 

would love to get this pushed out by end of year! please let me know if I can help with any pull requests?! 🙏❤️

@loganmarshall1
Copy link

Hi @RicoSuter looking very forward to this update and your support!

@RicoSuter
Copy link
Owner Author

but I'd like to offer my library JsonSchema.Net (Nuget | Github | Docs) as a replacement JSON Schema provider.

That's not really an option as it would essentially be a rewrite - NSwag and NJsonSchema are more or less one project...

Hi Everyone! I would love to ONLY use System.Text.Json instead of newtonsoft on my blazor wasm standalone pwa apps.

Why are you referencing NSwag in the wasm frontend app? NSwag is usually only needed in the backend to generate the spec, in the frontend you consume the generated client code which has no direct dependency on NSwag/NJS/Newtonsoft.

NSwag/NJsonSchema supports System.Text.Json, it just uses Newtonsoft to serialize/deserialize schemas... this is more or less an "implementation detail" that's why this was not high on the prio list (ie you only have the "bad" dependency).

It would be nice to migrate to STJ but this is quite some work.

@Trapulo
Copy link

Trapulo commented Oct 26, 2021

It is required if you may fix some troubles with some kind of serialize/deserialize using converters. Eg. polymorphism or special types as IPAddress.

@RicoSuter
Copy link
Owner Author

Polymorphism should also be supported when using STJ output, no?

I'd say IPAddress is not supported by JSON Schema and you should just use type "string" for that...

@loganmarshall1
Copy link

but I'd like to offer my library JsonSchema.Net (Nuget | Github | Docs) as a replacement JSON Schema provider.

That's not really an option as it would essentially be a rewrite - NSwag and NJsonSchema are more or less one project...

Hi Everyone! I would love to ONLY use System.Text.Json instead of newtonsoft on my blazor wasm standalone pwa apps.

Why are you referencing NSwag in the wasm frontend app? NSwag is usually only needed in the backend to generate the spec, in the frontend you consume the generated client code which has no direct dependency on NSwag/NJS/Newtonsoft.

NSwag/NJsonSchema supports System.Text.Json, it just uses Newtonsoft to serialize/deserialize schemas... this is more or less an "implementation detail" that's why this was not high on the prio list (ie you only have the "bad" dependency).

It would be nice to migrate to STJ but this is quite some work.

Hi Rico,

I'm using NSwag to generate an api client that the front end consumes In order to call the api.

Please Let me know if that make sense for the answer to your question.

@loganmarshall1
Copy link

but I'd like to offer my library JsonSchema.Net (Nuget | Github | Docs) as a replacement JSON Schema provider.

That's not really an option as it would essentially be a rewrite - NSwag and NJsonSchema are more or less one project...

Hi Everyone! I would love to ONLY use System.Text.Json instead of newtonsoft on my blazor wasm standalone pwa apps.

Why are you referencing NSwag in the wasm frontend app? NSwag is usually only needed in the backend to generate the spec, in the frontend you consume the generated client code which has no direct dependency on NSwag/NJS/Newtonsoft.

NSwag/NJsonSchema supports System.Text.Json, it just uses Newtonsoft to serialize/deserialize schemas... this is more or less an "implementation detail" that's why this was not high on the prio list (ie you only have the "bad" dependency).

It would be nice to migrate to STJ but this is quite some work.

Hi Rico,

The front end generated client has a dependency on newtonsoft json.

can you please confirm if there's an option to not use this on the generated C# client?

@RicoSuter
Copy link
Owner Author

image

?

@loganmarshall1
Copy link

image

?

Perfect thanks. I'll give it a shot!

I knew about we had Support to generate DTO's with STJ. I haven't seen this other option yet.

It's almost like when the Nswag program opens after a version update it should provide a pop up of what's new. Love this.

This is great is this new did it come out recently?

@smokedlinq
Copy link

It looks like NJsonSchema is using the right kind of template to generate this converter but it doesn't appear the nswag library is using this version, or maybe there is a bug in NJsonSchema with this template ...

https://github.com/RicoSuter/NJsonSchema/blob/master/src/NJsonSchema.CodeGeneration.CSharp/Templates/DateFormatConverter.liquid

@AHelper
Copy link

AHelper commented Nov 13, 2021

I'm seeing the same thing for JsonInheritanceConverter. The Newtonsoft version is being emitted, not the System.Text.Json one. The rest of the file uses the correct types.

@loganmarshall1
Copy link

image

?

Thanks @RicoSuter This works perfectly when you select the generate DTO option. However in my case the DTO and are in a shared class library that both my front end and api projects reference therefore I can’t use this option. Thanks!

@DominikPf
Copy link

DominikPf commented Nov 13, 2021

@loganmarshall1 You can enable the DTO option. Switch to System.Text.Json and then disable the DTO option again. This worked for us.

@RicoSuter The Json Library option should maybe be moved outside of the DTO options.

@loganmarshall1
Copy link

@loganmarshall1 You can enable the DTO option. Switch to System.Text.Json and then disable the DTO option again. This worked for us.

@RicoSuter The Json Library option should maybe be moved outside of the DTO options.

Wow perfect! Thank you so much!

@jochenjonc
Copy link
Contributor

I'm seeing the same thing for JsonInheritanceConverter. The Newtonsoft version is being emitted, not the System.Text.Json one. The rest of the file uses the correct types.

I have the same issue that the wrong JsonInheritanceConverter is injected in the generated contracts. Somehow this line results in false.
When I manually replace the Newtonsoft version of the JsonInheritanceConverter with the System.Text.Json version it works.

@n1l
Copy link

n1l commented Mar 25, 2022

Hi! What is the status of the epic? Is there anything I can help?

@ghost
Copy link

ghost commented May 13, 2022

Hey Guys!
This is still happening. I'm using the package NSwag.ApiDescription.Client v13.10.7.
Is there a newer version that fixes this problem?
image

Hi, @frosadev

I fixed it in #3338 Just need to release it.

I'm getting the inverse of this trying to use SystemTexstJson on the latest v13.15.10.

image

image

@JustinGrote
Copy link

JustinGrote commented Mar 9, 2023

It looks like #1052 is regressed in System.Text.Json. It doesn't respect Runtime.Serialization.EnumMember attribute

EDIT: Workaround here: dotnet/runtime#74385 (comment)

@ThaDaVos
Copy link

Any update on this? Currently working on a C# library which will be consumed by a Clarion Application and rather use System.Text.Json over NewtonSoft.Json due to it's size and improved performance

@yori-s
Copy link

yori-s commented Apr 28, 2023

@JustinGrote - ran into same STJ limitation on customizing enums as strings

It wasn't sufficient for me to provide a custom converter to a generated client's JsonSerializerSettings, but also had to remove the explicit converter annotation in generated enum properties:
https://github.com/RicoSuter/NJsonSchema/blob/94647c590b3c6cbc3d09569b027ee7cd77c20463/src/NJsonSchema.CodeGeneration.CSharp/Templates/Class.liquid#L83-L85

@PolarbearDK
Copy link

May I suggest a small fix in the generated code

You get compile errors when you consume a service that has a field called "System".

It will generate the following code:

[System.Text.Json.Serialization.JsonPropertyName("system")]
[System.Text.Json.Serialization.JsonIgnore(Condition = System.Text.Json.Serialization.JsonIgnoreCondition.Never)]   
public OpenMessageSystem System { get; set; }

And you get compile error:
CS0120: An object reference is required for the non-static field, method, or property 'CloseMessage.System'

It will work if you prefix System.Text Namespace with "global::":

[System.Text.Json.Serialization.JsonPropertyName("system")]
[System.Text.Json.Serialization.JsonIgnore(Condition = global::System.Text.Json.Serialization.JsonIgnoreCondition.Never)]   
public OpenMessageSystem System { get; set; }

I guess this you will get the same error with Newtonsoft.Json if you consume a service with a "Newtonsoft" property?

@albertocorrales
Copy link

This feature would be awesome since dotnet is doing a great job to improve the performance of System.Text.Json. Are there any ETAs about when System.Text.Json could be supported by NSwag?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests