Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Optional Parameters in Web Api Attribute Routing

I want to handle POST of the following API-Call:

/v1/location/deviceid/appid

Additional Parameter are coming from the Post-Body.

This all works fine for me. Now I wnat to extend my code by allowing "deviceid" and/or "appid" and/or BodyData to be null:

/v1/location/deviceid /v1/location/appid /v1/location/ 

These 3 URLs should responded by the same route.

My first approach (BodyData required):

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")] public location_fromuser Post(string deviceid = null, string appid = null, [FromBody] location_fromuser BodyData) {     return repository.AddNewLocation(deviceid, appid, BodyData); } 

This does not work and returns a compile error:

"optional Parameters must be at the end"

Next try:

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")] public location_fromuser Post([FromBody] location_fromuser BodyData, string deviceid = null, string appid = null) 

Now my function AddNewLocation() get always an BodyData=null - even if the call send the Body.

Finally I set all 3 Parameter optional:

[Route("v1/location/{deviceid}/{appid}", Name = "AddNewLocation")] public location_fromuser Post(string deviceid = null, string appid = null, [FromBody location_fromuser BodyData = null) 

Don´t work:

Optional parameter BodyData is not supported by FormatterParameterBinding.

Why do I want a solution with optional Parameters? My Controller handles just the "adding of a new Location" via a POST.

I want to send on wrong data my own exceptions or error messages. Even if the call has missing values. In this case I want to be able to decide to throw an exception or Setting Defaults by my code.

like image 879
Oliver Apel Avatar asked Apr 01 '14 06:04

Oliver Apel


People also ask

How do I pass optional parameters in web API?

Optional Parameters in Web API Attribute Routing and Default Values: You can make a URI parameter as optional by adding a question mark (“?”) to the route parameter. If you make a route parameter as optional then you must specify a default value by using parameter = value for the method parameter.

Which is optional element when you define route config in web API?

Web API uses URI as “DomainName/api/ControllerName/Id” by default where Id is the optional parameter. If we want to change the routing globally, then we have to change routing code in register Method in WebApiConfig.

What is attribute routing in web API?

As the name implies, attribute routing uses attributes to define routes. Attribute routing gives you more control over the URIs in your web API. For example, you can easily create URIs that describe hierarchies of resources. The earlier style of routing, called convention-based routing, is still fully supported.

How do you pass optional parameters in C#?

By Params Keyword: You can implement optional parameters by using the params keyword. It allows you to pass any variable number of parameters to a method. But you can use the params keyword for only one parameter and that parameter is the last parameter of the method.


2 Answers

For an incoming request like /v1/location/1234, as you can imagine it would be difficult for Web API to automatically figure out if the value of the segment corresponding to '1234' is related to appid and not to deviceid.

I think you should change your route template to be like [Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")] and then parse the deiveOrAppid to figure out the type of id.

Also you need to make the segments in the route template itself optional otherwise the segments are considered as required. Note the ? character in this case. For example: [Route("v1/location/{deviceOrAppid?}", Name = "AddNewLocation")]

like image 145
Kiran Avatar answered Sep 22 '22 23:09

Kiran


Another info: If you want use a Route Constraint, imagine that you want force that parameter has int datatype, then you need use this syntax:

[Route("v1/location/**{deviceOrAppid:int?}**", Name = "AddNewLocation")] 

The ? character is put always before the last } character

For more information see: Optional URI Parameters and Default Values

like image 27
Tiago Ferreira Avatar answered Sep 20 '22 23:09

Tiago Ferreira