I'm making a Web API and I want to retrieve the object created by the CreateCommand
Method.
To do that, I'm using the CreateAtRoute
function to call the GetCommandById
function ,with the id of the created Command
as parameter, but I'm getting the following error:
" System.InvalidOperationException: No route matches the supplied values."
This is my controller:
[Route("api/commands")]
[ApiController]
public class CommandsController : Controller
{
private readonly ICommanderRepo _repository;
private readonly IMapper _mapper;
public CommandsController(ICommanderRepo repository,IMapper mapper)
{
_repository = repository;
_mapper = mapper;
}
[HttpGet]
public ActionResult <IEnumerable<CommandReadDto>> GetAllCommands()
{
var commands = _repository.GetAllCommands();
return Ok(_mapper.Map<IEnumerable<CommandReadDto>>(commands));
}
[HttpGet("{id}")]
public ActionResult <CommandReadDto> GetCommandById(int id)
{
var command = _repository.GetCommandById(id);
if(command != null)
{
return Ok(_mapper.Map<CommandReadDto>(command));
}
return NotFound();
}
[HttpPost]
public ActionResult <CommandReadDto> CreateCommand(CommandCreateDto commandCreateDto)
{
var commandModel = _mapper.Map<Command>(commandCreateDto);
_repository.CreateCommand(commandModel);
_repository.SaveChanges();
var commandReadDto = _mapper.Map<CommandReadDto>(commandModel);
var x = nameof(GetCommandById);
return CreatedAtRoute(nameof(GetCommandById), new { id = commandReadDto.Id }, commandReadDto);
}
I have already tried this (which didn't resolve the problem):
services.AddControllers(options => options.SuppressAsyncSuffixInActionNames = false);
( I saw this on a post here in Stack Overflow)What might be the problem?
When using CreatedAtRoute
, you'll need something like shown below. Please note the addition of a route name, and use of that route name in CreatedAtRoute
.
[HttpGet("{id}", Name="GetCommand")]
public ActionResult <CommandReadDto> GetCommandById(int id)
{
... // your code here
}
[HttpPost]
public ActionResult <CommandReadDto> CreateCommand(CommandCreateDto commandCreateDto)
{
... // your code here
return CreatedAtRoute("GetCommand", new { commandReadDto.Id }, commandReadDto);
}
An alternative, is to use CreatedAtAction
like shown below. With this approach, a route name is not required.
return CreatedAtAction("GetCommandById", new { commandReadDto.Id }, commandReadDto);
You should derive your API-controllers from ControllerBase
instead of Controller
. The latter is targeting MVC-controllers.
And I believe you should remove options.SuppressAsyncSuffixInActionNames
until you actually need it.