Serializing query parameters as json #1727
-
|
What I thought wo be a simple thing turns out to be mostly impossible it seems. I'm moving so projects from RestEase to Refit and RestEase seems to have a default behavior that letst you serialize complext objects in query parameters to JSON. Refit does not support this, but more importantly I cannot seems to replicate this via any of the documented ways. The way I think this should work is the formatter route, but the UrlParameterFormatter does not exactly work as expected and will flatten complex types regardless and give you the separate properties instead of the object. While trying some other method and inhereting from the query attribute I noticed today that yesterdays release has now made the query attribute sealed so that is out of the windows as well. Is the only way to make this work rebuilding the entire query string in a DelegatingHandler and replace the Query attribute with a Parameter attribute (which is now also sealed, so no extending this either)? It would be nice if I could just drop this behavior, but it is used and we are stuck it with. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
|
Thank you for your feedback, its very useful |
Beta Was this translation helpful? Give feedback.
-
|
@RavenLiquid did you find a way to do this? I'm also working with an API that wants serialized JSON in query parameters. |
Beta Was this translation helpful? Give feedback.
-
|
A few updates, and a working approach. First, To send a complex object as a single JSON-valued query parameter (instead of having Refit flatten it into separate keys), you have two clean options:
public interface IApi
{
[Get("/search")]
Task<Result> Search([Query] string filter);
}
// call site
var filter = JsonSerializer.Serialize(new { name = "abc", tags = new[] { 1, 2 } });
await api.Search(filter);The value is URL-encoded for you, so the JSON travels safely in the query string.
[Get("/search")]
Task<Result> Search([Query(TreatAsString = true)] FilterDto filter);
public sealed class FilterDto
{
public string Name { get; set; }
public int[] Tags { get; set; }
public override string ToString() => JsonSerializer.Serialize(this);
}With Option 1 is what most people use and avoids putting serialization in |
Beta Was this translation helpful? Give feedback.
A few updates, and a working approach.
First,
QueryAttributeandParameterAttributeare not sealed in current Refit. The change you saw was not kept, so subclassing is possible again - but you do not need it for this.To send a complex object as a single JSON-valued query parameter (instead of having Refit flatten it into separate keys), you have two clean options:
Th…