RicoSuter / NSwag

The Swagger/OpenAPI toolchain for .NET, ASP.NET Core and TypeScript.
http://NSwag.org
MIT License
6.7k stars 1.24k forks source link

Epic: Support System.Text.Json #2243

Open RicoSuter opened 5 years ago

RicoSuter commented 5 years ago

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:

Tasks:

JoFrMueller commented 4 years ago

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 commented 4 years ago

Do you need A or B?

JoFrMueller commented 4 years ago

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

skorunka commented 4 years ago

Hello, how does it look with A?

RicoSuter commented 4 years ago

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 commented 4 years ago

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

stefanluchian commented 4 years ago

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 commented 4 years ago

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

dubtar commented 4 years ago

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 commented 4 years ago

Any update on this?

8VAid8 commented 4 years ago

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 commented 4 years ago

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

https://github.com/RicoSuter/NJsonSchema/issues/1013

RicoSuter commented 4 years ago

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

dubtar commented 4 years ago

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

electricessence commented 4 years ago

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

SommerEngineering commented 3 years ago

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

loganmarshall1 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

Very helpful thanks!

Standalone blazor wasm project or dotnet core hosted blazor wasm project?

Mine is Standalone. If you try to add newtonsoft as a reference to it, errors.

Please let me know your setup so I can learn if you've got it working that's fantastic! Thanks in advance,

Logan Marshall, MCP, MCSA, MCITP, MCTS, SA Scrum Agile Certified

On Jan 4, 2021, at 8:28 PM, Jack Della notifications@github.com wrote:



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.

— You are receiving this because you commented. Reply to this email directly, view it on GitHubhttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2FRicoSuter%2FNSwag%2Fissues%2F2243%23issuecomment-754326666&data=04%7C01%7C%7Cb74085fdaf1549eec2c208d8b1192495%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637454068827579979%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=Lq%2BW5Ze51BlEWggPAPAIozzWzR1%2BeCG%2Fmi7hcJGDCg4%3D&reserved=0, or unsubscribehttps://na01.safelinks.protection.outlook.com/?url=https%3A%2F%2Fgithub.com%2Fnotifications%2Funsubscribe-auth%2FAEYSEOC44MRQIXBNUGDYAYLSYJTKDANCNFSM4HYP45LQ&data=04%7C01%7C%7Cb74085fdaf1549eec2c208d8b1192495%7C84df9e7fe9f640afb435aaaaaaaaaaaa%7C1%7C0%7C637454068827589941%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C1000&sdata=kJVKBEz5SsbJwrbu%2FK9hWFalO8maKlvuGynNbOnn%2FRY%3D&reserved=0.

thebynggroup commented 3 years ago

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?

jeremyVignelles commented 3 years ago

I plan on doing my own code generator, written from scratch for modern C# (records, System.Text.Json...). However, I don't have time right now to do so.

RicoSuter commented 3 years ago

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?

I hope to start soon to migrate the DTO and client generators to also support System.Text.Json... To be honest I think it should not be that much work...

RicoSuter commented 3 years ago

First PR: https://github.com/RicoSuter/NJsonSchema/pull/1308

loganmarshall1 commented 3 years ago

Hi @RicoSuter been seeing a lot of great merges and commits. Is this epic complete? For example can I use an swag studio to generate a C-sharp client that’s dependent only on system.text.Json?

thank you for your continued work and support

RicoSuter commented 3 years ago

I'd say

A (code gen): 20% complete (what I'm currently working on) - not usable at the moment B (schema gen): 90% complete (usable) C (internal serialization): 0% (openapi models will use newtonsoft for now, changing this is huge)

loganmarshall1 commented 3 years ago

I'd say

A (code gen): 20% complete (what I'm currently working on) - not usable at the moment B (schema gen): 90% complete (usable)

that’s fantastic. Right now I’m hand writing the blazer web assembly front end client for Communication to an Nswag dotnet core Web API.

Honestly so excited, can’t wait. Keep up the great work!

is there any part of the process that I could help with and submit a PR?

RicoSuter commented 3 years ago

@loganmarshall1

is there any part of the process that I could help with and submit a PR?

In the PR I still have some TODOs (TODO(system.text.json)) and open question how to handle this in STJ: https://github.com/RicoSuter/NJsonSchema/pull/1308/files

You could help me solving these problems and adding unit tests for these cases.

I'm looking into also adding support in NSwag in the next days weeks, so if you use the new option now you'll see STJ attributes on DTOs but the clients still use Newtonsoft...:

image

image

famda commented 3 years ago

The generated class is still being generated with Newtonsoft instead of System.Text.Json. Is this still planned to be fixed?

RicoSuter commented 3 years ago

The generated class is still being generated with Newtonsoft instead of System.Text.Json. Is this still planned to be fixed?

Yes, of course. Currently its mostly only in dtos but not in the clients... there where more important things to work on (regressions, smaller enhancements), so this is still work in progress.. hope to find time soon...

loganmarshall1 commented 3 years ago

That's so great that it's coming soon.

The whole blazor Web assembly Standalone community is excited with baited breath! When this epic is successfully completed it will be OUR Xmas! ❤️

RicoSuter commented 3 years ago

Try again with https://github.com/RicoSuter/NSwag/pull/3333

JEnrightDev commented 3 years ago

Try again with #3333

This looks mostly good, however it seems you're still generating var settings = new Newtonsoft... in the CreateSerializerSettings when using the STJ version.

unchase commented 3 years ago

Try again with #3333

This looks mostly good, however it seems you're still generating var settings = new Newtonsoft... in the CreateSerializerSettings when using the STJ version.

It was fixed in PR #1331

famda commented 3 years ago

This is now throwing an error on create serializer settings.

image

image

RicoSuter commented 3 years ago

@unchase see commit: https://github.com/RicoSuter/NSwag/commit/870aee0c414546c01069a24af69564180301a07a

This JsonSerializerParameterCode in NSwag/NJS is quite messy as it has to remove chars etc... we should probably clean this up on both sides... do you have time to look into this?

famda commented 3 years ago

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

unchase commented 3 years ago

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.

RicoSuter commented 3 years ago

@unchase should we do a release of nswag now?

unchase commented 3 years ago

@RicoSuter Yes, we do. We will solve the remaining issues with System.Text.Json later.

crobibero commented 3 years ago

Current release of NSwag initializes a new JsonSerializerOptions each time the client is initialized, which is against best practice according to the docs- https://docs.microsoft.com/en-us/dotnet/standard/serialization/system-text-json-configure-options

Would it be possible to change the generator to initialize the options once, then reference that instance everywhere?

--

Registering the clients as ~Singleton~HttpClient is probably a better solution, I'll just do that instead

RicoSuter commented 3 years ago

@crobibero You're talking about this, right?

image

Any proposal on how to make this a better design. Of course we could make the property just static and remove the option to override the settings creation and remove the partial method (should usually not be tweaked anyway). Maybe put this behind a new setting... (eg UseStaticSerializerSettings)

What do you think

crobibero commented 3 years ago

In the project that I'm working on (Jellyfin) we initialize the JsonSerializerOptions only a few times with defaults that should be used throughout the codebase. example

I agree with it being initialized as a static property, but I think it should either be exposed or be able to be overwritten so the user can provide their own settings as the default JsonSerializerOptions are very strict and won't work in all cases.

RicoSuter commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

@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:

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