我的WebApi控制器以其名称中的“Api”后缀结尾(例如:StudentsApiController,InstructorsApiController)。我这样做是为了轻松区分我的MVC控制器和WebApi控制器。我希望我的WebApi路线看起来类似于
http://localhost:50009/api/students/5
而非http://localhost:50009/api/studentsapi/5
。
目前要实现这一目标,我正在设置像
这样的路线routes.MapHttpRoute(
name: "GetStudents",
routeTemplate: "api/students/{id}",
defaults: new { controller = "StudentsApi", id = RouteParameter.Optional });
routes.MapHttpRoute(
name: "GetInstructors",
routeTemplate: "api/instructors/{id}",
defaults: new { controller = "InstructorsApi", id = RouteParameter.Optional });
由于我必须在控制器中为每个方法添加路由,因此这非常麻烦。我希望有一个简单的方法来设置路由模板,在处理路由时自动添加控制器名称的“api”后缀。
答案 0 :(得分:9)
按照@Youssef Moussaoui的指示,我最终编写了以下代码来解决问题。
public class ApiControllerSelector : DefaultHttpControllerSelector
{
public ApiControllerSelector(HttpConfiguration configuration)
: base(configuration)
{
}
public override string GetControllerName(HttpRequestMessage request)
{
if (request == null)
throw new ArgumentNullException("request");
IHttpRouteData routeData = request.GetRouteData();
if (routeData == null)
return null;
// Look up controller in route data
object controllerName;
routeData.Values.TryGetValue("controller", out controllerName);
if (controllerName != null)
controllerName += "api";
return (string)controllerName;
}
}
并将其注册为Global.asax
GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerSelector),
new ApiControllerSelector(GlobalConfiguration.Configuration));
答案 1 :(得分:7)
我认为您正在寻找的可扩展性点是控制器选择器。您可以创建一个派生自DefaultHttpControllerSelector的类,并重写GetControllerName以去掉“api”部分。然后,您可以在服务的配置服务上注册此控制器选择器。
答案 2 :(得分:7)
现在,ASP.NET Web API 2已经推出,使用attribute routing进行更复杂的路由,就像你建议的那样繁琐。
在控制器的顶部,只需添加以下属性:
[RoutePrefix("api/students")]
public class StudentsApiController : ApiController
{
...
}
然后在每个API方法之前:
[Route("{id}"]
public HttpResponseMessage Get(int id)
{
...
}
需要进行一些设置,但以这种方式进行路由的好处很多。例如,您可以使用执行实际工作的控制器和方法进行路由,这样您就不会在想知道自己是否有正确的路线。其次,更重要的是,更复杂的路由更容易,例如让控制器名称与路由名称不同(如您所愿)或具有非常复杂的模式来匹配。
答案 3 :(得分:1)
根据Youssef对muruug的回答的评论看起来像这样
onScheduler:[RACScheduler scheduler]