Erik83
Erik83

Reputation: 549

Method not found in Web API 2

Im trying to figure out how to use Web API. I have gone through some tutorials and now Im trying to set up my web service. I have a really hard time trying to figure out why it cant find my methods. To me it just seems like random (the tutorials worked fine). During my experiments sometimes the get method returns "method not allowed".

This is my service:

public class ContentFilesController : ApiController
{
  [Route("api/contentfile/{id}")]
    [HttpGet]
    public IHttpActionResult GetContentFiles(int count)
    {
        if (_contentFiles == null)
            GenerateContentFileList();
        List<ContentFile> files = new List<ContentFile>();
        int i = 0;
        while(true)
        {
            ContentFile cf = _contentFiles[i];
            if(!_filesOutForProcessing.Contains(cf))
            {
                files.Add(cf);
                i++;
            }
            if (i == count)
                break;
        }
        return Ok(files);
    }
    [HttpPost]
    [Route("api/contentfile/{files}")]
    public IHttpActionResult Post([FromBody] List<ContentFile> files)
    {
        return Ok();
    }

}

Edit: This is the code I am using to call the service:

static async Task TestAsync()        {
        using (var client = new HttpClient())            {
            client.BaseAddress = new Uri("http://localhost:46015/");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            HttpResponseMessage response = await client.GetAsync("api/contentfile/1");
            if (response.IsSuccessStatusCode)
            {
                var contentfiles = await response.Content.ReadAsAsync<List<ContentFile>>();                    
            }
        }
    }

    static async Task ReportTest()
    {
        List<ContentFile> files = new List<ContentFile>()
        {
            new ContentFile(){Path="hej"},
            new ContentFile(){Path="då"}
        };

        using(var client = new HttpClient())
        {
            client.BaseAddress = new Uri("http://localhost:46015");
            client.DefaultRequestHeaders.Accept.Clear();
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            HttpResponseMessage response = await client.PostAsJsonAsync<List<ContentFile>>("api/contentfile", files);
            if(response.IsSuccessStatusCode)
            {

            }
        }
    }

Where do you start looking? Im going crazy here.

Thanks!

Edit: to clarify the error, the problem with both client methods are that the HttpResponseMessage has response.IsSuccessStatusCode false and the StatusCode = MethodNotAllowed or MethodNotFound.

Upvotes: 4

Views: 13974

Answers (1)

Stephen Byrne
Stephen Byrne

Reputation: 7495

Problems with the GET method

For the HTTP Get method, there is a problem with your routing.

You have declared the GET route as this:

[Route("api/contentfile/{id}")]

but then the method parameter is declared as this:

 public IHttpActionResult GetContentFiles(int count)

When using Attribute-based routing, the parameter names have to match.

I made a very simple reproduction of your code (obviously I don't have your classes but the infrastructure will be the same)

In the WebAPI project

public class ContentFile
    {
        public int ID { get; set; }
    }

    public class ContentFilesController : ApiController
    {
        [Route("api/contentfile/{count}")] //this one works
        [Route("api/contentfile/{id}")] //this one does not work
        [HttpGet]
        public IHttpActionResult GetContentFiles(int count)
        {
            var files = new List<ContentFile>();
            for (int x = 0; x < count; x++)
            {
                files.Add(new ContentFile(){ID=x});
            }

            return Ok(files);
        }
    }

In the client project

public class ContentFile
    {
        public int ID { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            using (var client = new HttpClient())
            {
                client.BaseAddress = new Uri("http://localhost:51518/");
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                HttpResponseMessage response = client.GetAsync("api/contentfile/1").Result;
                var data = response.Content.ReadAsStringAsync().Result;
                Console.WriteLine(data);
                Console.ReadKey();
            }
        }
    }

So the code is not quite identical to yours but it's pretty much the same code. Running the WebAPI project and then the client gives me:

[{"ID":0}]

Problems with the POST method

In the case of the POST method, you are declaring a route parameter, but this is never sent as part of the route, it's a POST body:

[HttpPost]
[Route("api/contentfile/{files}")] //{files} here tells routing to look for a parameter in the *Route* e.g api/contentfile/something
public IHttpActionResult Post([FromBody] List<ContentFile> files)

So the simple fix is to remove {files} from the Route template for this one.

Hope this helps.

Upvotes: 9

Related Questions