I\'m creating a new webapi using attribute routing to create a nested route as so:
// PUT: api/Channels/5/Messages
[ResponseType(typeof(void))]
[
Oh dear, this may be a new record for answering my own question.
return CreatedAtRoute("DefaultApi", new { controller = "messages", id = message.Id }, message);
does the trick. i.e. explicitly specifying the controller. I worked this our by seeing that the exception was related to the UrlHelper and reading its docs...
Late to the party but an alternative answer. If the action you are routing to also uses attribute routing, you can give the route a name and pass that in to the CreatedAtRoute method. This is done by setting a Name
property on the Route
. Following your post example, consider the following action.
// GET: api/Messages/5
[Route("api/messages/{id}", Name="GetMessage")]
public async Task<IHttpActionResult> GetMessage(int id)
{
// get the message
}
Note that the Name
property on the route attribute, [Route("api/messages/{id}", Name="GetMessage")]
, is set to "GetMessage"
. By doing this we can call the CreatedAtRoute
method from the PostChannelMessage
action and pass in the route name like so:
return CreatedAtRoute("GetMessage", new { id = message.Id }, message);
This is a scenario I encountered and my searching led here so thought I would post this alternative answer in case it helps anyone else.
Just adding to the answers above: on Attribute Routing:
I was caught out by the parameter name, took me an hour to realise that the parameter needs to named correctly otherwise the Url Helper will return null.
i.e if you have an action method like:
[Route("api/messages/{id}", Name="GetAction")]
public IHttpActionResult GetEntity(int mySpecialUniqueId)
{
// do some work.
}
Then the return should be:
return CreatedAtRoute("GetAction", new { mySpecialUniqueId = entity.Id }, entity);
On the more simple examples, the Id property kept throwing me off so i thought I would expand on it more in this answer to help save others time on this little issue.
See this more complicated example for more detail:
Attribute Routing and CreatedAtRoute