问题
I haven't used the ASP.NET WebAPI much although I have used routes in straight MVC. Obviously I'm doing something wrong, perhaps someone can help? I have one controller called UsersController and two methods on it, Register and Details, both take two string parameters and return a string, both marked as HttpGet. Originally I started with two route mappings in WebApiConfig.cs:
config.Routes.MapHttpRoute(
name: "TestApi",
routeTemplate: "api/{controller}/{action}/{userId}/{key}"
);
config.Routes.MapHttpRoute(
name: "Test2Api",
routeTemplate: "api/{controller}/{action}/{userId}/{class}"
);
With this set up only the first route is found for a URL such as:
http://<domain>/api/users/register/a123/b456/
If I call:
http://<domain>/api/users/details/a123/b456/
I get a 404. If I swap the two routes around then I can call the Details method but not the Register method, again getting a 404. The workaround I have in place is to be more specific with the routes:
config.Routes.MapHttpRoute(
name: "TestApi",
routeTemplate: "api/{controller}/register/{userId}/{key}"
);
config.Routes.MapHttpRoute(
name: "Test2Api",
routeTemplate: "api/{controller}/details/{userId}/{class}/"
);
The UsersController looks like:
namespace HelloWebAPI.Controllers
{
using System;
using System.Web.Http;
using HelloWebAPI.Models;
public class UsersController : ApiController
{
[HttpGet]
public string Register(string userId, string key)
{
return userId + "-" + key;
}
[HttpGet]
public string Enrolments(string userId, string @class)
{
return userId + "-" + @class
}
}
}
So what I don't understand is why the {action} component of the route registered second is not being associated with the correct method.
Thanks
Joe
回答1:
The routing in ASP.NET Web API works in three steps:
- Matching the URI to a route template.
- Selecting a controller.
- Selecting an action.
The framework selects the first route in the route table that matches the URI, there is no "second guessing" in case when 2nd or 3rd step fails - just 404. In your case both URI are always matching the first route so the second is never used.
For further analysis let's assume that the first route is:
api/{controller}/{action}/{userId}/{key}
And you call it with following URI:
http://<domain>/api/users/enrolments/a123/b456/
In order to choose action framework is checking three things:
- The HTTP method of the request.
- The
{action}
placeholder in the route template, if present. - The parameters of the actions on the controller.
In this case the {action}
part will be resolved correctly to enrolments
, but framework will be looking for Enrolments
method with userId
and key
parameters. Your method has a class
parameter which is no match. This will result in 404.
To avoid the issue you have to make more specific routes (like you did) or unify parameters names.
回答2:
You only need to define the one route:
config.Routes.MapHttpRoute(
name: "TestApi",
routeTemplate: "api/{controller}/{action}/{userId}/{key}"
);
Then change your controller methods to the following:
[HttpGet]
public string Register(string userId, string key)
{
return userId + "-" + key;
}
[HttpGet]
public string Details(string userId, string key)
{
return userId + "-" + key
}
来源:https://stackoverflow.com/questions/15553620/route-not-recognised-in-mvc-4-webapi