我有一个包含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结合的正确方法。
这是处理此问题的正确方法吗?或者有更好的选择吗?
答案 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" })