2014-10-16 16 views
0

我已經創建了兩個控制器,用於出口型模式和WADL和其他一切是使用ASP.NET WebApi,我怎樣才能讓路線排除一組控制器?

所以我創建了三條路線,二爲專用控制器(Schema和WADL),一個用於「一切」的API的一部分:

 config.Routes.MapHttpRoute(
      name: "Schemas", 
      routeTemplate: "api/{controller}/{typeName}/{subType}", 
      defaults: new { subtype = RouteParameter.Optional }, 
      constraints: new { controller = @"Schemas" } 
     ); 

     config.Routes.MapHttpRoute(
      name: "Wadl", 
      routeTemplate: "api/{controller}", 
      defaults: null, 
      constraints: new { controller = @"Wadl" } 
     ); 

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

我試過下面這個頁面:http://stephenwalther.com/archive/2008/08/07/asp-net-mvc-tip-30-create-custom-route-constraints

以及他們NotEquals類創建的變化:

public class NotEqual : IRouteConstraint 
{ 
    private IEnumerable<string> Matches; 

    public NotEqual(IEnumerable<string> matches) 
    { 
     Matches = matches; 
    } 

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     bool output = true; 
     var name = values[parameterName].ToString(); 
     foreach (var match in Matches) 
     { 
      if (name.Contains(match)) 
      { 
       output = false; 
       break; 
      } 
     } 
     return output; 
    } 
} 

,改變了第三路線是:

 config.Routes.MapHttpRoute(
      name: "api", 
      routeTemplate: "api/{controller}/{id}", 
      defaults: new { id = RouteParameter.Optional }, 
      constraints: new { controller = new NotEqual(new List<string> { "Schemas", "Wadl" }) } 
     ); 

public class NotEqual : IRouteConstraint 
{ 
    private IEnumerable<string> Matches; 

    public NotEqual(IEnumerable<string> matches) 
    { 
     Matches = matches; 
    } 

    public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) 
    { 
     bool output = true; 
     var name = values[parameterName].ToString(); 
     foreach (var match in Matches) 
     { 
      if (name.Contains(match)) 
      { 
       output = false; 
       break; 
      } 
     } 
     return output; 
    } 
} 

不行的,但它仍然爲所有三個控制器匹配

它會正常工作的一個途徑,但自動求助頁面是醜陋誤導。

如果我在Match上休息一下,它不會達到中斷點。

正則表達式約束完美,只是「一切」一個沒有工作

爲什麼是不是工作?

回答

1

第二條路線比最後一條路線更通用,因爲它在註冊ID之前註冊它會匹配它。只需將第二個移動到底部並構建應用程序即可。至於限制條件,你可以使用類似new {id = @"\d+" }的東西,但是這隻適用於你在URL中具有不同類型數據的相同格式。 api/myController/123,api/myController /我的名字。等等。

3

這是我自己的其他答案的組合:

註冊()有以下幾點:

 config.Routes.MapHttpRoute(
      name: "default", 
      routeTemplate: "api/{controller}/{id}", 
      defaults: new { id = RouteParameter.Optional }, 
      constraints: new { controller = @"^(?:(?!Wadl|Schemas).)*$" } 
     ); 

     config.MapHttpAttributeRoutes(); 
     <snip> 
     config.EnsureInitialized(); 

這給你的默認路由爲你的控制器,你可以排除他們通過添加更多|在那裏的正則表達式的語句。

然後,做定製路由,而不必擔心優先級,標記你操作是這樣的:

[Route("schemas/{typeName}")] 
    public XmlSchema GetSchema(string typeName) {} 

    [Route("schemas/{typeName}/{subType}")] 
    public XmlSchema GetSchema(string typeName, int subType) 

在這些控制器無標記方法不會有他們的路線,就好像他們是私人。

public string Test(int id) 
+0

你的約束中的正則表達式非常方便,並解決了我遇到的一個問題,謝謝。它應該是正確的接受答案,因爲接受的答案實際上並沒有解決確切的問題。 – 2015-02-13 15:09:46

相關問題