I am trying to create a proper, REST API, and document it with Swagger (2.0).
So, I have an API call that is a query, ie, it makes no changes and doesn\'t create any
For .Net and Swashbuckle (tested on 3.0) I have a generic class JsonModelBinder that implements IModelBinder interface. The class is used like this:
public IActionResult SomeAction(
[FromRoute] int id,
[FromQuery][ModelBinder(BinderType = typeof(JsonModelBinder))] SomeModelquery query) => {}
I have created Operation filter that does the following:
As a result in Swagger I have a text field where I can insert json and test requests
public class JsonModelBinderOperationFilter : IOperationFilter
{
public void Apply(Operation operation, OperationFilterContext context)
{
if (operation.Parameters == null || context.ApiDescription.HttpMethod != HttpMethod.Get.ToString())
return;
//Find json parameters
var jsonGetParameters = context.ApiDescription.ActionDescriptor.Parameters.Cast()
.Where(p => p.ParameterInfo.CustomAttributes.Any(c => c.AttributeType == typeof(ModelBinderAttribute) && c.NamedArguments.Any(IsJsonModelBinderType))).ToArray();
if (jsonGetParameters.Length > 0)
{
//Select parameters names created by Swagger from json parameters
var removeParamNames = new HashSet(context.ApiDescription.ParameterDescriptions.Where(d => jsonGetParameters.Any(p => p.Name == d.ParameterDescriptor.Name)).Select(p => p.Name));
//Create new Swagger parameters from json parameters
var newParams = jsonGetParameters.Select(p => new NonBodyParameter()
{
In = "query",
Name = p.Name,
Type = "string",
Description = "Json representation of " + p.ParameterType.Name
});
//Remove wrong parameters and add new parameters
operation.Parameters = operation.Parameters.Where(p => p.In != "query" || !removeParamNames.Contains(p.Name)).Concat(newParams).ToList();
}
}
private static bool IsJsonModelBinderType(CustomAttributeNamedArgument arg)
{
var t = arg.TypedValue.Value as Type;
return t != null && t.GetGenericTypeDefinition().IsAssignableFrom(typeof(JsonModelBinder<>));
}
}
Notes: