Reputation: 769
I have created a class that I want to use for sending in sorting and pagination information to apply to my large collections. I have a .NET Core Web API service that will receive requests and take my object as input FromQuery
. I wanted to adhere to certain naming conventions (i.e. Microsoft Rest API Guidelines) for the parameter names such a $orderby
, $top
, $skip
, etc. and have annotated the properties of the class using JsonProperty
.
However, in generated swagger doc these simply just show as the property name itself which is a problem in cases where my property is named Take
for example but the request parameter should be $top
. I would like the generated docs to match to not cause any confusion for consumers of the API. Everything I read seems to indicate this should work and I'm stumped why its not for me.
Here is my class with the annotations using Newtonsoft.Json.JsonPropertyAttribute
[JsonObject]
public class QueryParams {
[JsonProperty( "$orderBy" )]
public string OrderBy { get; set; }
[JsonProperty( "$skip" )]
public int? Skip { get; set; }
[JsonProperty( "$top" )]
public int? Take { get; set; }
[JsonProperty( "$maxpagesize" )]
public int? MaxPageSize { get; set; }
[JsonProperty( "$count" )]
public bool? IncludeCount { get; set; }
}
And then for example my Web API action method would look something like this
[HttpGet( "type/{type}" )]
public async Task<IActionResult> GetByType(
string type,
[FromQuery]QueryParams parameters )
{
/* ... */
}
I have tried several things such as trying to use MapType
as noted at
Override Schema for Specific Types but just don't have any luck. Appreciate any insight anyone can give in regards to this.
Upvotes: 5
Views: 3159
Reputation: 24222
According to this GitHub issue, the JsonSerializer
isn't used to bind to a class for GET requests. You need to customise the model binding instead.
So, when you use a class to represent query parameters, the JsonSerializer isn’t involved. Instead, MVC model binding is used to assign values directly from the request into the instance properties.
So, if you want to be explicit about required casing for this behavior, and hence the generated description, you need to customize the model binding behavior too. I’m not at my laptop now but off the top of my head, I think you can annotate properties with “FromQuery” and set the bind name that way.
The following should work, if I understand the discussion in the GH issue correctly:
public class QueryParams {
[FromQuery( Name = "$orderBy" )]
public string OrderBy { get; set; }
[FromQuery( Name = "$skip" )]
public int? Skip { get; set; }
[FromQuery( Name = "$top" )]
public int? Take { get; set; }
[FromQuery( Name = "$maxpagesize" )]
public int? MaxPageSize { get; set; }
[FromQuery( Name = "$count" )]
public bool? IncludeCount { get; set; }
}
Upvotes: 6