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
For that you need to
Microsoft.AspNetCore.JsonPatch namespace (AdditionalNamespaceUsages)Thanks for your response. I do not get further with "type to an any class (empty but still with a name)". I always get a "Could not find the JSON path of a referenced schema: Manually referenced schemas must be added to the 'Definitions' of a parent schema.". This is my current approach:
class JsonPatchDocumentMapper : ITypeMapper
{
public async Task GenerateSchemaAsync(JsonSchema4 schema, TypeMapperContext context)
{
// add the inner type to definitions
var argument = context.Type.GenericTypeArguments[0];
var argumentSchema = await context.JsonSchemaGenerator.GenerateAsync(argument,
context.JsonSchemaResolver);
schema.Definitions.Add(argument.Name, argumentSchema);
// map JsonPatchDocument to any type
schema.Reference = new JsonSchema4() { Title = "Foo" };
}
public Type MappedType { get; } = typeof(JsonPatchDocument<>);
public bool UseReference { get; }
}
Any help would be appreciated.
Best regards,
peter
I think you can just use the ObjectTypeMapper and map it to an empty schema of type Object.
Hi @ptr1120 . It seems like we are having similar issues. Did you get anywhere with this?
This is my issue: https://github.com/RSuter/NSwag/issues/1410
The generator output the schema in such a way that the operations root is expected, whereas the request simply needs to be an array of operations. Have you found a way around that?
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.
Can we please have an example of how this should work?