question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

SwaggerToCSharpClientGenerator: support of JsonPatchDocument<T> (HttpPatch)

See original GitHub issue

Hello,

when having a HttpPatch rest api method with a Microsoft.AspNetCore.JsonPatch.JsonPatchDocument<T> as argument the csharp client generation creates a custom poco type like JsonPatchDocumentOfMyT . Since JsonPatchDocument provides a fluent way to define the patch operations like for example patchDoc.Replace(o => o.StringProperty, "B"); the generated custom poco is not very helpful.

Is there a way to exclude generic types from poco generation (such that the Microsoft.AspNetCore.JsonPatch.JsonPatchDocument<T> is kept in the client method signature)? Or, where can I preferably control the generation/mapping of such action method parameters in using the NSwag.CodeGeneration.CSharp?

Best regards, peter

Issue Analytics

  • State:open
  • Created 5 years ago
  • Reactions:8
  • Comments:11 (3 by maintainers)

github_iconTop GitHub Comments

6reactions
greenmooseSEcommented, Nov 19, 2019

I am also struggling with this, trying to create a patch according from the example in MS docs with an empty WebApi .netCore 3.0 project.

My action is specified as:

        [HttpPatch]
        public WeatherForecast Patch([FromBody] 
            [JsonSchemaType(typeof(JsonPatchDocument<WeatherForecast>))]
            JsonPatchDocument<WeatherForecast> patchDoc)
        {

First, if I use default values for Api and the CSharpClientGenerator, I get same described in this issue (i.e. a type named JsonPatchDocumentOfWeatherForecast intead of JsonPatchDocument<WeatherForecast>).

If I instead use below to configure swagger generation:

            //add the Swagger services
            services.AddSwaggerDocument(settings =>
            {
                settings
                    .TypeMappers
                    .Add(new ObjectTypeMapper(typeof(JsonPatchDocument<WeatherForecast>), new JsonSchema
                    {
                        Type = JsonObjectType.Object,
                    }));
            });

I get a swagger json file like:

"operationId": "WeatherForecast_Patch",
        "consumes": [
          "application/json-patch+json",
          "application/json",
          "text/json",
          "application/*+json"
        ],
        "parameters": [
          {
            "name": "patchDoc",
            "in": "body",
            "required": true,
            "schema": {
              "$ref": "#/definitions/JsonPatchDocumentOfWeatherForecast"
            },
            "x-nullable": false
          }
//...
"JsonPatchDocumentOfWeatherForecast": {
      "type": "object",
      "additionalProperties": {}
    }

For the CSharpClientGenerator this generates below code.

        public System.Threading.Tasks.Task<WeatherForecast> PatchAsync(System.Collections.Generic.IDictionary<string, object> patchDoc)
        {
            return PatchAsync(patchDoc, System.Threading.CancellationToken.None);
        }
//...
    public partial class JsonPatchDocumentOfWeatherForecast : System.Collections.Generic.Dictionary<string, object>
    {
    
    }

Excluding type JsonPatchDocumentOfWeatherForecast in the generator does not help since then I only end up with the System.Collections.Generic.IDictionary<string, object> patchDoc parameter for the patch action.

Any more hints of how to proceed? Thanks.

1reaction
hexxonecommented, May 27, 2022

For those who still have this problem, I have found a workaround, even if it requires manual adjustment for each case.

  1. Publish your DTO types (where the Generics are) as separate package

  2. Reference your DTO’s in the Project where you use the Generated C# Client

  3. Manually Add all wrongly generated Generics (e.g. ResponseOfFoo,ResponseOfBar,ResponseOfFooBar) to excludedTypeNames in your .nswag-file. This can be tedious depending on your project size but in my case this part will probably not change a lot in the future… And there may be a way to grab these automatically if you really need to.

  4. Tell NSwag to use your custom Generics from your DTO’s by adding the required imports to additionalNamespaceUsages in your .nswag-file

  5. after NSwag Client generation, call MakeGenericAgain. I simply do this in my .csproj like so:

  <PropertyGroup>
    <RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
  </PropertyGroup>

  <Target Name="NSwag" AfterTargets="PostBuildEvent" Condition=" '$(NO_RECURSE)' != 'true' ">
    <Exec WorkingDirectory="$(ProjectDir)" EnvironmentVariables="NO_RECURSE=true" Command="$(NSwagExe_Net60) run ./nswag.nswag /variables:Configuration=$(Configuration)" />
  </Target>
  
  <Target Name="MakeItGenericAgain" AfterTargets="NSwag" Condition=" '$(NO_RECURSE)' != 'true' "> 
    <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet tool run makeGenericAgain -f &quot;./Client/csharp/Client.cs&quot;" />
    <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet tool run makeGenericAgain -f &quot;./Client/controller/Client.cs&quot;" />
    <Exec WorkingDirectory="$(ProjectDir)" Command="dotnet tool run makeGenericAgain -f &quot;./Client/ts/index.ts&quot;" />
  </Target> 

And you can basically do the same thing for TypeScript.

Hope this helps - Cheers 😃

Read more comments on GitHub >

github_iconTop Results From Across the Web

SwaggerToCSharpClientGenerat...
Hello, when having a HttpPatch rest api method with a Microsoft. ... SwaggerToCSharpClientGenerator: support of JsonPatchDocument<T> ...
Read more >
SwaggerToCSharpClientGenerat...
SwaggerToCSharpClientGenerator : JSON output of JsonPatchDocument (HttpPatch) includes the operations property wrapper, causing model binding ...
Read more >
JsonPatch in ASP.NET Core web API
This article explains how to handle JSON Patch requests in an ASP.NET Core web API. Package installation. JSON Patch support in ASP.NET Core...
Read more >
Swagger unexpected API PATCH action documentation of ...
Why is Swagger generating an alternate structure for a JsonPatchDocument object in the request body for the PATCH endpoint? How do I fix...
Read more >
Using HttpClient to Send HTTP PATCH Requests in ASP. ...
We can see that if we want to support a request body for the PATCH requests, we have to use the JsonPatchDocument class....
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found