我有一个在其名称中的“API”后缀结尾的WebAPI控制器(用于例如:StudentsApiController,InstructorsApiController)。 我这样做是为了方便地从控制器的WebAPI区分我的MVC控制器。 我希望我的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”后缀的控制器名称在处理路线。
我认为你正在寻找的扩展点是控制器选择。 您可以创建一个从DefaultHttpControllerSelector派生并重写GetControllerName剥离出来的“API”部分的类。 然后,您可以注册您的服务的配置服务该控制器选择。
继@Youssef穆萨维的方向我最后写下面的代码解决了这个问题。
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));
现在的ASP.NET Web API 2已经出来了,还有一个更麻烦的方式做更复杂的路由一样,你的建议,通过使用属性的路由 。
在控制器的顶部只需要添加以下属性:
[RoutePrefix("api/students")]
public class StudentsApiController : ApiController
{
...
}
再之前的每个API方法:
[Route("{id}"]
public HttpResponseMessage Get(int id)
{
...
}
有需要的一些设置的,但这样做路由这样的积极很多。 首先,你可以把与做实际工作的控制器和方法的路由,所以你永远摸索想知道,如果你有正确的路线。 其次,更重要的是,这是很容易做的更复杂的路由,就像控制器名称从路线名称不同(比如你想),或具有非常复杂的模型来匹配的。
继muruug的回答优素福的评论会是这个样子
public class ApiControllerSelector : DefaultHttpControllerSelector
{
public ApiControllerSelector (HttpConfiguration configuration) : base(configuration) { }
public override string GetControllerName(HttpRequestMessage request)
{
return base.GetControllerName(request) + "api";
}
}