0

.NET has [FromQuery] to get query parameters on the path.

For instance my/foo?bar=1 maps to:

public class MyController : Controller
{
    [HttpGet]
    public async Task<Whatever> Foo([FromQuery] int bar, ...

The problem is boolean parameters, which can be passed as ?bar=true but are often passed by presence alone. There's no standard enforcing this either way, but it's really common practice.

So this:

public class MyController : Controller
{
    [HttpGet]
    public async Task<Whatever> Foo([FromQuery] bool? bar, ...

Will have bar as true when my/foo?bar=true, but as null when my/foo?bar.

I need:

  • Path my/foo?bar sets bar = true in .NET
  • Path my/foo sets bar = false or bar = null (either is fine) in .NET
  • Ideally handle the other corner cases:
    • my/foo?bar=1 sets true
    • my/foo?bar=0 sets false
    • my/foo?bar=false sets false

I can write my own IModelBinder from scratch to handle this, but it seems like something that should be out of the box... MVC is 20 odd years old, this must be a commonly solved problem by now?

What's the best practice for these in .NET?

8
  • 3
    a commonly solved problem by now yes, using custom binders. Just like passing "arrays", what you ask isn't standard and each framework (in the Django, Drupal sense, not Python/PHP/ASP.NET sense) used its own convention. And using bar=1 is a bad convention - integers aren't bools, and what is 2 or -1? Commented Oct 13 at 11:45
  • 1
    In the 15-year old question Use "true" or "1" for boolean querystring params some people prefer true, some 1, some mention using flags but some point out that a checkbox will always generate a query parameter, so what does foo alone mean in that case? Commented Oct 13 at 11:49
  • 1
    BTW the OpenAPI spec says parameters can be open valued so I'd expect some version of ASP.NET Core to support this. ASP.NET "Classic" is 20 years old as you said, and couldn't follow the standards and conventions that came out since Commented Oct 13 at 11:55
  • 1
    it seems like something that should be out of the box why exactly would you expect that the ASP.NET Core devs should specifically cater for your weird and nonstandard method of handling parameters? Commented Oct 13 at 12:40
  • 2
    Yes. And since this wasn't common 20 years ago, there's probably no built-in support in ASP.NET. Since OpenAPI explicitly specifies this though, there may be support of some kind for ASP.NET Core. What .NET version are you using? Commented Oct 13 at 13:27

1 Answer 1

0

Change the data type of bar to string. Put it at the end of your argument list, and turn it into an optional argument

public async Task<Whatever> Foo([FromQuery] string bar = null)

You're then going to evaluate it in your code to accommodate all these translations you want to accomplish, and pass the translated value to whatever needs it.

Sign up to request clarification or add additional context in comments.

3 Comments

So by doing this you expect my/foo?bar to set bar = "" while my/foo will set bar = null? I think both will set bar = null, but I'll test it.
No, bar should be null in both of the cases you mentioned at the beginning of the method body. Change it per your needs, once inside the method
Then this doesn't help - I need to be able to tell the difference between GET my/foo?bar and GET my/foo, which I can do with a custom IModelBinder but that feels like overkill/reinventing the wheel when so many others (whether it's best practice or not) pass ?bar to indicate that bar==true.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.