Closed chrisjainsley closed 6 years ago
I'm holiday without access to a computer, but can you look at the swagger.json and see if that looks correct?
Matt
On 4 May 2018, at 13:24, cja100 notifications@github.com wrote:
I have a simple patch endpoint and I'm trying to create an example:
[SwaggerRequestExample(typeof(JsonPatchDocument
), typeof(UpdateCustomerRequestExample))] public IActionResult Patch(Guid id, [FromBody]JsonPatchDocument updateCustomerRequestPatch) public class UpdateCustomerRequestExample : IExamplesProvider { public object GetExamples() { return new JsonPatchDocument () { Operations = { new Operation ("replace", "email", "Aubree.Scott@gmail.com", "jane@hotmail.com") } }; } } Unfortunately the example displayed is: [ { "value": {}, "path": "string", "op": "string", "from": "string" } ] — You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.
The swagger json generated is also incorrect, is the same as above.
I have exactly the same problem. Even subclassed JsonPatchDocument but it didnt help :/
I must confess I've never heard of JsonPatchDocument
before. I'll investigate this when I get a chance but it won't be for at least another week or two.
@mattfrear - some more info that may help.
I don't know that there is anything you can do from this end - maybe it's one for the Swashbuckle guys. JsonPatchDocument is basically just a List\<Operation> and this seems to be what Swashbuckle registers as the parameter type.
The examples filter here: https://github.com/mattfrear/Swashbuckle.AspNetCore.Examples/blob/9eb6b006d4ce5e65f829c5944a15ada8d6885b82/src/Swashbuckle.AspNetCore.Examples/Examples/ExamplesOperationFilter.cs#L43 is looking for JsonPatchDocument but there isn't one because it defined as an Operation, so you get back null and therefore no example.
A solution may be to have a schema filter which would generate the correct types for your models. https://github.com/domaindrivendev/Swashbuckle.AspNetCore#extend-generator-with-operation-schema--document-filters
Or perhaps Swashbuckle should be registering JsonPatchDocument.
Incidentally, I created a custom class inheriting from JsonPatchDocument to see if that would help and fool Swashbuckle into registering my type, but sadly not :(
Hello
Sorry for the delay in looking at this, I haven't had a lot of free time until the last week or so.
This works, using ASP.NET Core 1.1:
[HttpPatch]
[Route("api/values/patchperson")]
[SwaggerRequestExample(typeof(JsonPatchDocument<PersonRequest>), typeof(JsonPatchPersonRequestExample))]
public PersonResponse JsonPatchPerson([FromBody]JsonPatchDocument<PersonRequest> personRequest)
or this, for ASP.NET Core 2.0:
[HttpPatch]
[Route("api/values/patchperson")]
[SwaggerRequestExample(typeof(Operation), typeof(JsonPatchPersonRequestExample))]
public PersonResponse JsonPatchPerson([FromBody]JsonPatchDocument<PersonRequest> personRequest)
using Microsoft.AspNetCore.JsonPatch.Operations;
using Swashbuckle.AspNetCore.Filters;
namespace WebApi.Models.Examples
{
public class JsonPatchPersonRequestExample : IExamplesProvider
{
public object GetExamples()
{
return new[]
{
new Operation
{
op = "replace",
path = "/firstname",
value = "Steve"
},
new Operation
{
op = "remove",
path = "/income"
}
};
}
}
}
Hope that helps.
See my updated answer above for a solution for .NET Core 1.1.
Thanks @mattfrear - It is not intuitive to use Operation rather than JsonPatchDocument, but at least this works which is the main thing!
Hey, I might miss something here. My problem on ASP.NET Core 2 is not about if it is intuitive or not (well, it might be). Because the example is registered to a parameter type and not for an operation/action (if I understood well) using the Operation type means the example still will be the same for each and every JsonPatchDocument<> parameter - just not the default one. But in practice I'd like to provide a real meaningful example for each of my patch actions. Because, for example, JsonPatchDocument<MyClass> is not the same as JsonPatchDocument<List<OtherClass>>. Currently I cannot do it, not even with a schema filter, because only the Operation type is taken into account. If I register an example for Operation<Myclass> then it does nothing, so I cannot differentiate between different JsonPatchDocuments. Is there a way to do that?
And the fact that it uses Operation instead of JsonPatchDocument also causes trouble to give an example with multiple operations... It will have an extra level of array.
Yes, it's a limitation of Swagger 2.0 that you can only have example per Request type. OpenApi 3 seems to allow different request examples for each operation, and I have released a beta version of this package which supports OpenApi 3, so that may work for you?
But to be honest, I haven't had the need to use JsonPatch on any of my own projects and until I do I'm not going to really attempt to tackle this.
OK, thanks, That might work indeed. And you're right, I have to admit my requirements are a bit extreme. But in case someone has the same weird thing in mind: I was able to solve it with an operation filter. I pick up the BodyParameter from the operation. That one has a Schema which is not from the SchemaRegistry but rather just has a reference to it. So if I set the example on this Schema, then it will be for that certain operation only.
We ended up inherting from JsonPatchDocument - e.g. FooOverlaysJsonPatchDocument and then doing a map type on that:
public class FooJsonPatchDocument : JsonPatchDocument
{
public FooJsonPatchDocument() : base()
{
}
public FooJsonPatchDocument(List<Operation> operations, IContractResolver contractResolver) : base(operations, contractResolver)
{
}
}
public static void AddPatchExample<TPatchDocument, TExamplesProvider>(this SwaggerGenOptions options) where TPatchDocument : JsonPatchDocument where TExamplesProvider: IExamplesProvider, new()
{
options.MapType<TPatchDocument>(() => new Schema
{
Type = "object",
Example = new TExamplesProvider().GetExamples()
});
}
options.AddPatchExample<FooJsonPatchDocument, PatchFooExample>();
I have a simple patch endpoint and I'm trying to create an example:
Unfortunately the example displayed is: