Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ASP MVC controller action '404 not found' error when decorated with [HttpPost]

Tags:

asp.net-mvc

I have a controller action method that works when it looks like this:

public ActionResult testMethod(int id)
{
    //do something...
    //return something...
    return View();
}

But when I specify that it should be a "Post" method, I get a '404 not found error':

[HttpPost]
public ActionResult testMethod(int id)
{
    //do something...
    //return something...
    return View();
}

I have other controller action methods in the same controller - both POST and GET, and they work fine. But this one doesn't? What's going on? (I'm sure I'm missing something obvious here...)

Update: An ajax call requests the controller method: var id = 1;

$.ajax({
    url: '/indices/testMethod/',
    data: id,
    type: 'POST',
    success: function (data) {
        //Do something
    }
});

I've also tried to test the method with Postman, making sure a POST request is sent.

Update 2: I've tried changing the parameter to id, and tried to make sure all method and url locations are capitalised to match, but without any effect.

In Fiddler, I can see that actually a GET request is being made, even though I specify a POST request in the ajax call, so now I need to find out why the request ends up being sent as a GET instead of a POST.

I also tried including an attribute route description, like this

    [HttpPost]
    [Route("indices/TestMethod/{id:int}")]
    public ActionResult TestMethod(int id)

And then tried the ajax call with a different url:

$.ajax({
    url: '/indices/TestMethod/1',
    data: id,
    type: 'POST',
    success: function (data) {
        var tr = 123;
        var yr = data;
        //Do something
    }
});

With attribute routing on, and the paramter value in the URL, I see in Fiddler that first a POST request happens, which gets a 301 status error, but then a GET request is also made, which gets the 404 error.

Update 3: After more investigations I narrowed the problem definition down sufficiently that it made sense to open a new question, which can be found here: ASP MVC jQuery $.ajax POST request does not call controller method, but works in "fresh" MVC project

The issue seems to be caused by Content Security Policy settings that were active for this project.

like image 216
Proposition Joe Avatar asked Sep 29 '15 13:09

Proposition Joe


2 Answers

Try changing param1 to id and see if it works. This may sound stupid but actually I've experienced your problem before myself and that solved the problem.

The other issue I could think of is that in your app, testMethod's path is /Indices/TestMethod with uppercase characters. And when you request /indices/testMethod/ there might be some redirect happening which results in a GET request.

Try changing the url in your ajax call or try adding a [Route()] attribute to set the route name.

like image 52
Martin Shishkov Avatar answered Nov 13 '22 15:11

Martin Shishkov


You might need to add the FromBody-attribute to the int param1-parameter as it is a simple type? See here for more info.

Otherwise a route in the format /indices/testMethod/{param1} is expected (i.e. param is required to be in the URL, even if it is a POST-request). This route might not be defined, i.e. in your global.asax.cs. You could try making a POST-request to /indices/testMethod/1 for example. Just to try if it really is a routing issue?

In case you do have issues with your routing, you can define a specific route for your method using Attribute Routing. At least for testing/development as this makes it easier to see/understand which route is actually defined for your method.

Some additional questions to narrow down, what it could actually be:

  • What format does you dataGoesHere-object have?
  • What do the POST-methods that work look like? What datatype is their parameter? Reference- or value-type?
  • What routes do you register (i.e. in the global.asax.cs)?

Update

I would try following:

Define controller method like this:

[HttpPost]
[Route("indices/TestMethod/")]
public ActionResult TestMethod([FromBody] int id)

Define action call like this:

$.ajax({
    url: '/indices/TestMethod/',
    data: id, // alternatively try: {id: id}
    type: 'POST',
    success: function (data) { }
});

Either try passing the id as a simple value or try passing it withn an object with an id-property (see comment above).

like image 44
PzYon Avatar answered Nov 13 '22 15:11

PzYon