26

I am trying to use an MVC Controller and a Web API controller in the same project, but I get 404 errors for the Web API. I started the project as an MVC project in VS 2015, but then added the Web API controller, and with the default code it is giving a 404 error.

What could be the possible solution? I have tried some solutions on Stack Overflow, but they didn't work. One I tried is the accepted answer from this question: All ASP.NET Web API controllers return 404

Global.asax:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);//WEB API 1st
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}

WebApiConfig:

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 }
        );
    }
}

RouteConfig:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }
}

Web API Controller:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using O365_APIs_Start_ASPNET_MVC.Models;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using O365_APIs_Start_ASPNET_MVC.Helpers;
using System.Threading.Tasks;

namespace O365_APIs_Start_ASPNET_MVC.Controllers
{
    public class MAILAPIController : ApiController
    {
        private MailOperations _mailOperations = new MailOperations();
        //async Task<BackOfficeResponse<List<Country>>>

        // GET: api/MAILAPI
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

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

        // POST: api/MAILAPI
        public void Post([FromBody]string value)
        {
        }

        // PUT: api/MAILAPI/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE: api/MAILAPI/5
        public void Delete(int id)
        {
        }
    }
}

I'm also getting an error restoring NuGet packages in the same solution:

An error occurred while trying to restore packages: The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.

CarenRose
  • 1,266
  • 1
  • 12
  • 24
user3177519
  • 391
  • 2
  • 4
  • 12

4 Answers4

32

You need to register the routing for web api BEFORE registering the routing for MVC, so basically your App_Start()function should look like this:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);//WEB API 1st
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);//MVC 2nd
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}
Denys Wessels
  • 16,829
  • 14
  • 80
  • 120
  • sorry its not working . Actually I already Tried it if you see my 5th comment in comments under question. I have mentioned there that i have placed this line of code after RegisterAllAreas() . I have also updated the question code now – user3177519 Aug 29 '16 at 12:23
  • 2
    Are you sure you're calling your api controller correctly?Because it's working perfectly on my side.Try calling this url but obviously replace my port number with yours - http://localhost:37294/api/MAILAPI – Denys Wessels Aug 29 '16 at 12:31
  • Thanks I was making some silly mistake .it may also due to nuget restore after nuget error resolved it worked like a charm – user3177519 Aug 29 '16 at 12:31
  • Hi All, I've got the API element working in my MVC solution, but as default it tried to run the solution as a API solution. But I want it to run as a MVC solution as default and then if you go to the API location etc, run the APIs.. Has anyone else had this issue and been able to resolve it? Thanks – Chris Cooper Feb 20 '17 at 11:48
  • works great, thank you! would you mind explaining why we musts register web api routes before mvc routes? – Sisyphus Jun 01 '19 at 13:33
1

Just add one line in the Application_Start() method in Global.asax:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();
    GlobalConfiguration.Configure(WebApiConfig.Register);   // This line you need to add
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
    RouteConfig.RegisterRoutes(RouteTable.Routes);
    BundleConfig.RegisterBundles(BundleTable.Bundles);
}
CarenRose
  • 1,266
  • 1
  • 12
  • 24
1

You can write both configurations in the same file like this:

public class RouteConfig
{
    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index",
                id = UrlParameter.Optional }
        );
    }

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

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

In the Global.aspx file, edit your code like this:

protected void Application_Start()
{
   AreaRegistration.RegisterAllAreas();
   GlobalConfiguration.Configure(RouteConfig.Register); // WEB API 1st
   FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
   RouteConfig.RegisterRoutes(RouteTable.Routes); // MVC 2nd
   BundleConfig.RegisterBundles(BundleTable.Bundles);
} 
CarenRose
  • 1,266
  • 1
  • 12
  • 24
0

You have two routes mapping the same way. Either remove delete(id) or get(id). Alternatively, you can add action in your route mapping.

sharad shrestha
  • 188
  • 2
  • 7