.Net Core 2.2 Web API 405

邮差的信 提交于 2019-12-07 04:56:30

Short answer

It could be as simple as that. The reason is routing.

Just send your POST request to right URL like https://localhost:44327/api/values/123.


Detailed explanation

It's not the issue. It works as expected.

You make a GET request to https://localhost:44327/api/values/. It returns 200 OK.

But when you make a POST request to the same URL https://localhost:44327/api/values/. It says 405 Method not allowed.

However, you get 405. It is happening because you are hitting the GET endpoint with POST method.

Microsoft Docs says:

... the HTTP client sent a valid JSON request to the URL for a Web API application on a web server, but the server returned an HTTP 405 error message which indicates that the PUT method was not allowed for the URL. In contrast, if the request URI did not match a route for the Web API application, the server would return an HTTP 404 Not Found error.

https://docs.microsoft.com/en-us/aspnet/web-api/overview/testing-and-debugging/troubleshooting-http-405-errors-after-publishing-web-api-applications

If you simply remove the GET endpoint. The POST request will start returning 404 Not found. Which means that you are not hitting any registered route.

To send POST request you need to use different URL according to the routing rules.

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{

    // POST api/values
    [HttpPost("{val}")]
    public StatusCodeResult Post()
    {
        return Ok();
    }
}

This attribute-based configuration means that route of your POST endpoint is /api/Values/{val}. Where {val} is any value. It's not processed in the endpoint.

If you want to process it, you should pass it to the method:

[HttpPost("{val}")]
public StatusCodeResult Post(string val)
{
    return Ok();
}

I think that in your controller you have to import another library. Try

using System.Web.Http;

Instead of

using Microsoft.AspNetCore.Mvc

Looking at what you have defined:

[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase

Then for the action:

[HttpPost("{val}")]
public StatusCodeResult Post()
{
        return Ok();
}

Your routing matches the following url:

https://localhost:44327/api/values/StatusCodeResult

It is going to take your main route defined on your controller [Route("api/[controller]")]

Then you are defining the "template" to use "{val}"

This is telling it to use the ActionResult specific name and to expect var val to be passed/appened.

Checking out the official documentation here: https://docs.microsoft.com/en-us/aspnet/core/mvc/controllers/routing?view=aspnetcore-2.2

under section "Token replacement in route templates ([controller], [action], [area])"

They specifiy:

For convenience, attribute routes support token replacement by enclosing a token in square-braces ([, ]). The tokens [action], [area], and [controller] are replaced with the values of the action name, area name, and controller name from the action where the route is defined. In the following example, the actions match URL paths as described in the comments:

[Route("[controller]/[action]")]
public class ProductsController : Controller
{
  [HttpGet] // Matches '/Products/List'
  public IActionResult List() {
    // ...
  }

  [HttpGet("{id}")] // Matches '/Products/Edit/{id}'
  public IActionResult Edit(int id) {
    // ...
  }
}

If you want it to just route based on just verbs (follow a pattern where each api endpoint just handles operations for that specific object) then you would change your post method to just

    [HttpPost]
    public ActionResult Post(string val)
    {
        return Ok();
    }

I totally agree with @Vladimir's answer. I dont have enough points to add comments to the answer by @vlaimir so i am adding my thoughts and suggestions.

The code you have on your github,

// POST api/values
[HttpPost("{val}")]
public StatusCodeResult Post()
{
     return Ok();
}

This is a post and it would expect a value {val} per the route action configuration. Since you may try to hit the post without any value, thats not permitted. Ensure you supply some value and then do the POST. If you are using POSTMAN, you may have to supply the BODY of your request with some value. Swagger is a great util tool to embed into the web api's and that comes with excellent intuitive UI for our routes/resources. That might be even ideal to help determine and ensure you supply the right value.

Otherwise, you dont need to modify or worry about your IIS or IIS Express settings. or webdav.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!