Skip to content

[REQ] [csharp] [generichost] Support query parameters with style: deepObject and explode: true #19970

Open
@leorg99

Description

@leorg99

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: string

This 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

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,

Describe alternatives you've considered

Additional context

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions