#c# #mysql #visual-studio #asp.net-web-api
#c# #mysql #visual-studio #asp.net-web-api
Вопрос:
Мой webapi работает с get и GetById, но у моего post есть проблемы. Он будет успешно отправлен в базу данных, но возвращенное тело в postman показывает ошибку 500 с маршрутами. Мой поиск в Google до сих пор предлагал добавлять имена к запросам, что я и сделал, но это не помогло. Любой совет был бы высоко оценен.
Я пытался добавлять имена к запросам, но безуспешно.
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");
}
}
}
}
Ошибка консоли:
info: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[0]
User profile is available. Using 'C:UsersUserAppDataLocalASP.NETDataProtection-Keys' as key repository and Windows DPAPI to encrypt keys at rest.
Hosting environment: Development
Content root path: C:workingtripout-apiWebApi
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](Stateamp; next, Scopeamp; scope, Objectamp; state, Booleanamp; 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(Stateamp; next, Scopeamp; scope, Objectamp; state, Booleanamp; 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
В идеале он должен возвращать 200 и показывать добавленную запись при публикации.
Комментарии:
1. проследите за исключением, например, пожалуйста
2. Конечно, я только что отредактировал, чтобы включить его.
3. Привет, я немного сбит с толку, поскольку я вообще не использую «страницу». У меня уже есть return CreatedAtRoute(«LocationById», new { id = местоположение. Идентификатор }, местоположение);
Ответ №1:
Теперь это решено.
Для всех, кто мог бы прочитать это и ответ был бы полезен, проблема заключалась в том, что мой запрос post возвращался:
return CreatedAtRoute("LocationById", new { id = location.Id }, location);
и это было неправильное имя для GetLocationById
запроса get. Как только я изменил возврат post на:
return CreatedAtRoute("GetLocationById", new { id = location.Id }, location);
все это сработало нормально.
Обратите внимание, что то же самое может произойти с CreatedAtAction()
. Я рекомендую использовать ключевое слово nameof, чтобы избежать проблем, вызванных рефакторингом.
Комментарии:
1. Большое спасибо за публикацию ответа!! Это убивало меня… Оказалось, что это одно и то же. 🙂
Ответ №2:
Попробуйте указать маршрут для каждого метода, добавив [Route("api/location/getlocationbyid/{id}")]
атрибут. Когда вы это сделаете, вам, возможно, придется уменьшить атрибут get до [HttpGet]
.
Комментарии:
1. Спасибо, но это не меняет результат. Я попытался добавить этот маршрут к GetLocationById, как было предложено, с уменьшением атрибута get или без него.