0

I've searched around on Google and found lots of answers which I've tried testing out on my own project to get this API working. However, no luck!

In my Global file, I have:

 protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();
        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
    }

In my WebApiConfig file, I have:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MapHttpAttributeRoutes();

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

The BackupController contains:

public class BackupController : ApiController
{
    public IEnumerable<string> Backup()
    {
        return new string[] { "value1", "value2" };
    }

    // GET: api/Backup/5
    public string Get(int id)
    {
        return "value";
    }
}

Yet when I try to use the API using http://localhost:909/api/Backup I get a 404 error. Does anyone know why?

KTOV
  • 559
  • 3
  • 14
  • 39
  • Is this .netcore? – DiscipleMichael Nov 20 '17 at 18:28
  • It might help for you to include the version of Visual Studio you're using (if any), what the target platform is (.NET Framework, .NET Core), and some other details. When you create a new project in Visual Studio, it assigns a port (in the project) for your app to run at. It's possible you're querying the wrong location. I've seen some very strange issues with this over the years. – PSGuy Nov 20 '17 at 18:30

3 Answers3

2

Your web api route definition uses a route pattern which does not include the action name. It uses only the controller name and an optional parameter.

You might have a problem since your action method name is same as controller name. Change it to something which starts with Get

public class BackupController : ApiController
{
    public IEnumerable<string> GetBackupList() // or even just Get()
    {
        return new string[] { "value1", "value2" };
    }

    // GET: api/Backup/5
    public string Get(int id)
    {
        return "value";
    }
}

Now you can access it by yourSiteName/api/backup and the GetBackupList method will handle that request and the request yourSiteName/api/backup/34 will be handled by the Get(int id) action method.

Shyju
  • 214,206
  • 104
  • 411
  • 497
  • Copied exactly what you put but still no luck :( – KTOV Nov 20 '17 at 18:43
  • It should work with the code you provided. What is your action method name now and what is the url you are trying ? – Shyju Nov 20 '17 at 18:44
  • Action method name is GetBackupList() and the url is http://localhost:909/api/backup – KTOV Nov 20 '17 at 18:45
  • 1
    is your `yourSiteName/api/backup/2` working ? i assume you have called the `WebApiConfig.Register` already in app start – Shyju Nov 20 '17 at 18:47
  • Nope this doesn't work either. I've also tried the new answer but still no luck. I added a new WebAPI Controller to my Empty MVC project.. the HomeController of the project loads fine however the WebAPI Controller "BackupController" gives a 404 when trying to access it – KTOV Nov 20 '17 at 18:50
  • Are you registering your WebAPI routes at app startup? – codeMonkey Nov 20 '17 at 18:51
  • 3
    Is web api enabled in your app ? Are you calling `WebApiConfig.Register` inside the app startup ? Take a look at this post to make sure that you have web api enabled https://stackoverflow.com/questions/46943556/how-do-i-initialize-a-webhook-receiver-in-asp-net-mvc/46943972#46943972 – Shyju Nov 20 '17 at 18:52
  • 1
    @Shyju Beautiful! I updated my question to show I didn't have the bundle, your comment is what got things working! Thank you! – KTOV Nov 20 '17 at 18:58
0

It's not always necessary, but I like to use routing attributes to make this stuff more clear.

[RoutePrefix("api/backup")]
public class BackupController : ApiController
{
    [Route("backup")
    public IEnumerable<string> Backup()
    {
        return new string[] { "value1", "value2" };
    }

    // GET: api/Backup/5
    [Route("get")]
    public string Get(int id)
    {
        return "value";
    }
}

If you take a look at this diagram above, you'd see what you really want is http://localhost:909/api/backup/backup, because the first backup is the Controller name, and the second backup is your method.

In my example, adding the [Route("get")] would turn the second method into http://localhost:909/api/backup/get?id=5 or whatever, so that's not absolutely necessary--just trying to demonstrate the routing attribute concepts.

codeMonkey
  • 4,134
  • 2
  • 31
  • 50
0

Specify the route and what the controller produces.Try adding this on your Top controller

[Produces("application/json")]
[Route("api/Backup")]
public class class BackupController : ApiController

{
         //do something with other controllers



}
Mohamoud Mohamed
  • 515
  • 7
  • 16