Update: I'm starting to wonder if this is due to a bug:
https://github.com/domaindrivendev/Swashbuckle/issues/590
But the workaround suggested there does not seem to solve my problem.
I am using Swashbuckle to generate API documentation for a C# ASP.NET Web API project.
My target is to allow the following as valid URL:
/endpoint/items/123/foo?param2=bar
With a required parameter (param1) set to "foo" and an optional parameter (param2) set to "bar". I would like both parameters contained inside a single C# parameter object. (with other optional parameters like param3 and so on). Several endpoints will use identical parameters and I would like to have a single object representing the parameters.
The details of Swagger/Swashbuckle are mostly a black box to be, and I'm unable to figure this out. I'm getting duplicates in the parameter list.
Sample code to reproduce the problem:
// This endpoint is generating documentation the way I would like.
[HttpGet]
[Route("endpoint1/items/{id}/{param1}")]
public string GetDataForParameters(int id, string param1, string param2 = null, string param3 = null)
{
return string.Format("Params: {1}, {2}, {3}", id, param1, param2, param3);
}
// This endpoint has the structure I would like, but I get duplicates for param1 in the documentation.
[HttpGet]
[Route("endpoint2/items/{id}/{param1}")]
public string GetDataForParameters(int id, [FromUri(Name = "")]MyParams myParams)
{
return string.Format("Params: {1}, {2}, {3}", id, myParams.Param1, myParams.Param2, myParams.Param3);
}
public class MyParams
{
public string Param1 { get; set;}
public string Param2 { get; set;}
public string Param3 { get; set;}
}
With the second method, I receive the parameters inside a single object. But Swagger displays a duplicate entry for the "param1".
Screenshot: Swagger duplicate parameter
How can I make Swagger/Swashbuckle not display the second entry for "param1"?
The reason for having this structure is that I have multiple endpoints that return different types of data, but they use common parameters. Some of the parameters are required (and a prt of the ID) so we would like to include those in the URL, with optional parameters in the querystring. I would prefer the common parameter object should include both required and optional parameters.
Sample code created with Visual Studio 2015 update 1. Default ASP.NET Web API project. Adding the code above to the generated ValuesController.cs. Installed package Swashbuckle 5.3.1 + dependencies.
explode (true/false) specifies whether arrays and objects should generate separate parameters for each array item or object property.
Update: Found a workaround. It's ugly:
Swagger will then pick up the method parameter and documentation for this one. ASP.Net will assign parameters to BOTH the method parameter and the parameter object, allowing the code to use the parameter object.
/// <param name="param1">URL parameters must be documented on this level.</param>
[HttpGet]
[Route("endpoint2/items/{id}/{param1}")]
public string GetDataForParameters(int id, string param1, [FromUri(Name = "")]MyParams myParams)
{
// the param1 method parameter is a dummy, and not used anywhere.
return string.Format("Params: {1}, {2}, {3}", id, myParams.Param1, myParams.Param2, myParams.Param3);
}
public class MyParams
{
/// <summary>
/// Cannot add documentation here, it will be ignored.
/// </summary>
[JsonIgnore]
public string Param1 { get; set;}
/// <summary>
/// This is included. Querystring parameters can be documented in this class.
/// </summary>
public string Param2 { get; set;}
public string Param3 { get; set;}
}
I will not use this approach, it will be too confusing for any other developer reading the code. So unfortunately, Swagger/Swashbuckle has in pratice forced me to change my (fully working) code in order to generate documentation.
Unless anyone can suggest a proper solution I think the best solution is to have plain method parameters.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With