How to Respond to a Post Request with method CreatedAtRoute()

Viewed 104

I am having an issue with the following code, now I understand what the problem is but I don't have a solution to make the code do what I want.

// POST: api/Airports
    [HttpPost]
    public async Task<ActionResult<Airport>> CreateAirport(AirportCreateDto airportCreateDto)
    {
        var airportModel = _mapper.Map<Airport>(airportCreateDto);
        _repository.CreateAirport(airportModel);
        await _repository.SaveChanges();

        var airportReadDto = _mapper.Map<AirportReadDto>(airportModel);

        return CreatedAtRoute(nameof(GetAirport), new { airportReadDto.ID }, airportReadDto);
    }

The CreatedAtRoute() method is the issue. Now, GetAirport is of type Task<ActionResult> which is probably the cause of the problem.

Here's the error

System.InvalidOperationException: No route matches the supplied values.
 at Microsoft.AspNetCore.Mvc.CreatedAtRouteResult.OnFormatting(ActionContext context)
 at Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsyncCore(ActionContext 
 context, ObjectResult result, Type objectType, Object value)
at Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsync(ActionContext context, 
ObjectResult result)
at Microsoft.AspNetCore.Mvc.ObjectResult.ExecuteResultAsync(ActionContext context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultAsync(IActionResult result)
at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& 
next, Scope& scope, Object& state, Boolean& isCompleted)
at 
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeNextResultFilterAsync[TFilter,
TFilterAsync 
]()

Is there a solution where I can keep using CreatedAtRoute() and GetAirport of type Task<ActionResult>?

Here's the code for GetAirport

// GET: api/Airports/5
    [HttpGet("{id}")]
    public async Task<ActionResult<Airport>> GetAirport(int id)
    {
        var airport = await _repository.GetAirportById(id);

        if (airport == null)
        {
            return NotFound();
        }

        return Ok(_mapper.Map<AirportReadDto>(airport.Value));
    }
1 Answers

System.InvalidOperationException: No route matches the supplied values.

You can try to explicitly set route name as below, which works for me.

[HttpGet("{id}", Name = "GetAirport")]
public async Task<ActionResult> GetAirport()
{
    //...

Action method CreateAirport

[HttpPost]
public async Task<ActionResult<Airport>> CreateAirport(AirportCreateDto airportCreateDto)
{
    //...

    return CreatedAtRoute(nameof(GetAirport), new { id = airportReadDto.ID }, airportReadDto);
}

Test Result

enter image description here

Related