Статус 500: исключение InvalidOperationException: ни один маршрут не соответствует предоставленным значениям

#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 или без него.