Feanaro
Feanaro

Reputation: 932

MVC4 API Post verb throws http 404

I'm trying to create a REST api based on the Asp.Net MVC4 web api framework. The GET requests are working just fine. All other verbs are getting ignored by the server. It just says the following:

"No action was found on the controller 'Track' that matches the request."

Though the example error is from the Track controller all other controllers have the same problem.

This is the method on the controller Track I'm trying to call:

    [HttpPost]
    public Object Index(string token, string juke, string track)
    {
    }

I'v tried it using a JSON object like so:

{ "track": "0000", "juke": "0000" }

And I tried to use the "normal" way:

track=0000&juke=0000

The '0000' in the examples above are stand-ins for the real id's.

To be sure I'm also posting the Register() from WebApiConfig.cs:

public static void Register(HttpConfiguration config)
    {
        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));
        config.Routes.MapHttpRoute(
            name: "DefaultIndexBackEnd",
            routeTemplate: "back-end/{controller}/{token}",
            defaults: new { action = "Index", token = RouteParameter.Optional }
        );
        config.Routes.MapHttpRoute(
            name: "DefaultBackEnd",
            routeTemplate: "back-end/{controller}/{action}/{token}",
            defaults: new { token = RouteParameter.Optional }
        );
    }

Upvotes: 1

Views: 316

Answers (3)

Feanaro
Feanaro

Reputation: 932

After several hours of trying and researching articles I finally found an article that precisely described my problem! If you're having the same problems, check out the article.

The problem was that I had to use the [FromBody] attribute on one parameter of the of the action. After moving juke and track into a model it finally worked as I had hoped.

Thanks everyone for the help, you all set me on the right track!

Upvotes: 1

Alex Sanséau
Alex Sanséau

Reputation: 8780

First, it's important to understand how a typical REST Web API is supposed to work. Typically, it uses different HTTP verbs (GET, POST, PUT, DELETE) for specific actions.

  • GET: get an entity (or a collection) from the server
  • POST: create a new entity
  • PUT: update an existing entity
  • DELETE: delete an existing entity

So when I see [HttpPost] on your Index action, it seems to me that the REST API pattern is broken.

Instead, in your controller you should have a Entity Get(int id) action (to get data) and a void Post(Entity entity) action to create new records.

No need to decorate your actions with HttpGet or HttpPost, the MVC Api framework will route the request to your action based on their names.

You can take a look at an example here.

Upvotes: 1

su8898
su8898

Reputation: 1713

Try this in your TrackController. Because you are using multiple parameters, they must be declared as optional.

[HttpPost]
public Object Index(string token="", string juke="", string track="")
{
}

You can make parameter token mandatory because token is declared as optional in routing configuration DefaultIndexBackEnd. I think using [FromBody] attribute is a good idea when there is more than one parameter for POST actions.

Upvotes: 1

Related Questions