18

In Web Api 2.2, we could return the location header URL by returning from controller as follows:

return Created(new Uri(Url.Link("GetClient", new { id = clientId })), clientReponseModel);

Url.Link(..) would resolve the resource URL accordingly based on the controller name GetClient:

Location header

In ASP.NET 5 MVC 6's Web Api, Url doesn't exist within the framework but the CreatedResult constructor does have the location parameter:

return new CreatedResult("http://www.myapi.com/api/clients/" + clientId, journeyModel);

How can I resolve this URL this without having to manually supply it, like we did in Web API 2.2?

Dave New
  • 38,496
  • 59
  • 215
  • 394

6 Answers6

21

I didn't realise it, but the CreatedAtAction() method caters for this:

return CreatedAtAction("GetClient", new { id = clientId }, clientReponseModel);

Ensure that your controller derives from MVC's Controller.

Bernard Vander Beken
  • 4,848
  • 5
  • 54
  • 76
Dave New
  • 38,496
  • 59
  • 215
  • 394
12

In the new ASP.NET MVC Core there is a property Url, which returns an instance of IUrlHelper. You can use it to generate a local URL by using the following:

[HttpPost]
public async Task<IActionResult> Post([FromBody] Person person)
{
  _DbContext.People.Add(person);
  await _DbContext.SaveChangesAsync();

  return Created(Url.RouteUrl(person.Id), person.Id);
}
Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632
1

There is an UrlHelper class which implements IUrlHelper interface. It provides the requested functionality.

Source code

mbudnik
  • 2,087
  • 15
  • 34
1

There is also CreatedAtRoute:

public async Task<IActionResult> PostImpl([FromBody] Entity entity)
{
  ...

  return CreatedAtRoute(entity.Id, entity);
  //or
  return CreatedAtRoute(new { id = entity.Id }, entity);      
}
Shimmy Weitzhandler
  • 101,809
  • 122
  • 424
  • 632
0

My GET action has a route name

    [HttpGet("{id:int}", Name = "GetOrganizationGroupByIdRoute")]
    public async Task<IActionResult> Get(int id, CancellationToken cancellationToken = default(CancellationToken))
    {
        ...
    }

And my POST action uses that route name to return the URL

    [HttpPost]
    public async Task<HttpStatusCodeResult> Post([FromBody]OrganizationGroupInput input, CancellationToken cancellationToken = default(CancellationToken))
    {
        ...
        var url = Url.RouteUrl("GetOrganizationGroupByIdRoute", new { id = item.Id }, Request.Scheme, Request.Host.ToUriComponent());
        Context.Response.Headers["Location"] = url;
        ...
    }

Resulting response using Fiddler enter image description here

Hope that helps.

mcbowes
  • 798
  • 1
  • 6
  • 14
-2

I use this simple approximation based on the Uri being served at the web server:

[HttpPost]
[Route("")]
public IHttpActionResult AddIntervencion(MyNS.MyType myObject) {
  return Created<MyNS.MyType>(Request.RequestUri + "/" + myObject.key, myObject);
}