0

我的 WebApiConfig.cs 注册方法如下所示:

public static void Register(HttpConfiguration config)
{
    config.Routes.MapHttpRoute(
        name: "ClassroomContentApi",
        routeTemplate: "classroomContent/{controller}/{id}",
        defaults: new {id = RouteParameter.Optional}
        );

    // Default
    config.Routes.MapHttpRoute(
        name: "DefaultApi",
        routeTemplate: "api/{controller}/{id}",
        defaults: new {id = RouteParameter.Optional});

    MediaTypeHeaderValue appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
    config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);
}

Controllers的 MVC 项目中的文件夹结构如下(这些不是控制器的真实名称,但这并不重要):

Controllers
    ClassroomContent
        ClassroomController.cs
        ClassroomController2.cs
        ClassroomController3.cs
    SchoolInfo
        CampusController.cs
        CampusController2.cs
        CampusController3.cs
    StudentInfo
        StudentController.cs
        StudentController2.cs
        StudentController3.cs
    etc...

我希望ClassroomContent文件夹中的所有控制器都使用上面的第一个路由,而所有其他控制器(在任何其他文件夹中)都使用上面的第二个路由。

我遇到的问题是,上面的第一条路由在ClassroomContent控制器文件夹之外的控制器中获取 web api 操作,反之亦然。

例如,我可以访问http://MYHOST/classroomContent/Campushttp://MYHOST/api/Classroom。我希望能够Classroom仅从http://MYHOST/classroomContent/ClassroomCampus仅从http://MYHOST/api/Campus.

我知道这是“预期的行为”,因为从我的路线配置的角度来看,没有什么能阻止这一点。但是我该如何预防呢?

我所考虑的:

  • 使用领域。但是,根据我的阅读,Web API 不支持它们(至少不是开箱即用的)。我可以尝试探索尝试实现区域功能的选项,但是当我什至不确定它们是否是正确的解决方案时,这似乎很多。
  • 为每个控制器定义单独的路由。但是,我有很多控制器,所以这看起来很麻烦。

解决这个问题的最佳方法是什么?有没有办法在不尝试自己实现 Web API 区域的情况下做到这一点?理想情况下,我能够以某种方式“过滤”哪些控制器是{controller}每个路由模板参数的有效值。

4

2 回答 2

4

如果您不想使用属性路由,RouteConstraints也应该起作用。

假设您的控制器命名为:ClassRoom1Controller、ClassRoom2Controller 等,以下应该可以工作(请注意,您可以使用正则表达式来配​​置约束,因此应该有很多可能性来配置它):

public static void Register(HttpConfiguration config)
{
   config.Routes.MapHttpRoute(
      name: "ClassroomContentApi",
      routeTemplate: "classroomContent/{controller}/{id}",
      defaults: new {id = RouteParameter.Optional},
      constraints: new { controller = "classRoom1|classRoom2|classRoom3" }
    );

// Default
config.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new {id = RouteParameter.Optional},
    constraints: new { controller = @"^((?!(classRoom1|classRoom2|classRoom3)).)*$" });

MediaTypeHeaderValue appXmlType = config.Formatters.XmlFormatter.SupportedMediaTypes.FirstOrDefault(t => t.MediaType == "application/xml");
config.Formatters.XmlFormatter.SupportedMediaTypes.Remove(appXmlType);

}

于 2013-10-25T15:51:45.750 回答
2

此链接应该对您有所帮助:http ://aspnetwebstack.codeplex.com/wikipage?title=Attribute%20routing%20in%20Web%20API

您可以使用 Web Api 2 在控制器级别定义自定义路由。

于 2013-10-25T15:47:24.813 回答