Elfayer
Elfayer

Reputation: 4561

404 Not found on C# WebApi

I have an class that inherits from ApiController, some of its methods are called properly, some others are Not found. I can't find out why. I've been looking for a solution for hours now, still not getting it. Note That I'm new at this, it's my first WebApi in C#.

Routing: (WebApiConfig.cs)

public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Configuration et services API Web

            // Itinéraires de l'API Web
            config.MapHttpAttributeRoutes();

            config.Routes.MapHttpRoute(
                name: "DefaultApi",
                routeTemplate: "api/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional }
            );
        }
    }

Controller:

public class ExchangeController : ApiController
{
    public HttpResponseMessage GetMailHeader(int id)
    {
        Console.WriteLine(id);
        HttpResponseMessage response = new HttpResponseMessage();

        response.Content = new StringContent("ok");

        return response;
    }

    public HttpResponseMessage GetTest()
    {
        HttpResponseMessage response = new HttpResponseMessage();

        response.Content = new StringContent("working !!");

        return response;
    }
}

JS:

$.ajax({
    type: "GET",
    url: "/api/exchange/getTest",
    done: function (data) {
        console.log(data);
    }
});

$.ajax({
    type: "GET",
    url: "/api/exchange/getMailHeader",
    data: "42",
    done: function (data) {
        console.log(data);
    }
});

The getTest method returns a 200 OK while the getMailHeader returns 404 Not Found. What did I miss ?

Upvotes: 1

Views: 953

Answers (3)

Elfayer
Elfayer

Reputation: 4561

Thanks to everyone for your comments and answers, it has led me to the solution.

I was miss writing my ajax request. I didn't get any printed data on the console from console.log, and as @Ahmedilyas said, the data property was badly written.

The following works :

$.ajax({
    type: "GET",
    url: "/api/exchange/getTest"
})
.done(function (data) {
    console.log(data);
});

$.ajax({
    type: "GET",
    url: "/api/exchange/getMailHeader",
    data: { id: 42 }
})
.done(function (data) {
    console.log(data);
});

Upvotes: 0

robasta
robasta

Reputation: 4701

Because your method starts with 'Get', and does not have a specific attribute, the framework assumes its an HttpGet (see rule 2 below), which requires the id to be part of the url (based on the default route).

If you want it to be an HttpPost (where you pass a json object in the body like you are doing now), then add a [HttpPost] attribute above your method or remove the 'Get' portion of the action name

Reference

HTTP Methods. The framework only chooses actions that match the HTTP method of the request, determined as follows:

  1. You can specify the HTTP method with an attribute: AcceptVerbs, HttpDelete, HttpGet, HttpHead, HttpOptions, HttpPatch, HttpPost, or HttpPut.
  2. Otherwise, if the name of the controller method starts with "Get", "Post", "Put", "Delete", "Head", "Options", or "Patch", then by convention the action supports that HTTP method.
  3. If none of the above, the method supports POST.

Upvotes: 0

Vegahyo
Vegahyo

Reputation: 86

As I understand it, data adds a query string, not a part of the url itself. You define the id to be part of the url, so the right url is /api/exchange/getmailheader/42. You can also move id out of the routeTemplate.

Upvotes: 3

Related Questions