20

I need a controller to return JSON to be consumed by JavaScript so I inherited from the ApiController class but it isn't behaving as I expected. The Apress book Pro ASP.NET MVC 4 and most of the online examples I've found give examples like:

public class ServicesController : ApiController
{
    public string[] MethodFruit()
    {
        return new string[] { "Apple", "Orange", "Banana" };
}

accessed via the URL:

http://mysite/services/methodfruit

But that never works - the resource isn't found. The only approach I can get working is to have the controller contain a different method for each HTTP verb, then:

http://mysite/api/services

Which calls the GET method.

I checked the Apress website but they don't seem to have any forums and the current source code is in VS 2012 which I'm not using. I examined the source files and they seem to think the former approach should work. Is the former approach no longer supported?

abatishchev
  • 98,240
  • 88
  • 296
  • 433
Dave
  • 1,484
  • 3
  • 14
  • 17

4 Answers4

34

Yep... generally you have to follow the default naming convention expected by ASP.NET WEB API.

Check this official doc:

Routing in ASP.NET Web API

If you do not want to follow the convention, you can try the Routing by Action Name section described in the above linked doc.

Routing by Action Name

With the default routing template, Web API uses the HTTP method to select the action. However, you can also create a route where the action name is included in the URI:

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

In your case, you'd have to do this:

[HttpGet]
public string[] MethodFruit()
{
    return new string[] { "Apple", "Orange", "Banana" };
}
Leniel Maccaferri
  • 100,159
  • 46
  • 371
  • 480
  • 1
    I have done the same thing. But I want to get this function called on `POST` request. I have added `{action}` in route and added `[AcceptVerbs("GET", "POST")]` instead of `[HttpGet]`. But It says 404 when accessing this API by making a post request. When no issue with `GET`. My action name is `GetAuthToken`. I am really can't get this resolved. Please help. – shashwat Feb 20 '14 at 12:53
  • @shashwat check if this solves your issue: http://stackoverflow.com/a/12766431/114029 – Leniel Maccaferri Feb 20 '14 at 14:46
  • @LenielMacaferi I am already using `[System.Web.Http.AcceptVerbs("GET", "POST")]`. Please look on http://pastebin.com/aCJStvT7 – shashwat Feb 21 '14 at 03:54
  • I'm not sure if you can do this in Web API. Anyways, check this similar question: http://stackoverflow.com/q/18050689/114029 Here we see a guy doing exactly that: http://stackoverflow.com/a/19765210/114029 – Leniel Maccaferri Feb 21 '14 at 15:52
10

Adding additional information on above answer. Adding RoutePrefix would fix the issue sometimes. Hope it helps

Controller

    [RoutePrefix("api/Services")]
    public class ServicesController : ApiController
    {
        [System.Web.Http.AcceptVerbs("GET", "POST")]
        [System.Web.Http.HttpGet]
        [Route("MethodFruit")]
        public string[] MethodFruit()
        {
            return new string[] { "Apple", "Orange", "Banana" };
        }
    }

In config

routes.MapHttpRoute(
name: "ActionApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional } );
Praveen M P
  • 11,314
  • 7
  • 34
  • 41
  • 1
    Using [RoutePrefix("api/referencedata")] and [Route("products")] on the action method was the only thing that worked for me. Fails when I used [Route("api/referencedata")][ActionName("products")] – MartinS Apr 21 '16 at 13:22
8

If you want Web API to look for the action name when routing, change the WebApiConfig.cs class in the App_Start folder to this:

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

Then you can just make a GET request to

http://mysite/api/Services/MethodFruit
Mahesh
  • 174
  • 7
  • I'd missed the WebApiConfig.cs class entirely. It makes a lot more sense now - I wondered why the RouteConfig class hadn't changed... – Dave Sep 06 '13 at 16:26
0

i was facing same issue, i found that on my code

using System.Web.Mvc; 

i've imported Mvc intead of using System.Web.Http. so it was using Mvc routing not webApi route. i've replaced that with

using System.Web.Http 

and it works for me. i'm adding my answer so newbies won't repeat the same mistake

Uttam Ughareja
  • 842
  • 2
  • 12
  • 21