-
-
Notifications
You must be signed in to change notification settings - Fork 7.3k
Description
Is your feature request related to a problem? Please describe.
The OpenAPI spec allows you to define parameters that can be rendered as color[R]=100&color[G]=200&color[B]=150.
This can be written in the OpenApi yaml file as follows:
parameters:
- name: color
in: query
style: deepObject
explode: true
schema:
title: ColorParameter
type: object
properties:
key:
type: string
value:
type: stringThis is related to the issue in #19893
Describe the solution you'd like
To implement this, we need to modify several files.
Dealing with explode
First, we need to fix the signature of parameters with 'explode: true'.
The spec states that when this is true:
Parameter values of type array or object generate separate parameters for each value of the array or key-value pair of the map.
For a query parameter with name: color, this would look like
/foo&color=blue&color=black&color=orange
Since the parameter can be used 0 or more times, we need to change the parameter to a collection type (like List<T>).
This can be done by modifying Operation.Signature.mustache to add a {{#isExplode}} ... {{/isExplode}} section.
Next, we have to modify the following to add all the values in the List<T> parameter to NameValueCollection
Lines 408 to 443 in 008c1a4
| System.Collections.Specialized.NameValueCollection parseQueryStringLocalVar = System.Web.HttpUtility.ParseQueryString(string.Empty); | |
| {{/-first}} | |
| {{/queryParams}} | |
| {{^queryParams}} | |
| {{#authMethods}} | |
| {{#isApiKey}} | |
| {{#isKeyInQuery}} | |
| System.Collections.Specialized.NameValueCollection parseQueryStringLocalVar = System.Web.HttpUtility.ParseQueryString(string.Empty); | |
| {{/isKeyInQuery}} | |
| {{/isApiKey}} | |
| {{/authMethods}} | |
| {{/queryParams}} | |
| {{#queryParams}} | |
| {{#required}} | |
| {{#-first}} | |
| {{/-first}} | |
| parseQueryStringLocalVar["{{baseName}}"] = ClientUtils.ParameterToString({{paramName}}); | |
| {{/required}} | |
| {{/queryParams}} | |
| {{#constantParams}} | |
| {{#isQueryParam}} | |
| // Set client side default value of Query Param "{{baseName}}". | |
| parseQueryStringLocalVar["{{baseName}}"] = ClientUtils.ParameterToString({{#_enum}}"{{{.}}}"{{/_enum}}); // Constant query parameter | |
| {{/isQueryParam}} | |
| {{/constantParams}} | |
| {{#queryParams}} | |
| {{^required}} | |
| if ({{paramName}}.IsSet) | |
| parseQueryStringLocalVar["{{baseName}}"] = ClientUtils.ParameterToString({{paramName}}.Value); | |
| {{/required}} | |
| {{#-last}} | |
| uriBuilderLocalVar.Query = parseQueryStringLocalVar.ToString(); |
Support deepObject style
This along with explode:true allows us to specify query parameters as someParam[field1]=value1&someParam[field2]=value2&someParam[field3]=value3
Since the parameter defines a schema with type: object and properties, the generator generates a model to represent this type. For deepObject styles, it only makes sense to define two properties: the field or column and the value. I think what we can do here is then generate a model that has
// from parameter.name
public string Name {get; set;}
// from parameter.schema.properties[0]
public string Column {get; set;} // or Field
// from parameter.schema.properties[1]
public string Value {get; set;}Then we can generate the query parameter as Name[Column]=Value
Building on top of the changes we made previously,