我有一个MVC应用程序,其中包含几个简单的页面,这些页面主要在Web API调用上运行。为简单起见,我想将它们包含在同一个项目中。我可以启动并导航到我的页面,但是当我尝试通过Ajax调用我的API时,我一直收到404错误 - 它无法找到API函数。
这是我的javascript文件:
$(document).ready(function () {
//set the login button to call our test API function
document.getElementById("login_submit").addEventListener("click", GetUser);
});
function GetUser() {
var response = $.ajax({
url: '/api/User',
method: 'GET',
contentType: 'application/json; charset=utf-8',
success: function (data) {
alert("Success!");
},
error: function (request, status, error) {
alert(error);
}
});
}
这是我的控制器:
namespace MyProject.Controllers.API
{
public class UserController : ApiController
{
// GET api/<controller>
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/<controller>/5
[HttpGet]
public string Get(int id)
{
return "value";
}
}
}
API控制器位于我项目中Controllers文件夹中的自己的文件夹(称为“API”)中 - 这就是命名空间在此示例控制器中包含“API”的原因。
当我在浏览器上使用F12捕获发送的请求时,我可以看到我的呼叫具有以下信息:
Request URL: http://localhost:50035/api/User
Request Method: GET
Status Code: 404 / Not Found
现在我的理解是,这应该找到名为UserController的API并找到没有参数的[HttpGet]标签的函数,然后返回字符串数组(“value1”,“value2”)。相反,它没有找到任何东西。
作为最后一点,这是我的路由配置(是的,它正在Global.asax上初始化):
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
更新
根据我到目前为止收到的反馈,我移动了我的Global.asax配置。 现在看起来像这样:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
GlobalConfiguration.Configure(WebApiConfig.Register);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
}
现在当我调用我的API函数时,我得到......待定。它不会返回成功消息。它只是挂起。我没有得到“成功!”警报。
答案 0 :(得分:2)
虽然我不确定这与我在评论中猜到的问题相同,但这是一个可能的原因。所以任何面临类似问题的人都会遇到这个问题。
MVC路由引擎尝试将传入请求与路由按照注册顺序进行匹配。
然后传入的请求将与MVC路由匹配,如果它不匹配路由PATTERN,那么它只会与WebAPI路由匹配。
现在,如果您有api/User
之类的请求,它将与MVC路由模式匹配,并且不会与WebAPI路由匹配。因此,MvcHandler将尝试创建一个ApiController
MVC控制器类并在其上调用User()
方法。因此,客户端将获得404 - 资源未找到!
此外,如果您没有使用属性路由,则可能需要删除/注释此行
//config.MapHttpAttributeRoutes();
对于更安全的http-verb-to-api-method路由,您可以在api配置中添加以下内容。
routes.MapHttpRoute("RestApiRoute", "Api/{controller}/{id}", new { id = RouteParameter.Optional }, new { id = @"\d+" }); //this replaces your current api route
routes.MapHttpRoute("ApiWithActionRoute", "Api/{controller}/{action}/{id}", new { id = RouteParameter.Optional });
routes.MapHttpRoute("DefaultApiGetRoute", "Api/{controller}", new { action = "Get" }, new { httpMethod = new HttpMethodConstraint(new string[] { "GET" }) });
routes.MapHttpRoute("DefaultApiPostRoute", "Api/{controller}", new { action = "Post" }, new { httpMethod = new HttpMethodConstraint(new string[] { "POST" }) });
routes.MapHttpRoute("DefaultApiPutRoute", "Api/{controller}", new { action = "Put" }, new { httpMethod = new HttpMethodConstraint(new string[] { "PUT" }) });
routes.MapHttpRoute("DefaultApiDeleteRoute", "Api/{controller}", new { action = "Delete" }, new { httpMethod = new HttpMethodConstraint(new string[] { "DELETE" }) });
前两条路线可以以[1]纯REST方式调用端点。 [2]用方法名称调用它们(虽然不符合REST标准!)
答案 1 :(得分:1)