13

我有以“Api”后缀结尾的 WebApi 控制器(例如: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”后缀控制器名称。

4

4 回答 4

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));
于 2013-01-28T21:17:47.777 回答
8

现在 ASP.NET Web API 2 已经发布,有一种更简单的方法可以像您建议的那样执行更复杂的路由,方法是使用属性 routing

在控制器的顶部添加以下属性:

[RoutePrefix("api/students")]
public class StudentsApiController : ApiController
{
    ...
}

然后在每个 API 方法之前:

[Route("{id}"]
public HttpResponseMessage Get(int id)
{
    ...
}

需要进行一些设置,但是以这种方式进行路由的好处很多。一方面,您可以将路由与执行实际工作的控制器和方法放在一起,因此您永远不会四处寻找是否有正确的路由。其次,更重要的是,执行更复杂的路由要容易得多,例如控制器名称与路由名称不同(如您所愿)或具有非常复杂的模式来匹配。

于 2014-05-07T00:27:27.313 回答
7

我认为您正在寻找的可扩展点是控制器选择器。您可以创建一个派生自 DefaultHttpControllerSelector 并覆盖 GetControllerName 以去除“api”部分的类。然后,您可以在服务的配置服务中注册此控制器选择器。

于 2013-01-23T17:16:58.197 回答
1

跟随优素福对穆鲁格的回答的评论看起来像这样

public class ApiControllerSelector : DefaultHttpControllerSelector
{
    public ApiControllerSelector (HttpConfiguration configuration) : base(configuration) { }

    public override string GetControllerName(HttpRequestMessage request)
    {
        return base.GetControllerName(request) + "api";
    }
}
于 2015-07-17T06:53:45.123 回答