0

我WebApiConfig.cs註冊方法如下:MVC的Web API航線配置 - 在路由模板過濾器控制器

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。我希望能夠僅從http://MYHOST/classroomContent/ClassroomCampus控制器僅從http://MYHOST/api/Campus訪問Classroom控制器。

我知道這是「預期的行爲」,因爲從我的路線配置角度來看,沒有任何東西可以阻止這種情況發生。但我該如何預防呢?

我已經考慮:

  • 使用領域。但是,從我閱讀的內容來看,它們不支持Web API(至少不是開箱即可)。我可以嘗試探索嘗試實現區域功能的選項,但是當我甚至不確定它們是否是正確的解決方案時,似乎很多。
  • 爲每個控制器定義一個單獨的路由。但是,我有很多控制器,所以這看起來非常麻煩。

解決此問題的最佳方法是什麼?有沒有辦法做到這一點,而不嘗試自己實現Web API領域?理想情況下,我可以以某種方式「過濾」哪些控制器是每個路由模板的參數{controller}的有效值。

回答

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); 

}

+0

謝謝!如果我可以將2個答案標記爲「接受」,我會的。你的方法很好,用一個例子很好地回答了我的問題。但在我的情況下,屬性路由更好。我提出了兩個答案。 :) – mayabelle