除了默认路由之外,Web Api呼叫失败

时间:2012-08-24 06:06:26

标签: asp.net-mvc-3 asp.net-mvc-routing asp.net-web-api

我有一个包含Mvc和Api控制器的Mvc3项目。当我在未指定“ controller / action ”的情况下运行应用程序时,选择了“默认”路由并选择了“ home / index ”页面被渲染。当该页面运行时,使用url:“ api / controller ”进行Ajax调用,返回json,然后用于填充页面上的表。

     

 <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>

但是,当请求指定“控制器/操作”的同一页面时,如“ localhost / home / index ”,Ajax调用将转换为“ / home / api / controller “当然请求无法完成或返回任何结果,因为无法找到ApiController。

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

考虑到它必须是路由问题,我接着通过添加路由来解决这个问题:

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

这是成功的。正如我下一次改为:

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

哪个也有效但让我有点怀疑它是否是处理WebApi与Mvc结合的正确方法。

这是处理此问题的正确方法吗?或者有更好的选择吗?

2 个答案:

答案 0 :(得分:1)

  

考虑到它必须是路由问题,我接着通过添加路由来解决这个问题:

不,这根本不是路由问题。你的路线非常好:

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

您的问题源于这样一个事实:您已经在javascript中对网址进行了硬编码,而不是使用网址助手来生成它。您绝对应该永远对ASP.NET MVC应用程序中的URL进行硬编码。您应始终使用网址助手。

所以:

<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>

另请注意,我已从您的AJAX调用中删除了contentType: 'json',因为首先正确的内容类型是contentType: 'application/json',其次是在这种情况下您没有在请求中发送任何数据,所以您不应该'将其设置为application/json

答案 1 :(得分:0)

无需在那里添加路由 - 您可以指定API URL以便它始终有效:

/api/controller

在某些情况下,您可能需要使用Url.RouteUrl帮助程序根据路由显式创建URL(按路由名称和/或路由值)。例如,这将使用 controller = products 指定名为“DefaultApi”的路由:

@Url.RouteUrl("DefaultApi", new { controller = "products" })