ASP.NET Web Api 路由自定义
Posted
技术标签:
【中文标题】ASP.NET Web Api 路由自定义【英文标题】:ASP.NET Web Api Routing Customization 【发布时间】:2013-01-23 16:34:50 【问题描述】:我的 WebApi 控制器的名称以“Api”后缀结尾(例如:StudentApiController、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”后缀控制器名称。
【问题讨论】:
【参考方案1】:按照@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));
【讨论】:
muruge,如果您只调用 base.GetControllerName 然后向其添加“api”,这会容易得多。但这是正确的想法。很高兴看到这个结果:) 我同意,那样会干净得多。没打到我。 :) 我一定遗漏了一些东西,这对我不起作用。我看到我的控制器选择器被调用,它最后返回 api 但我的控制器从未被调用。【参考方案2】:既然 ASP.NET Web API 2 已经发布,那么使用 attribute routing 就可以像您建议的那样执行更复杂的路由。
只需在控制器顶部添加以下属性:
[RoutePrefix("api/students")]
public class StudentsApiController : ApiController
...
然后在每个 API 方法之前:
[Route("id"]
public HttpResponseMessage Get(int id)
...
需要进行一些设置,但以这种方式进行路由的好处很多。一方面,您可以将路由与执行实际工作的控制器和方法放在一起,因此您永远不会四处寻找是否有正确的路由。其次,更重要的是,执行更复杂的路由要容易得多,例如控制器名称与路由名称不同(如您所愿)或匹配非常复杂的模式。
【讨论】:
它仍然需要带有属性路由的“控制器”后缀。【参考方案3】:我认为您正在寻找的可扩展点是控制器选择器。您可以创建一个派生自 DefaultHttpControllerSelector 并覆盖 GetControllerName 以去除“api”部分的类。然后,您可以在服务的配置服务中注册此控制器选择器。
【讨论】:
听起来是个值得研究的好地方。我会试一试,然后告诉你情况如何。【参考方案4】:在 Youssef 对 muruug 的回答发表评论之后,看起来像这样
public class ApiControllerSelector : DefaultHttpControllerSelector
public ApiControllerSelector (HttpConfiguration configuration) : base(configuration)
public override string GetControllerName(HttpRequestMessage request)
return base.GetControllerName(request) + "api";
【讨论】:
以上是关于ASP.NET Web Api 路由自定义的主要内容,如果未能解决你的问题,请参考以下文章
如何自定义 ASP .NET Web API JWT 令牌响应?
ASP.NET web api - 设置自定义 IIdentity 或 IPrincipal
如何在 ASP.NET Web API 中为 Json.NET 设置自定义 JsonSerializerSettings?