I have an API action that accepts a dictionary from the query string like so:
[ApiController]
public class MyController : ControllerBase {
public async Task<ActionResult> Post(CancellationToken ct, [FromQuery(Name = "responses")] Dictionary<string, bool> responses, [FromBody] MyModelType model) { }
}
The dictionary keys describe nested properties on model
(which is sent as the request body), e.g.:
Foo
Foo.Bar
Bar[2].Foo
For the first two keys above, the dictionary binding works fine (as you would expect):
POST https://localhost/MyController?responses[Foo]=true&responses[Foo.Bar]=false
However, for the third key it fails due to the square brackets:
POST https://localhost/MyController?responses[Bar[2].Foo]=false
...with responses
containing a single entry with the key Bar[2
. Clearly the input needs to be escaped, but I haven't been able to find any documentation for how to do this, and the following approaches have not worked:
Bar\[2\].Foo
Bar[[2]].Foo
How should I go about escaping square brackets in the query string when binding to a dictionary?
CodePudding user response:
You can use the following request:
https://localhost/MyController?responses[0].key=bar[2].Foo&responses[0].value=false
Result:
For you use [FromQuery(Name = "responses")]
, so you must use responses[index].xxx
.
CodePudding user response:
I believe there are two ways to solve this problem. First, you can bind a dictionary by treating it exactly the same as a List<KeyPair<,>>
. Providing;
https://localhost/MyController?responses[0].key=Foo&responses[0].value=true&responses[1].key=bar[2].Foo&responses[1].value=false
Or, rather than numeric indices, you can provide all the index names explicitly;
https://localhost/MyController?responses.index=Foo&responses.index=bar[2].Foo&responses[Foo]=true&responses[bar[2].Foo]=false