簡體   English   中英

使用ASP.NET WebApi,如何使路由排除一組控制器?

[英]Using ASP.NET WebApi, how can I make a route exclude a set of controllers?

我已經創建了兩個用於導出類型模式和wadl的控制器,其他所有內容都屬於api

因此,我創建了三個路由,兩個用於特殊控制器(Schema和Wadl),一個用於“其他所有東西”:

        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休息一下,它不會達到斷點。

正則表達式約束完美運行,只是“其他”約束不起作用

為什么這樣不起作用?

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

在Register()中具有以下內容:

        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)

第二條路由比最后一條更通用,因為它在與id匹配的一條之前注冊。 只需將第二個移動到底部並構建您的應用程序即可。 至於約束,您可以使用諸如new {id = @"\\d+" }但這僅在您具有相同格式且URL中數據類型不同的情況下才有效,例如api / myController / 123,api / myController / my Name 。 等等

老實說,如果可以的話,您應該使用AttributeRouting它在代碼中更加清晰,對於項目新手來說,更容易看到什么路線在起作用。

http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM