63
votes

I have a controller with the following signature:

[Route("products/filter/{apc=apc}/{xpc=xpc}/{sku=sku}")]
public IHttpActionResult Get(string apc, string xpc, int? sku)
{ ... }

I call this method with following URIs:

  • ~/api/products/filter?apc=AA&xpc=BB
  • ~/api/products/filter?sku=7199123

The first URI works without issue. The second one has a strange side effect. Even though the default values for apc and xpc should be null when not provided, the parameters are actually their names. I can overcome this by adding the additional logic:

apc = (apc == "apc") ? null : apc;
xpc = (xpc == "xpc") ? null : xpc;

This seems like a hack, and would be problematic if value passed was ever equal to the parameter name.

Is there a way to define the Route without this side effect?

4
You provided default values in your route template. Why would you expect them to be null?Kenneth K.
I thought {sku=sku} mapped the parameter in the query string to the method parameter.Josh
You should review the documentation for attribute routing. It shows how to make parameters optional.Kenneth K.

4 Answers

145
votes

I figured it out. I was using a bad example I found in the past of how to map query string to the method parameters.

In case anyone else needs it, in order to have optional parameters in a query string such as:

  • ~/api/products/filter?apc=AA&xpc=BB
  • ~/api/products/filter?sku=7199123

you would use:

[Route("products/filter/{apc?}/{xpc?}/{sku?}")]
public IHttpActionResult Get(string apc = null, string xpc = null, int? sku = null)
{ ... }

It seems odd to have to define default values for the method parameters when these types already have a default.

28
votes

you need only set default value to parameters(you do not need the Route attribute):

public IHttpActionResult Get(string apc = null, string xpc = null, int? sku = null)
{ ... }
7
votes

Sku is an int, can't be defaulted to string "sku". Please check Optional URI Parameters and Default Values.

0
votes
[Route("~/api/[Controller]/AutocompleteAdress/{input=}/{input2=}")]
public IEnumerable<string> GetAutocompleteAdress(string input, string input2)

It works for me (ASP.NET WEB API).