I have an action method already written in my web api 2.0 project. I would like to add a new parameter without disturbing the existing contract. What is the best way to do that? Appreciate any best practice hints on this :)
Here's the code sample of what I intend to do:
Existing code:
[Route("{myId}",Name="MyId")]
Public IHttpActionResult Get(String myId)
{
//Some more code here
}
Url: http://localhost:8888/webapi/1111
Expecting to do something like the below:
//I want to keep the route name same for backwards compatibility.
[Route("{myId}/{myName}",Name="MyId")]
Public IHttpActionResult Get(String myId,string? myName)
{
//Some more code here
}
Url: http://localhost:8888/webapi/1111/John The Url mentioned above hits the method rightly, but I never get the second parameter (myName) populated with John.
Thanks everyone for any help towards this. Sree.
In your example you have myName
as string?
which is not allowed as:
The type 'string' must be a non-nullable value type in order to use it as parameter 'T' in the generic type or method 'System.Nullable'
A test controller was created to implement you action
[RoutePrefix("webapi")]
public class TestsController : ApiController {
[HttpGet]
[Route("{myId}/{myName}", Name = "MyId")]
public IHttpActionResult Get(string myId, string myName) {
//Some code to show the values of the parameters
return Ok(new { myId = myId, myName = myName });
}
}
When tested with webapi/1111/John
the following response is returned
{"myId":"1111","myName":"John"}
which does include the value for MyName
as John
If backwards uri webapi/1111
is tried, a NotFound
response is returned as the template does not match the new action.
To fix this you need to make the myName
parameter optional. To learn more about that check
Optional URI Parameters and Default Values
The new route will look like
//NOTICE THE `?` ON THE {myName} TEMPLATE
[Route("{myId}/{myName?}", Name = "MyId")]
public IHttpActionResult Get(string myId, string myName = null) {...}
You will notice that myName
was made optional in the route {myId}/{myName?}
and in the action parameter (string myId, string myName = null)
Now when tested with webapi/1111
the following response is returned
{"myId":"1111","myName":null}
Which would match your expected result for backwards compatibility.