Question

I have this routing set up in my WebApiConfig

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

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

        config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));

        GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
    }

and these methods inside /Api/ProductController.cs

    public object GetProduct(int id)
    {
        var productRepo = new ProductRepository(db);
        var product = productRepo.GetItem(id);
        return product.ToAnonymousType();
    }

    public object GetTest()
    {
        var productRepo = new ProductRepository(this.db);
        var product = productRepo.GetItem(10000);
        return product.ToAnonymousType();
    }

I can request /api/product/getproduct/10000 and get JSON back.

If I request /api/product/gettest I get a 404

If I change gettest to

public object GetTest(int id)

and request /api/product/gettest/10000 I get JSON.

I have no idea why that 404 is happening. I have other controllers (for non-api requests) that are handling requests as normal. I'm new to MVC after some years of webforms, and this has me stumped. For reference, here's my 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 }
        );
    }

and my Application_Start

    protected void Application_Start()
    {
        BundleConfig.RegisterBundles(BundleTable.Bundles);
        RouteConfig.RegisterRoutes(RouteTable.Routes);
        GlobalConfiguration.Configure(WebApiConfig.Register);
    }
Was it helpful?

Solution

This is due to the ordering of your routes.

RouteConfig.RegisterRoutes(RouteTable.Routes);

is called before

GlobalConfiguration.Configure(WebApiConfig.Register);

and your RegisterRoutes method contains a default (and very generic) route

url: "{controller}/{action}/{id}"

this generic (default) rule will match your url pattern of

api/product/gettest

before your WebAPI route will get a chance to match it.

You can either get rid of that super generic route if not needed (and use more specific routes), or simply move the call to

GlobalConfiguration.Configure(WebApiConfig.Register);

to come before the call to

RouteConfig.RegisterRoutes(RouteTable.Routes);

in your Global.asax.

I built a sample with all of the info you gave, and moving that call worked just fine. I hope this helps.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top