Reputation: 333
I created an apicontroller that offers a Post method to create a new nested resource (in this example: customer > mediaFile):
[Route("api/Customer/{customerId}/MediaFile", Name = "CreateMediaFileForCustomer")]
[HttpPost]
[ResponseType(typeof(MediaFile))]
public IHttpActionResult Post(long customerId, [FromBody]MediaFile mediaFile)
{
...
return CreatedAtRoute("CreateMediaFileForCustomer", new { id = mediaFile.Id }, mediaFile);
}
I expected the CreatedAtRoute method to return a location header that looks like this:
http://localhost:51656/api/Customer/1/MediaFile/37
But instead I got this:
http://localhost:51656/api/Customer/1/MediaFile?id=37
After struggling quite a bit I came up with a "solution" that somehow feels like a cheesy approach:
[Route("api/Customer/{customerId}/MediaFile/{generatedMediaFileId:long?}", Name = "CreateMediaFileForCustomer")]
[HttpPost]
[ResponseType(typeof(MediaFile))]
public IHttpActionResult Post(long customerId, [FromBody]MediaFile mediaFile)
{
...
return CreatedAtRoute("CreateMediaFileForCustomer", new { generatedMediaFileId = mediaFile.Id }, mediaFile);
}
So like this I have an optional resource id that I only need to then set the location header correctly. Is this the way it is meant to work? Or is there a more elegant solution?
Thanks!
Upvotes: 0
Views: 171
Reputation: 2071
The "CreatedAtRoute" location header should return a URL to where you can see the newly created resource. You are using the same route name as your POST method. So I would expect to see something like this:
[HttpGet()]
[Route("api/Customer/{customerId}/MediaFile/{id}", Name="GetMediaFileForCustomer")]
public IHttpActionResult Get(long customerId, long id)
{
....
}
And your CreatedAtRoute
would be:
return CreatedAtRoute("GetMediaFileForCustomer", new { customerId = customerId, id = mediaFile.Id }, mediaFile);
Upvotes: 1