ASP.NET Web API 2'de Öznitelik YönlendirmeAttribute Routing in ASP.NET Web API 2

Mike Wasson tarafındanby Mike Wasson

Yönlendirme, Web API'nin bir EYLEMle URI ile eşleştiğinin şeklidir.Routing is how Web API matches a URI to an action. Web API 2, öznitelik yönlendirmeadı verilen yeni bir yönlendirme türünü destekler.Web API 2 supports a new type of routing, called attribute routing. Adından da anlaşılacağı gibi, öznitelik yönlendirme yolları tanımlamak için öznitelikleri kullanır.As the name implies, attribute routing uses attributes to define routes. Öznitelik yönlendirme, web API'nizdeki URI'ler üzerinde daha fazla denetim sağlar.Attribute routing gives you more control over the URIs in your web API. Örneğin, kaynak hiyerarşilerini açıklayan UR'leri kolayca oluşturabilirsiniz.For example, you can easily create URIs that describe hierarchies of resources.

Kongre tabanlı yönlendirme olarak adlandırılan daha önceki yönlendirme stili hala tam olarak desteklenir.The earlier style of routing, called convention-based routing, is still fully supported. Aslında, aynı projede her iki tekniği birleştirebilirsiniz.In fact, you can combine both techniques in the same project.

Bu konu öznitelik yönlendirmesini nasıl etkinleştireceklerini gösterir ve öznitelik yönlendirmesi için çeşitli seçenekleri açıklar.This topic shows how to enable attribute routing and describes the various options for attribute routing. Öznitelik yönlendirmesini kullanan uçtan uca bir öğretici için bkz.For an end-to-end tutorial that uses attribute routing, see Create a REST API with Attribute Routing in Web API 2.

Ön koşullarPrerequisites

Visual Studio 2017 Topluluk, Profesyonel veya Kurumsal sürümVisual Studio 2017 Community, Professional, or Enterprise edition

Alternatif olarak, gerekli paketleri yüklemek için NuGet Package Manager'ı kullanın.Alternatively, use NuGet Package Manager to install the necessary packages. Visual Studio'daki Araçlar menüsünden NuGet Package Manager'ıseçin, ardından Paket Yöneticisi Konsolu'nuseçin.From the Tools menu in Visual Studio, select NuGet Package Manager, then select Package Manager Console. Paket Yöneticisi Konsolu penceresine aşağıdaki komutu girin:Enter the following command in the Package Manager Console window:

Install-Package Microsoft.AspNet.WebApi.WebHost

Neden Öznitelik Yönlendirme?Why Attribute Routing?

Web API'nin ilk sürümünde kural tabanlı yönlendirme kullanılmıştır.The first release of Web API used convention-based routing. Bu yönlendirme türünde, temelde parametrelendirilmiş dizeleri olan bir veya daha fazla rota şablonu tanımlarsınız.In that type of routing, you define one or more route templates, which are basically parameterized strings. Çerçeve bir istek aldığında, uri ile rota şablonuyla eşleşir.When the framework receives a request, it matches the URI against the route template. Kongre tabanlı yönlendirme hakkında daha fazla bilgi için, ASP.NET Web API'de Yönlendirme'yebakın.For more information about convention-based routing, see Routing in ASP.NET Web API.

Kural tabanlı yönlendirmenin bir avantajı, şablonların tek bir yerde tanımlanması ve yönlendirme kurallarının tüm denetleyicilere tutarlı bir şekilde uygulanmasıdır.One advantage of convention-based routing is that templates are defined in a single place, and the routing rules are applied consistently across all controllers. Ne yazık ki, kongre tabanlı yönlendirme zor RESTful API'larda yaygın olan bazı URI desenleri desteklemek için yapar.Unfortunately, convention-based routing makes it hard to support certain URI patterns that are common in RESTful APIs. Örneğin, kaynaklar genellikle alt kaynaklar içerir: Müşterilerin siparişleri vardır, filmlerin aktörleri vardır, kitapların yazarları vardır, vb.For example, resources often contain child resources: Customers have orders, movies have actors, books have authors, and so forth. Bu ilişkileri yansıtan URI'ler oluşturmak doğaldır:It's natural to create URIs that reflect these relations:

/customers/1/orders

Uri Bu tür kural tabanlı yönlendirme kullanarak oluşturmak zordur.This type of URI is difficult to create using convention-based routing. Yapılsa da, çok sayıda denetleyiciniz veya kaynak türünüz varsa sonuçlar iyi ölçeklendirilmez.Although it can be done, the results don't scale well if you have many controllers or resource types.

Öznitelik yönlendirmesi ile, bu URI için bir rota tanımlamak için önemsiz.With attribute routing, it's trivial to define a route for this URI. Denetleyici eylemine bir öznitelik eklemeniz yeterlidir:You simply add an attribute to the controller action:

[Route("customers/{customerId}/orders")]
public IEnumerable<Order> GetOrdersByCustomer(int customerId) { ... }

Yönlendirmenin kolaylaştırdığı diğer desenler şunlardır.Here are some other patterns that attribute routing makes easy.

API sürümAPI versioning

Bu örnekte, "/api/v1/products" "/api/v2/products" daha farklı bir denetleyiciye yönlendirildirilebilir.In this example, "/api/v1/products" would be routed to a different controller than "/api/v2/products".

/api/v1/products /api/v2/products

Aşırı yüklenmiş URI segmentleriOverloaded URI segments

Bu örnekte, "1" bir sipariş numarasıdır, ancak bir koleksiyona "beklemede" eşler.In this example, "1" is an order number, but "pending" maps to a collection.

/orders/1 /orders/pending

Birden çok parametre türüMultiple parameter types

Bu örnekte, "1" bir sipariş numarasıdır, ancak "2013/06/16" bir tarih belirtir.In this example, "1" is an order number, but "2013/06/16" specifies a date.

/orders/1 /orders/2013/06/16

Öznitelik Yönlendirmesini EtkinleştirmeEnabling Attribute Routing

Öznitelik yönlendirmesini etkinleştirmek için yapılandırma sırasında MapHttpAttributeRoutes'u arayın.To enable attribute routing, call MapHttpAttributeRoutes during configuration. Bu uzantı yöntemi System.Web.Http.HttpConfigurationExtensions sınıfında tanımlanır.This extension method is defined in the System.Web.Http.HttpConfigurationExtensions class.

using System.Web.Http;

namespace WebApplication
{
    public static class WebApiConfig
    {
        public static void Register(HttpConfiguration config)
        {
            // Web API routes
            config.MapHttpAttributeRoutes();

            // Other Web API configuration not shown.
        }
    }
}

Öznitelik yönlendirme, kural tabanlı yönlendirme ile birleştirilebilir.Attribute routing can be combined with convention-based routing. Kongre tabanlı rotalar tanımlamak için MapHttpRoute yöntemini arayın.To define convention-based routes, call the MapHttpRoute method.

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        // Attribute routing.
        config.MapHttpAttributeRoutes();

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

Web API'yi yapılandırma hakkında daha fazla bilgi için bkz. ASP.NET Yapılandırma Web API 2.For more information about configuring Web API, see Configuring ASP.NET Web API 2.

Not: Web API'sinden Geçiş 1Note: Migrating From Web API 1

Web API 2'den önce, Web API proje şablonları aşağıdaki gibi kod lar oluşturmaktadır:Prior to Web API 2, the Web API project templates generated code like this:

protected void Application_Start()
{
    // WARNING - Not compatible with attribute routing.
    WebApiConfig.Register(GlobalConfiguration.Configuration);
}

Öznitelik yönlendirmesi etkinleştirilmişse, bu kod bir özel durum oluşturur.If attribute routing is enabled, this code will throw an exception. Öznitelik yönlendirmesini kullanmak üzere varolan bir Web API projesini yükseltirseniz, bu yapılandırma kodunu aşağıdakilere güncelleştirmeyi unutmayın:If you upgrade an existing Web API project to use attribute routing, make sure to update this configuration code to the following:

protected void Application_Start()
{
    // Pass a delegate to the Configure method.
    GlobalConfiguration.Configure(WebApiConfig.Register);
}

Note

Daha fazla bilgi için, web API'yi ASP.NET Barındırma ile Yapılandırma'yabakın.For more information, see Configuring Web API with ASP.NET Hosting.

Rota Öznitelikleri EklemeAdding Route Attributes

Burada bir öznitelik kullanılarak tanımlanan bir rota örneği verilmiştir:Here is an example of a route defined using an attribute:

public class OrdersController : ApiController
{
    [Route("customers/{customerId}/orders")]
    [HttpGet]
    public IEnumerable<Order> FindOrdersByCustomer(int customerId) { ... }
}

String "customers/{customerId}/orders," rota için URI şablonudur.The string "customers/{customerId}/orders" is the URI template for the route. Web API, istek URI'yi şablonla eşleştirmeye çalışır.Web API tries to match the request URI to the template. Bu örnekte, "müşteriler" ve "siparişler" gerçek segmentlerdir ve "{customerId}" değişken bir parametredir.In this example, "customers" and "orders" are literal segments, and "{customerId}" is a variable parameter. Aşağıdaki URI'ler bu şablonla eşleşir:The following URIs would match this template:

  • http://localhost/customers/1/orders
  • http://localhost/customers/bob/orders
  • http://localhost/customers/1234-5678/orders

Bu konuda daha sonra açıklanan kısıtlamalarıkullanarak eşleştirmeyi kısıtlayabilirsiniz.You can restrict the matching by using constraints, described later in this topic.

Rota şablonundaki "{customerId}" parametresinin yöntemdeki customerId parametresinin adıyla eşleştiğini unutmayın.Notice that the "{customerId}" parameter in the route template matches the name of the customerId parameter in the method. Web API denetleyici eylemini çağırdığında, rota parametrelerini bağlamaya çalışır.When Web API invokes the controller action, it tries to bind the route parameters. Örneğin, URI ise, http://example.com/customers/1/ordersWeb API eylemi customerId parametre "1" değerini bağlamaya çalışır.For example, if the URI is http://example.com/customers/1/orders, Web API tries to bind the value "1" to the customerId parameter in the action.

URI şablonunda çeşitli parametreler olabilir:A URI template can have several parameters:

[Route("customers/{customerId}/orders/{orderId}")]
public Order GetOrderByCustomer(int customerId, int orderId) { ... }

Rota özniteliği olmayan tüm denetleyici yöntemleri kural tabanlı yönlendirme kullanır.Any controller methods that do not have a route attribute use convention-based routing. Bu şekilde, aynı projede her iki yönlendirme türünü birleştirebilirsiniz.That way, you can combine both types of routing in the same project.

HTTP YöntemleriHTTP Methods

Web API ayrıca isteğin HTTP yöntemine (GET, POST, vb) dayalı eylemleri seçer.Web API also selects actions based on the HTTP method of the request (GET, POST, etc). Varsayılan olarak, Web API denetleyici yöntemi adının başlangıcı ile bir büyük/küçük harf duyarsız eşleşme arar.By default, Web API looks for a case-insensitive match with the start of the controller method name. Örneğin, adlı PutCustomers bir denetleyici yöntemi bir HTTP PUT isteğiyle eşleşir.For example, a controller method named PutCustomers matches an HTTP PUT request.

Yöntemi aşağıdaki özniteliklerle süsleyerek bu kuralı geçersiz kılabilirsiniz:You can override this convention by decorating the method with any the following attributes:

  • [HttpDelete][HttpDelete]
  • [HttpGet][HttpGet]
  • [HttpHead][HttpHead]
  • [Seçenekler][HttpOptions]
  • [HttpPatch][HttpPatch]
  • [Posta][HttpPost]
  • [HttpPut][HttpPut]

Aşağıdaki örnek, CreateBook yöntemini HTTP POST istekleriyle eşler.The following example maps the CreateBook method to HTTP POST requests.

[Route("api/books")]
[HttpPost]
public HttpResponseMessage CreateBook(Book book) { ... }

Standart olmayan yöntemler de dahil olmak üzere diğer tüm HTTP yöntemleri için, HTTP yöntemlerinin bir listesini alan AcceptVerbs özniteliğini kullanın.For all other HTTP methods, including non-standard methods, use the AcceptVerbs attribute, which takes a list of HTTP methods.

// WebDAV method
[Route("api/books")]
[AcceptVerbs("MKCOL")]
public void MakeCollection() { }

Rota ÖnekleriRoute Prefixes

Genellikle, denetleyicideki yolların tümü aynı önek ile başlar.Often, the routes in a controller all start with the same prefix. Örneğin:For example:

public class BooksController : ApiController
{
    [Route("api/books")]
    public IEnumerable<Book> GetBooks() { ... }

    [Route("api/books/{id:int}")]
    public Book GetBook(int id) { ... }

    [Route("api/books")]
    [HttpPost]
    public HttpResponseMessage CreateBook(Book book) { ... }
}

[RoutePrefix] özniteliğini kullanarak tüm denetleyici için ortak bir önek ayarlayabilirsiniz:You can set a common prefix for an entire controller by using the [RoutePrefix] attribute:

[RoutePrefix("api/books")]
public class BooksController : ApiController
{
    // GET api/books
    [Route("")]
    public IEnumerable<Book> Get() { ... }

    // GET api/books/5
    [Route("{id:int}")]
    public Book Get(int id) { ... }

    // POST api/books
    [Route("")]
    public HttpResponseMessage Post(Book book) { ... }
}

Rota önekini geçersiz kılmak için yöntem özniteliğiüzerinde bir tilde (~) kullanın:Use a tilde (~) on the method attribute to override the route prefix:

[RoutePrefix("api/books")]
public class BooksController : ApiController
{
    // GET /api/authors/1/books
    [Route("~/api/authors/{authorId:int}/books")]
    public IEnumerable<Book> GetByAuthor(int authorId) { ... }

    // ...
}

Rota öneki parametreleri içerebilir:The route prefix can include parameters:

[RoutePrefix("customers/{customerId}")]
public class OrdersController : ApiController
{
    // GET customers/1/orders
    [Route("orders")]
    public IEnumerable<Order> Get(int customerId) { ... }
}

Rota KısıtlamalarıRoute Constraints

Rota kısıtlamaları, rota şablonundaki parametrelerin nasıl eşleşip eşleşip eşleştirildiğini kısıtlamanıza izin sağlar.Route constraints let you restrict how the parameters in the route template are matched. Genel sözdizimi "{parametre:constraint}"'dur.The general syntax is "{parameter:constraint}". Örneğin:For example:

[Route("users/{id:int}")]
public User GetUserById(int id) { ... }

[Route("users/{name}")]
public User GetUserByName(string name) { ... }

Burada, ilk rota yalnızca "URI'nin" kimlik bölümü bir sondaysa seçilecektir.Here, the first route will only be selected if the "id" segment of the URI is an integer. Aksi takdirde, ikinci rota seçilir.Otherwise, the second route will be chosen.

Aşağıdaki tabloda desteklenen kısıtlamaları listeler.The following table lists the constraints that are supported.

KısıtlamaConstraint AçıklamaDescription ÖrnekExample
alfaalpha Büyük veya küçük Latin alfabesi karakterleri (a-z, A-Z) eşleşirMatches uppercase or lowercase Latin alphabet characters (a-z, A-Z) {x:alfa}{x:alpha}
boolbool Boolean değeriyle eşleşir.Matches a Boolean value. {x:bool}{x:bool}
datetimedatetime DateTime değeriyle eşleşir.Matches a DateTime value. {x:datetime}{x:datetime}
decimaldecimal Ondalık değerle eşleşir.Matches a decimal value. {x:ondalık}{x:decimal}
doubledouble 64 bit kayan nokta değeriyle eşleşir.Matches a 64-bit floating-point value. {x:çift}{x:double}
floatfloat 32 bit kayan nokta değeriyle eşleşir.Matches a 32-bit floating-point value. {x:float}{x:float}
Guıdguid GUID değeriyle eşleşir.Matches a GUID value. {x:guid}{x:guid}
intint 32 bit tamsayı değeriyle eşleşir.Matches a 32-bit integer value. {x:int}{x:int}
lengthlength Bir dize belirtilen uzunlukta veya belirli bir uzunluk aralığında eşleşir.Matches a string with the specified length or within a specified range of lengths. {x:uzunluk(6)} {x:uzunluk(1,20)}{x:length(6)} {x:length(1,20)}
longlong 64 bit tamsayı değeriyle eşleşir.Matches a 64-bit integer value. {x:uzun}{x:long}
maxmax En yüksek değere sahip bir tamsayıyla eşleşir.Matches an integer with a maximum value. {x:max(10)}{x:max(10)}
Maxlengthmaxlength Bir dize maksimum uzunlukta eşleşir.Matches a string with a maximum length. {x:maxlength(10)}{x:maxlength(10)}
minmin En az değere sahip bir tamsayıyla eşleşir.Matches an integer with a minimum value. {x:min(10)}{x:min(10)}
Minlengthminlength En az uzunlukta bir dize eşleşir.Matches a string with a minimum length. {x:minlength(10)}{x:minlength(10)}
aralıkrange Bir tamsede, çeşitli değerler içinde eşleşir.Matches an integer within a range of values. {x:aralığı(10,50)}{x:range(10,50)}
Regexregex Normal bir ifadeyle eşleşir.Matches a regular expression. {x:regex(^\d{3}-\d{3}-\d{4}$)}{x:regex(^\d{3}-\d{3}-\d{4}$)}

Min ""gibi bazı kısıtlamaların parantez içinde bağımsız değişkenler aldığına dikkat edin.Notice that some of the constraints, such as "min", take arguments in parentheses. Bir üst nokta ile ayrılmış bir parametreye birden çok kısıtlama uygulayabilirsiniz.You can apply multiple constraints to a parameter, separated by a colon.

[Route("users/{id:int:min(1)}")]
public User GetUserById(int id) { ... }

Özel Rota KısıtlamalarıCustom Route Constraints

IHttpRouteConstraint arabirimini uygulayarak özel rota kısıtlamaları oluşturabilirsiniz.You can create custom route constraints by implementing the IHttpRouteConstraint interface. Örneğin, aşağıdaki kısıtlama bir parametreyi sıfır olmayan bir tamsayı değeriyle sınırlandırmaz.For example, the following constraint restricts a parameter to a non-zero integer value.

public class NonZeroConstraint : IHttpRouteConstraint
{
    public bool Match(HttpRequestMessage request, IHttpRoute route, string parameterName, 
        IDictionary<string, object> values, HttpRouteDirection routeDirection)
    {
        object value;
        if (values.TryGetValue(parameterName, out value) && value != null)
        {
            long longValue;
            if (value is long)
            {
                longValue = (long)value;
                return longValue != 0;
            }

            string valueString = Convert.ToString(value, CultureInfo.InvariantCulture);
            if (Int64.TryParse(valueString, NumberStyles.Integer, 
                CultureInfo.InvariantCulture, out longValue))
            {
                return longValue != 0;
            }
        }
        return false;
    }
}

Aşağıdaki kod kısıtlamanın nasıl kaydedilen gösteriş olduğunu gösterir:The following code shows how to register the constraint:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        var constraintResolver = new DefaultInlineConstraintResolver();
        constraintResolver.ConstraintMap.Add("nonzero", typeof(NonZeroConstraint));

        config.MapHttpAttributeRoutes(constraintResolver);
    }
}

Artık kısıtlamaları rotalarınızda uygulayabilirsiniz:Now you can apply the constraint in your routes:

[Route("{id:nonzero}")]
public HttpResponseMessage GetNonZero(int id) { ... }

Ayrıca IInlineConstraintResolver arabirimini uygulayarak tüm DefaultInlineConstraintResolver sınıfını değiştirebilirsiniz.You can also replace the entire DefaultInlineConstraintResolver class by implementing the IInlineConstraintResolver interface. Bunu yapmak, IInlineConstraintResolver uygulamanız özellikle bunları eklmediği sürece, yerleşik kısıtlamaların tümünün yerini alacaktır.Doing so will replace all of the built-in constraints, unless your implementation of IInlineConstraintResolver specifically adds them.

İsteğe Bağlı URI Parametreleri ve Varsayılan DeğerlerOptional URI Parameters and Default Values

Rota parametresine soru işareti ekleyerek URI parametresini isteğe bağlı hale getirebilirsiniz.You can make a URI parameter optional by adding a question mark to the route parameter. Bir rota parametresi isteğe bağlıysa, yöntem parametresi için varsayılan değer tanımlamanız gerekir.If a route parameter is optional, you must define a default value for the method parameter.

public class BooksController : ApiController
{
    [Route("api/books/locale/{lcid:int?}")]
    public IEnumerable<Book> GetBooksByLocale(int lcid = 1033) { ... }
}

Bu örnekte /api/books/locale/1033 /api/books/locale ve aynı kaynağı döndürün.In this example, /api/books/locale/1033 and /api/books/locale return the same resource.

Alternatif olarak, rota şablonu içinde aşağıdaki gibi varsayılan bir değer belirtebilirsiniz:Alternatively, you can specify a default value inside the route template, as follows:

public class BooksController : ApiController
{
    [Route("api/books/locale/{lcid:int=1033}")]
    public IEnumerable<Book> GetBooksByLocale(int lcid) { ... }
}

Bu, önceki örnekle hemen hemen aynıdır, ancak varsayılan değer uygulandığında hafif bir davranış farkı vardır.This is almost the same as the previous example, but there is a slight difference of behavior when the default value is applied.

  • İlk örnekte ("{lcid:int?}"), 1033 varsayılan değeri doğrudan yöntem parametresine atanır, böylece parametre tam olarak bu değere sahip olur.In the first example ("{lcid:int?}"), the default value of 1033 is assigned directly to the method parameter, so the parameter will have this exact value.
  • İkinci örnekte ("{lcid:int=1033}"), "1033"ün varsayılan değeri model bağlama işleminden geçer.In the second example ("{lcid:int=1033}"), the default value of "1033" goes through the model-binding process. Varsayılan model bağlayıcısı "1033"ü sayısal değer 1033'e dönüştürür.The default model-binder will convert "1033" to the numeric value 1033. Ancak, farklı bir şey yapabilir özel bir model bağlayıcı, takabilirsiniz.However, you could plug in a custom model binder, which might do something different.

(Çoğu durumda, ardışık ardışık nızda özel model bağlayıcıları yoksa, iki form eşdeğer olacaktır.)(In most cases, unless you have custom model binders in your pipeline, the two forms will be equivalent.)

Rota AdlarıRoute Names

Web API'sinde her rotanın bir adı vardır.In Web API, every route has a name. Rota adları, http yanıtına bir bağlantı ekleyebilmeniz için bağlantı oluşturmak için yararlıdır.Route names are useful for generating links, so that you can include a link in an HTTP response.

Rota adını belirtmek için, öznitelik üzerinde Ad özelliğini ayarlayın.To specify the route name, set the Name property on the attribute. Aşağıdaki örnek, rota adının nasıl ayarlanır ve bağlantı oluştururken rota adının nasıl kullanılacağını gösterir.The following example shows how to set the route name, and also how to use the route name when generating a link.

public class BooksController : ApiController
{
    [Route("api/books/{id}", Name="GetBookById")]
    public BookDto GetBook(int id) 
    {
        // Implementation not shown...
    }

    [Route("api/books")]
    public HttpResponseMessage Post(Book book)
    {
        // Validate and add book to database (not shown)

        var response = Request.CreateResponse(HttpStatusCode.Created);

        // Generate a link to the new book and set the Location header in the response.
        string uri = Url.Link("GetBookById", new { id = book.BookId });
        response.Headers.Location = new Uri(uri);
        return response;
    }
}

Rota SiparişiRoute Order

Çerçeve bir URI'yi bir rotayla eşleştirmeye çalıştığında, yolları belirli bir sırada değerlendirir.When the framework tries to match a URI with a route, it evaluates the routes in a particular order. Siparişi belirtmek için, rota özniteliği üzerinde Sipariş özelliğini ayarlayın.To specify the order, set the Order property on the route attribute. Önce daha düşük değerler değerlendirilir.Lower values are evaluated first. Varsayılan sipariş değeri sıfırdır.The default order value is zero.

Toplam sıralama nın nasıl belirlendiği aşağıda açıklanmıştır:Here is how the total ordering is determined:

  1. Rota özniteliğinin Sipariş özelliğini karşılaştırın.Compare the Order property of the route attribute.

  2. Rota şablonundaki her URI bölümüne bakın.Look at each URI segment in the route template. Her kesim için aşağıdaki gibi sipariş:For each segment, order as follows:

    1. Gerçek bölümler.Literal segments.
    2. Kısıtlarla rota parametreleri.Route parameters with constraints.
    3. Kısıtlama olmadan rota parametreleri.Route parameters without constraints.
    4. Joker karakter parametresi kısıtlamaları içeren segmentler.Wildcard parameter segments with constraints.
    5. Joker karakter parametresi kısıtlama olmadan segmentler.Wildcard parameter segments without constraints.
  3. Bir kravat durumunda, rotalar rota şablonunun duyarsız bir ordinal dize karşılaştırması(OrdinalIgnoreCase)tarafından sıralanır.In the case of a tie, routes are ordered by a case-insensitive ordinal string comparison (OrdinalIgnoreCase) of the route template.

Aşağıda bir örnek vardır.Here is an example. Aşağıdaki denetleyiciyi tanımladığınızı varsayalım:Suppose you define the following controller:

[RoutePrefix("orders")]
public class OrdersController : ApiController
{
    [Route("{id:int}")] // constrained parameter
    public HttpResponseMessage Get(int id) { ... }

    [Route("details")]  // literal
    public HttpResponseMessage GetDetails() { ... }

    [Route("pending", RouteOrder = 1)]
    public HttpResponseMessage GetPending() { ... }

    [Route("{customerName}")]  // unconstrained parameter
    public HttpResponseMessage GetByCustomer(string customerName) { ... }

    [Route("{*date:datetime}")]  // wildcard
    public HttpResponseMessage Get(DateTime date) { ... }
}

Bu güzergahlar aşağıdaki gibi sıralanır.These routes are ordered as follows.

  1. siparişler/ayrıntılarorders/details
  2. siparişler/{id}orders/{id}
  3. siparişler/{customerName}orders/{customerName}
  4. siparişler/{*tarih}orders/{*date}
  5. siparişler/beklemedeorders/pending

"Ayrıntılar"ın gerçek bir kesim olduğuna ve "{id}" harfinin önünde göründüğüne, ancak Sipariş özelliği 1 olduğundan "beklemede" olarak en son göründüğüne dikkat edin.Notice that "details" is a literal segment and appears before "{id}", but "pending" appears last because the Order property is 1. (Bu örnek, "ayrıntılar" veya "beklemede" adlı müşteri olmadığını varsayar.(This example assumes there are no customers named "details" or "pending". Genel olarak, belirsiz yolları önlemek için deneyin.In general, try to avoid ambiguous routes. Bu örnekte, daha iyi GetByCustomer bir rota şablonu için "customers/{customerName}" (In this example, a better route template for GetByCustomer is "customers/{customerName}" )