AutoQuery , Skip , Take and Swagger

Hi, it seems that the SKip And Take parameters are reported as being of type Form in the metadata page … and they do not show up in the Swagger UI.

I succesfully workaround the problem writing this
typeof(QueryBase).GetProperty(“Skip”).AddAttributes(new ApiMemberAttribute {IsRequired = false, ParameterType = “Query”, DataType = “integer” });

typeof(QueryBase).GetProperty(“Take”).AddAttributes(new ApiMemberAttribute { IsRequired = false, ParameterType = “Query”, DataType = “integer” });

However I think this attributes should be defined “out of the box” in the QueryBase class

it’s actually
ParameterType = “query” (lowercase)

btw , the same applies to OrderBy and OrderByDesc

I’m seeing them reported as query:

Are you looking at the GET operation?

it works as long in my input dto I do not put any apimemember attribute …
when I do it , swagger breaks …

with this DTO :
public class FindPersonsBindings : QueryDb
{
[DataMember(Name = “applicationId”)]
public int ApplicationId { get; set; }
[DataMember(Name = “projectId”)]
public int ProjectId { get; set; }
[DataMember(Name = “personId”)]
public List PersonId { get; set; }
[DataMember(Name = “surnameStartsWith”)]
public string SurnameStartsWith { get; set; }
[DataMember(Name = “firstNameStartsWith”)]
public string FirstNameStartsWith { get; set; }
[DataMember(Name = “defaultOrganisationNameStartsWith”)]
public string DefaultOrganisationNameStartsWith { get; set; }
[DataMember(Name = “abbreviation”)]
public string Abbreviation { get; set; }
[DataMember(Name = “userName”)]
public string UserName { get; set; }

}
IT DOES WORK

If I add Apimember attribute to 3 properties

public class FindPersonsBindings : QueryDb
{
[DataMember(Name = “applicationId”)]
[ApiMember(IsRequired = true, ParameterType = “path”, DataType = “integer”)]
public int ApplicationId { get; set; }
[DataMember(Name = “projectId”)]
[ApiMember(IsRequired = true, ParameterType = “path”, DataType = “integer”)]
public int ProjectId { get; set; }

[DataMember(Name = "personId")]
**[ApiMember(ParameterType = "query", DataType = "integer",Description = "more than one personId can be specified, repeating the querystring parameter. e.g.: ..&personId=1&personId=2")]**
public List<int> PersonId { get; set; } 
[DataMember(Name = "surnameStartsWith")]

public string SurnameStartsWith { get; set; }
[DataMember(Name = "firstNameStartsWith")]

public string FirstNameStartsWith { get; set; }
[DataMember(Name = "defaultOrganisationNameStartsWith")]

public string DefaultOrganisationNameStartsWith { get; set; }
[DataMember(Name = "abbreviation")]

public string Abbreviation { get; set; }
[DataMember(Name = "userName")]

public string UserName { get; set; }

}

all the properties without the ApiMemeber attribute disappear from the browser:

Right, as soon as you use a [ApiMember] on your Request DTO the behavior becomes opt-in same as DataContract/DataMember attributes, this is by design.

I don’t think an opt-in behaviour is a good idea for ApiMember attribute …

Say I have a dto with 25 properties … If I need to add a description to one of them (using ApiMember) … I’ll have to add that attribute to all of them…

You can use the [Description] attribute if you just want to add a description.

Adding ApiMember (for example to specify that an input field is required) hides all the AutoQuery parameters, as you described. Because those properties are not in my custom DTO, I can’t even add an ApiMember attribute to them to bring them back. How can use ApiMember but not lose the skip/take etc. params?

In current design adding [ApiMember] hides all other non-annotated by [ApiMember] properties. Like [DataMember] in serialization. And the only way to make them visible or use plugin filters or by dynamically add [ApiMember] attribute to remaining properties. Alternative way could be an adding option to Swagger/OpenApi plugin configuration, which changes the behavior of hiding non-annotated members, but this change in design need to be approved by @mythz first

I understand the behavior - however in this case, because there are properties on a AutoQuery object that we don’t control, we cannot add ApiMember to them to opt them in. You understand the problem?

As I said in previous post [ApiMember] attributes can be added dynamically to any types during program execution. One note that these attributes have to be added before AppHost.Init(), so you can add them in constructor

You can look at example here

I think that the current behaviour is not a good idea … properties without apimember should fall back to an “autonomous” fallback behaviour.

BTW : when I moved to openapi … I had all autoquerybase object properties set to parameter type “form” even if there was no apimember on the input dto
so I add to write this

public override void Configure(Container container)
{
    base.Configure(container);
    Plugins.Add(new AutoQueryFeature { MaxLimit = 100, EnableUntypedQueries = true });
    typeof(QueryBase).GetProperty("Skip").AddAttributes(new ApiMemberAttribute { IsRequired = false, ParameterType = "query", DataType = "integer" });
    typeof(QueryBase).GetProperty("Take").AddAttributes(new ApiMemberAttribute { IsRequired = false, ParameterType = "query", DataType = "integer" });
    typeof(QueryBase).GetProperty("OrderBy").AddAttributes(new ApiMemberAttribute { IsRequired = false, ParameterType = "query", DataType = "integer" });
    typeof(QueryBase).GetProperty("OrderByDesc").AddAttributes(new ApiMemberAttribute { IsRequired = false, ParameterType = "query", DataType = "integer" });
    typeof(QueryBase).GetProperty("Include").AddAttributes(new ApiMemberAttribute { IsRequired = false, ParameterType = "query", DataType = "integer" });
    typeof(QueryBase).GetProperty("Fields").AddAttributes(new ApiMemberAttribute { IsRequired = false, ParameterType = "query", DataType = "integer" });
}

… would you check that ?
tjhank you
enrico