0

我有一个包含 Mvc 和 Api 控制器的 Mvc3 项目。当我在没有指定“控制器/动作”的情况下运行应用程序时,会选择“默认”路由并呈现“主页/索引”页面。当该页面运行时,使用 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>

但是,当向指定“controller/action”的同一页面发出请求时,如“ 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 结合的正确方法。

这是处理这个问题的正确方法吗?还是有更好的选择?

4

2 回答 2

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 中对 url 进行了硬编码,而不是使用 url helpers 来生成它。您绝对应该在 ASP.NET MVC 应用程序中对 url 进行硬编码。您应该始终使用 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>

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

于 2012-08-24T06:11:34.207 回答
0

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

/api/controller

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

@Url.RouteUrl("DefaultApi", new { controller = "products" })
于 2012-08-24T06:10:08.237 回答