Ни один маршрут не соответствует указанным значениям для HTTP POST

#c# #asp.net #asp.net-mvc #asp.net-core #asp.net-web-api

#c# #asp.net #asp.net-mvc #asp.net-core #asp.net-web-api

Вопрос:

Я создаю метод POST. Следующий код принимает объект, извлекает данные из нужного объекта, затем форматирует их в новый объект и сохраняет в базе данных. Я использую следующий код:

         [HttpPost]
        public async Task<IActionResult> Create (Course course) {

            // Generate the object "newCourse" from the data I want

            // Save changes
            _context.Courses.Add(newCourse);
            await _context.SaveChangesAsync();

            // Return 201
            return CreatedAtAction(nameof(newCourse), newCourse);
        }
 

Я получаю следующую ошибку:

 System.InvalidOperationException: No route matches the supplied values.
   at Microsoft.AspNetCore.Mvc.CreatedAtActionResult.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](Stateamp; next, Scopeamp; scope, Objectamp; state, Booleanamp; isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeNextResultFilterAsync[TFilter,TFilterAsync]()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Rethrow(ResultExecutedContextSealed context)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[TFilter,TFilterAsync](Stateamp; next, Scopeamp; scope, Objectamp; state, Booleanamp; isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters()
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, Object state, Boolean isCompleted)
   at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
   at Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
   at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

 

Насколько я понимаю из других вопросов о переполнении стека, эта ошибка была (в 2016 году) вызвана ошибкой с методами маршрутизации, которая заканчивалась на «Async», которая была исправлена. Однако я использую самую новую версию, и мой метод не содержит фразы «Асинхронный», так что это не может быть проблемой, с которой я столкнулся. Я считаю, что это проблема с CreatedAtAction. Что я могу делать неправильно?

Ответ №1:

Ваша проблема заключается в том, что вы предоставляете конкретный класс в качестве параметра объекта, и ему нужен объект, поэтому

return CreatedAtAction(nameof(newCourse), newCourse);

должно быть

return CreatedAtAction(nameof(newCourse), new { newCourse });

Ответ №2:

Я думаю, что у нас проблема с первым аргументом. Второй аргумент передан правильно.

Метод CreatedAtAction(string actionName, object value) принимает два аргумента, первый — это имя действия. Похоже newCourse , что внутри одного и того же контроллера нет метода.

CreatedAtAction принимает имя действия для создания Location заголовка, который обычно возвращается вместе с кодом ответа 201 в соответствии с соглашениями REST. Это uri, который можно использовать для извлечения вновь созданного ресурса.

Вот пример, если у вас есть два метода, один для Get, а другой для Create . Предполагается, что у вас есть какой id -то аргумент для Get метода.

 [HttpGet]
public async Task<IActionResult> Get(string id) {
     ...
}

[HttpPost]
public async Task<IActionResult> Create (Course course) {
    var newCourse = ...
    
    _context.Courses.Add(newCourse);
    await _context.SaveChangesAsync();

    return CreatedAtAction("Get", new {id = course.Id}, newCourse);
}
 

Документация CreatedAtAction

Ответ №3:

Я исправил проблему, изменив

 return CreatedAtAction(nameof(newCourse), newCourse);
 

Для

 return CreatedAtAction("Create", newCourse);
 

Я считаю, что nameof(newCourse) не был правильным параметром ActionName для перегрузки, которую я пытался использовать. Перегрузить страницу документов. Я изменил его на имя функции.
примечание — это не сработало, когда я попробовал строку «Создано», только «Создать».