ChatGPT解决这个技术问题 Extra ChatGPT

Web API optional parameters

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?

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

J
Josh

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.


I echo your thoughts - It seems odd to have to define default values for the method parameters when these types already have a default.. Checked the details on MSDN als here but it doesn't talk about any technical details as to why it has been decided to be like that.
Nullability and optionality are two different concepts, and they have nothing to do with one another (since nullable values can be used outside a parameter list). Simply declaring a parameter int? marks it as nullable, but it is not optional: You must pass either a non-null integral value or null. Adding = null, however, is the syntax required for declaring the default value of an optional parameter. Hence, int? sku = null is a nullable int whose default value is null (instead of some other integral value).
A
Ali Rasouli

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)
{ ... }

i
iliketocode

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


Not recommended solution as you need to provide additional validation logic to check whether the parameter is actually an int if it is not null. If you stick to int? the framework provides the validation out-of-the-box and you only need to check the ModelState...
i
iliketocode
[Route("~/api/[Controller]/AutocompleteAdress/{input=}/{input2=}")]
public IEnumerable<string> GetAutocompleteAdress(string input, string input2)

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