Q:

WebApi call fails for other than the default route

I have an Mvc3 project that includes both Mvc and Api controllers. When I run the application without specifying the "controller/action", the "Default" route is selected and the "home/index" page is rendered. When that page runs, an Ajax call is made using url: "api/controller", returning json, which is then used to populate a table on the page.

 <script type="text/javascript">
     $(function () {
         var $products = $("#products");
         $.ajax({
             url: "api/products",
             contentType: "json",
             success: function (data) {
                 $.each(data, function (index, item) {
                     $products.append("<tr><td>" + item.ProductCode + "</td>" +
                                         "<td>" + item.Description + "</td>");
                 });
             }
         });
     });
 </script>

However, when a request is made to the same page specifying the "controller/action", as in "localhost/home/index", the Ajax call is translated to "/home/api/controller" and of course the request cannot complete or return any results, since the ApiController cannot be found.
    public static void RegisterRoutes(RouteCollection routes) {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.MapHttpRoute(
           "DefaultApi",
           "api/{controller}/{id}",
           new { id = RouteParameter.Optional }
        );

        routes.MapRoute(
            "Default", // Route name
            "{controller}/{action}/{id}", // URL with parameters
            new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
        );
    }

Considering that it must be a routing issue, I proceeded to resolve this by adding a route:
        routes.MapHttpRoute(
           "HomeApi",
           "home/api/{controller}/{id}",
           new { id = RouteParameter.Optional }
        );

This was successful. As was my next change to:
        routes.MapHttpRoute(
           "AnyApi",
           "{folder}/api/{controller}/{id}",
           new { id = RouteParameter.Optional }
        );

Which also works but leaves me somewhat skeptical as to whether it is the correct way to handle combining WebApi with Mvc.
Is this the correct way to handle this? Or are there better alternatives?

A:

Considering that it must be a routing issue, I proceeded to resolve this by adding a route:

No, that's not a routing issue at all. Your routes are perfectly fine:
public static void RegisterRoutes(RouteCollection routes) {
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapHttpRoute(
       "DefaultApi",
       "api/{controller}/{id}",
       new { id = RouteParameter.Optional }
    );

    routes.MapRoute(
        "Default", // Route name
        "{controller}/{action}/{id}", // URL with parameters
        new { controller = "Home", action = "Index", id = UrlParameter.Optional } 
    );
}

Your issue stems from the fact that you have hardcoded the url in your javascript instead of using url helpers to generate it. You should absolutely never hardcode an url inside an ASP.NET MVC application. You should always use url helpers.
So:
<script type="text/javascript">
    $(function () {
        var $products = $("#products");
        var url = '@Url.RouteUrl("DefaultApi", new { httproute = "", controller = "products" })';
        $.ajax({
            url: url,
            success: function (data) {
                $.each(data, function (index, item) {
                    $products.append("<tr><td>" + item.ProductCode + "</td>" +
                                         "<td>" + item.Description + "</td>");
                });
            }
        });
    });
</script>

Also notice that I have removed the contentType: 'json' from your AJAX call because first the correct content type is contentType: 'application/json' and second in this case you are not sending any data in the request, so you shouldn't be setting it to application/json.

