I've got my webapi working with get and getById, but my post has issues. It will successfully post to the database but the returned body in postman shows a 500 error with routes. My googling so far has suggested adding names to the requests, which I've done but doesn't help. Any advice would be greatly appreciated.
I've tried adding names to the requests, but no luck.
using Contracts;
using Entities.Models;
using Microsoft.AspNetCore.Mvc;
using System;
namespace WebApi.Controllers
{
[Route("api/location")]
[ApiController]
public class LocationController : ControllerBase
{
private ILoggerManager _logger;
private IRepositoryWrapper _repository;
public LocationController(ILoggerManager logger, IRepositoryWrapper repository)
{
_logger = logger;
_repository = repository;
}
[HttpGet(Name = "GetAllLocations")]
public IActionResult GetAllLocations()
{
try
{
var locations = _repository.Location.GetAllLocations();
_logger.LogInfo($"Returned all locations from database.");
return Ok(locations);
}
catch (Exception ex)
{
_logger.LogError($"Something went wrong inside GetAllLocations action: {ex.Message}");
return StatusCode(500, "Internal server error");
}
}
[HttpGet("{id}", Name = "GetLocationById")]
public IActionResult GetLocationById(int id)
{
try
{
var location = _repository.Location.GetLocationById(id);
_logger.LogInfo($"Returned location with id: {id}");
return Ok(location);
}
catch (Exception ex)
{
_logger.LogError($"Something went wrong inside GetLocationById action: {ex.Message}");
return StatusCode(500, "Internal server error");
}
}
[HttpPost(Name = "CreateLocation")]
public IActionResult CreateLocation([FromBody]Location location)
{
try
{
if (location == null)
{
_logger.LogError("Location object sent from client is null.");
return BadRequest("Location object is null");
}
if (!ModelState.IsValid)
{
_logger.LogError("Invalid location object sent from client.");
return BadRequest("Invalid model object");
}
_repository.Location.CreateLocation(location);
return CreatedAtRoute("LocationById", new { id = location.Id }, location);
}
catch (Exception ex)
{
_logger.LogError($"Something went wrong inside CreateLocation action: {ex.Message}");
return StatusCode(500, "Internal server error");
}
}
}
}
The console error is:
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
User profile is available. Using 'C:\Users\User\AppData\Local\ASP.NET\DataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
Hosting environment: Development
Content root path: C:\working\tripout-api\WebApi
Now listening on: http://localhost:5000
Application started. Press Ctrl+C to shut down.
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 POST http://localhost:5000/api/location application/json 74
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Route matched with {action = "CreateLocation", controller = "Location"}. Executing action WebApi.Controllers.LocationController.CreateLocation (WebApi)
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Executing action method WebApi.Controllers.LocationController.CreateLocation (WebApi) with arguments (Entities.Models.Location) - Validation state: Valid
info: Microsoft.EntityFrameworkCore.Infrastructure[10403]
Entity Framework Core 2.1.8-servicing-32085 initialized 'RepositoryContext' using provider 'Pomelo.EntityFrameworkCore.MySql' with options: None
info: Microsoft.EntityFrameworkCore.Database.Command[20101]
Executed DbCommand (27ms) [Parameters=[@p0='?' (DbType = Single), @p1='?' (DbType = Single), @p2='?' (Size = 4000)], CommandType='Text', CommandTimeout='30']
INSERT INTO `location` (`Latitude`, `Longitude`, `Name`)
VALUES (@p0, @p1, @p2);
SELECT `LocationId`
FROM `location`
WHERE ROW_COUNT() = 1 AND `LocationId` = LAST_INSERT_ID();
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action method WebApi.Controllers.LocationController.CreateLocation (WebApi), returned result Microsoft.AspNetCore.Mvc.CreatedAtRouteResult in 870.6956ms.
info: Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor[1]
Executing ObjectResult, writing value of type 'Entities.Models.Location'.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action WebApi.Controllers.LocationController.CreateLocation (WebApi) in 1283.1481ms
fail: Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware[1]
An unhandled exception has occurred while executing the request.
System.InvalidOperationException: No route matches the supplied values.
at Microsoft.AspNetCore.Mvc.CreatedAtRouteResult.OnFormatting(ActionContext context)
at Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsync(ActionContext context, ObjectResult result)
at Microsoft.AspNetCore.Mvc.ObjectResult.ExecuteResultAsync(ActionContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultAsync(IActionResult result)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResultFilterAsync[TFilter,TFilterAsync]()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResultExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.ResultNext[TFilter,TFilterAsync](State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeResultFilters()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Cors.Infrastructure.CorsMiddleware.Invoke(HttpContext context)
at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Request finished in 1615.8678ms 500 text/html; charset=utf-8
Ideally it should return a 200 and show the added entry when posting.
This is now resolved.
For anyone who might read this and the answer be helpful, the issue was that my post request was returning:
return CreatedAtRoute("LocationById", new { id = location.Id }, location);
and this was the incorrect name for the GetLocationById get request. Once I changed the post return to:
return CreatedAtRoute("GetLocationById", new { id = location.Id }, location);
this all worked fine.
Note that the same may occur with CreatedAtAction(). I recommend using nameof keyword to avoid problems caused by refactoring.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With