MVC Web API路由配置 - 路由模板中的过滤器控制器

时间:2013-10-25 15:29:16

标签: asp.net-mvc-4 model-view-controller asp.net-web-api asp.net-mvc-routing asp.net-web-api-routing

我的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);
}

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

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/Classroom控制器而只能从Campus访问http://MYHOST/api/Campus控制器。

据我所知,这是“预期的行为”,因为从我的路线配置方面来看,没有什么能阻止这种行为。但是我该如何预防?

我考虑过:

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

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

2 个答案:

答案 0 :(得分: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);

}

答案 1 :(得分:2)

此链接可以帮助您:http://aspnetwebstack.codeplex.com/wikipage?title=Attribute%20routing%20in%20Web%20API

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