ASP.NET Core'da Yönlendirme

Ryan Nowak, Kirk Larkin ve Rick Anderson tarafından

Not

Bu, bu makalenin en son sürümü değildir. Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

Önemli

Bu bilgiler, ticari olarak piyasaya sürülmeden önce önemli ölçüde değiştirilebilen bir yayın öncesi ürünle ilgilidir. Burada verilen bilgilerle ilgili olarak Microsoft açık veya zımni hiçbir garanti vermez.

Geçerli sürüm için bu makalenin .NET 8 sürümüne bakın.

Yönlendirme, gelen HTTP isteklerini eşleştirmek ve bu istekleri uygulamanın yürütülebilir uç noktalarına göndermekle sorumludur. Uç noktalar , uygulamanın yürütülebilir istek işleme kodu birimleridir. Uç noktalar uygulamada tanımlanır ve uygulama başlatıldığında yapılandırılır. Uç nokta eşleştirme işlemi, isteğin URL'sinden değerleri ayıklayabilir ve istek işleme için bu değerleri sağlayabilir. Yönlendirme, uygulamadaki uç nokta bilgilerini kullanarak uç noktalara eşleyen URL'ler de oluşturabilir.

Uygulamalar yönlendirmeyi şu şekilde yapılandırabilir:

  • Denetleyiciler
  • Razor Pages
  • SignalR
  • gRPC Hizmetleri
  • Sistem Durumu Denetimleri gibi uç nokta özellikli ara yazılım.
  • Yönlendirme ile kaydedilen temsilciler ve lambdalar.

Bu makale, ASP.NET Core yönlendirmesinin alt düzey ayrıntılarını kapsar. Yönlendirmeyi yapılandırma hakkında bilgi için:

Yönlendirmeyle ilgili temel bilgiler

Aşağıdaki kod, yönlendirmenin temel bir örneğini gösterir:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

Yukarıdaki örnek, yöntemini kullanan MapGet tek bir uç nokta içerir:

  • Kök URL'ye /bir HTTP GET isteği gönderildiğinde:
    • İstek temsilcisi yürütülür.
    • Hello World! HTTP yanıtına yazılır.
  • İstek yöntemi değilse GET veya kök URL değilse /, hiçbir yol eşleşmez ve bir HTTP 404 döndürülür.

Yönlendirme, ve UseEndpointstarafından UseRouting kaydedilen bir ara yazılım çifti kullanır:

  • UseRouting ara yazılım işlem hattına yol eşleştirmesi ekler. Bu ara yazılım, uygulamada tanımlanan uç nokta kümesine bakar ve isteğe göre en iyi eşleşmeyi seçer.
  • UseEndpoints ara yazılım işlem hattına uç nokta yürütme ekler. Seçili uç noktayla ilişkili temsilciyi çalıştırır.

Uygulamaların genellikle veya UseEndpointsaraması UseRouting gerekmez. WebApplicationBuilderve UseEndpointsile UseRouting eklenen Program.cs ara yazılımı sarmalayan bir ara yazılım işlem hattı yapılandırıyor. Ancak, uygulamalar bu yöntemleri açıkça çağırarak ve UseEndpoints çalıştırma sırasını UseRouting değiştirebilir. Örneğin, aşağıdaki kod için UseRoutingaçık bir çağrı yapar:

app.Use(async (context, next) =>
{
    // ...
    await next(context);
});

app.UseRouting();

app.MapGet("/", () => "Hello World!");

Önceki kodda:

  • çağrısı app.Use , işlem hattının başında çalışan özel bir ara yazılımı kaydeder.
  • çağrısıUseRouting, özel ara yazılımdan sonra çalıştırılacak yol eşleştirme ara yazılımını yapılandırıyor.
  • ile MapGet kaydedilen uç nokta işlem hattının sonunda çalışır.

Yukarıdaki örnekte çağrısı UseRoutingyoksa, özel ara yazılım yol eşleştirme ara yazılımından sonra çalıştırılırdı.

Not: İşlem hattının sonunda doğrudan WebApplication yürütmeye eklenen yollar.

Uç Noktalar

MapGet yöntemi bir uç nokta tanımlamak için kullanılır. Uç nokta şu şekilde olabilir:

  • URL ve HTTP yöntemiyle eşleştirilerek seçilir.
  • Temsilci çalıştırılarak yürütülür.

Uygulama tarafından eşleştirilebilen ve yürütülebilen uç noktalar içinde UseEndpointsyapılandırılır. Örneğin, MapGet, MapPostve benzer yöntemler istek temsilcilerini yönlendirme sistemine bağlar. ASP.NET Core çerçeve özelliklerini yönlendirme sistemine bağlamak için ek yöntemler kullanılabilir:

Aşağıdaki örnekte daha gelişmiş bir yol şablonuyla yönlendirme gösterilmektedir:

app.MapGet("/hello/{name:alpha}", (string name) => $"Hello {name}!");

Dize /hello/{name:alpha} bir yol şablonudur. Uç noktanın nasıl eşleşeceklerini yapılandırmak için bir yol şablonu kullanılır. Bu durumda şablon aşağıdakiyle eşleşir:

  • Gibi bir URL /hello/Docs
  • ile /hello/ başlayan ve ardından alfabetik karakter dizisi gelen herhangi bir URL yolu. :alpha yalnızca alfabetik karakterlerle eşleşen bir yol kısıtlaması uygular. Yol kısıtlamaları bu makalenin devamında açıklanmıştır.

URL yolunun ikinci kesimi: {name:alpha}

Aşağıdaki örnekte sistem durumu denetimleri ve yetkilendirme ile yönlendirme gösterilmektedir:

app.UseAuthentication();
app.UseAuthorization();

app.MapHealthChecks("/healthz").RequireAuthorization();
app.MapGet("/", () => "Hello World!");

Yukarıdaki örnekte aşağıdakiler gösterilmiştir:

  • Yetkilendirme ara yazılımı yönlendirme ile kullanılabilir.
  • Yetkilendirme davranışını yapılandırmak için uç noktalar kullanılabilir.

Çağrısı bir MapHealthChecks sistem durumu denetimi uç noktası ekler. Bu çağrıya zincirleme RequireAuthorization , uç noktaya bir yetkilendirme ilkesi ekler.

Arama UseAuthentication ve UseAuthorization kimlik doğrulama ve yetkilendirme ara yazılımını ekler. Bu ara yazılım, şunları yapabilecekleri şekilde ve UseEndpoints arasına UseRouting yerleştirilir:

  • tarafından UseRoutinghangi uç noktanın seçildiğini görün.
  • Uç noktaya göndermeden önce UseEndpoints bir yetkilendirme ilkesi uygulayın.

Uç nokta meta verileri

Yukarıdaki örnekte iki uç nokta vardır, ancak yalnızca sistem durumu denetimi uç noktasının bir yetkilendirme ilkesi eklenmiştir. İstek sistem durumu denetimi uç noktasıyla /healthzeşleşiyorsa yetkilendirme denetimi gerçekleştirilir. Bu, uç noktaların bunlara ek veri ekleyebileceğini gösterir. Bu ek veriler uç nokta meta verileri olarak adlandırılır:

  • Meta veriler yönlendirme kullanan ara yazılım tarafından işlenebilir.
  • Meta veriler herhangi bir .NET türünde olabilir.

Yönlendirme kavramları

Yönlendirme sistemi, güçlü uç nokta kavramını ekleyerek ara yazılım işlem hattının üzerine inşa eder. Uç noktalar yönlendirme, yetkilendirme ve herhangi bir sayıda ASP.NET Core sistemi açısından birbirinden ayrı olan uygulama işlevlerinin birimlerini temsil eder.

ASP.NET Temel uç nokta tanımı

ASP.NET Core uç noktası:

Aşağıdaki kod, geçerli istekle eşleşen uç noktanın nasıl alınıp denetlendiğini gösterir:

app.Use(async (context, next) =>
{
    var currentEndpoint = context.GetEndpoint();

    if (currentEndpoint is null)
    {
        await next(context);
        return;
    }

    Console.WriteLine($"Endpoint: {currentEndpoint.DisplayName}");

    if (currentEndpoint is RouteEndpoint routeEndpoint)
    {
        Console.WriteLine($"  - Route Pattern: {routeEndpoint.RoutePattern}");
    }

    foreach (var endpointMetadata in currentEndpoint.Metadata)
    {
        Console.WriteLine($"  - Metadata: {endpointMetadata}");
    }

    await next(context);
});

app.MapGet("/", () => "Inspect Endpoint.");

Uç nokta seçilirse öğesinden HttpContextalınabilir. Özellikleri incelenebilir. Uç nokta nesneleri sabittir ve oluşturulduktan sonra değiştirilemez. En yaygın uç nokta türü bir RouteEndpoint'dir. RouteEndpoint , yönlendirme sistemi tarafından seçilmesini sağlayan bilgileri içerir.

Önceki kodda, uygulama. Kullan , satır içi ara yazılımı yapılandırıyor.

Aşağıdaki kod, işlem hattında çağrılan yere app.Use bağlı olarak bir uç nokta bulunmayabileceğini gösterir:

// Location 1: before routing runs, endpoint is always null here.
app.Use(async (context, next) =>
{
    Console.WriteLine($"1. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    await next(context);
});

app.UseRouting();

// Location 2: after routing runs, endpoint will be non-null if routing found a match.
app.Use(async (context, next) =>
{
    Console.WriteLine($"2. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    await next(context);
});

// Location 3: runs when this endpoint matches
app.MapGet("/", (HttpContext context) =>
{
    Console.WriteLine($"3. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    return "Hello World!";
}).WithDisplayName("Hello");

app.UseEndpoints(_ => { });

// Location 4: runs after UseEndpoints - will only run if there was no match.
app.Use(async (context, next) =>
{
    Console.WriteLine($"4. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    await next(context);
});

Yukarıdaki örnek, bir uç noktanın seçili olup olmadığını görüntüleyen deyimler ekler Console.WriteLine . Netlik sağlamak için örnek, sağlanan / uç noktaya bir görünen ad atar.

Yukarıdaki örnek ayrıca, bu ara yazılımların işlem hattı içinde tam olarak ne zaman çalıştığını denetlemek için ve UseEndpoints çağrılarını UseRouting içerir.

Bu kodu ekranların URL'si / ile çalıştırma:

1. Endpoint: (null)
2. Endpoint: Hello
3. Endpoint: Hello

Bu kodu başka herhangi bir URL ile çalıştırmak şunu görüntüler:

1. Endpoint: (null)
2. Endpoint: (null)
4. Endpoint: (null)

Bu çıkış şunları gösterir:

  • Çağrılmadan önce UseRouting uç nokta her zaman null'tır.
  • Eşleşme bulunursa, ile UseEndpointsarasında UseRouting uç nokta null değildir.
  • Bir UseEndpoints eşleşme bulunduğunda ara yazılım terminaldir . Terminal ara yazılımı bu makalenin devamında tanımlanmıştır.
  • Yürüttkten sonra UseEndpoints ara yazılım yalnızca eşleşme bulunamadığında yürütülür.

Ara yazılım, UseRouting uç noktayı geçerli bağlama eklemek için yöntemini kullanır SetEndpoint . Ara yazılımı özel mantıkla değiştirmek UseRouting ve yine de uç noktaları kullanmanın avantajlarından yararlanmak mümkündür. Uç noktalar ara yazılım gibi alt düzey bir temel öğedir ve yönlendirme uygulamasıyla birleştirilmiş değildir. Çoğu uygulamanın özel mantıkla değiştirilmesi UseRouting gerekmez.

Ara UseEndpoints yazılım, ara yazılımla UseRouting birlikte kullanılacak şekilde tasarlanmıştır. Bir uç noktayı yürütmek için temel mantık karmaşık değildir. Uç noktayı almak ve ardından özelliğini RequestDelegate çağırmak için kullanınGetEndpoint.

Aşağıdaki kodda ara yazılımların yönlendirmeyi nasıl etkilediği veya buna nasıl tepki gösterebileceği gösterilmektedir:

app.UseHttpMethodOverride();
app.UseRouting();

app.Use(async (context, next) =>
{
    if (context.GetEndpoint()?.Metadata.GetMetadata<RequiresAuditAttribute>() is not null)
    {
        Console.WriteLine($"ACCESS TO SENSITIVE DATA AT: {DateTime.UtcNow}");
    }

    await next(context);
});

app.MapGet("/", () => "Audit isn't required.");
app.MapGet("/sensitive", () => "Audit required for sensitive data.")
    .WithMetadata(new RequiresAuditAttribute());
public class RequiresAuditAttribute : Attribute { }

Yukarıdaki örnekte iki önemli kavram gösterilmektedir:

  • Ara yazılım, yönlendirmenin üzerinde çalıştığı verileri değiştirmek için daha önce UseRouting çalışabilir.
  • Ara yazılım, uç nokta yürütülmeden önce yönlendirme sonuçlarını işlemek için ve UseEndpoints arasında UseRouting çalışabilir.
    • ile UseEndpointsarasında UseRouting çalışan ara yazılım:
      • Genellikle uç noktaları anlamak için meta verileri inceler.
      • ve tarafından UseAuthorizationUseCorsyapıldığı gibi genellikle güvenlik kararları alır.
    • Ara yazılım ve meta verilerin birleşimi, uç nokta başına ilkelerin yapılandırılmasına olanak tanır.

Yukarıdaki kod, uç nokta başına ilkeleri destekleyen özel bir ara yazılım örneğini gösterir. Ara yazılım, konsola hassas verilere erişimin denetim günlüğünü yazar. Ara yazılım, meta verilerle RequiresAuditAttribute bir uç noktayı denetleyecek şekilde yapılandırılabilir. Bu örnek, yalnızca hassas olarak işaretlenmiş uç noktaların denetlendiği bir kabul etme deseni gösterir. Bu mantığı tersten tanımlamak, örneğin güvenli olarak işaretlenmemiş her şeyi denetlemek mümkündür. Uç nokta meta veri sistemi esnektir. Bu mantık, kullanım örneğine uygun şekilde tasarlanabilir.

Yukarıdaki örnek kod, uç noktaların temel kavramlarını göstermeye yöneliktir. Örnek, üretim kullanımı için tasarlanmamıştır. Denetim günlüğü ara yazılımının daha eksiksiz bir sürümü şunları yapar:

  • Bir dosyada veya veritabanında oturum açın.
  • Kullanıcı, IP adresi, hassas uç noktanın adı ve daha fazlası gibi ayrıntıları ekleyin.

Denetim ilkesi meta verileriRequiresAuditAttribute, denetleyiciler ve SignalRgibi sınıf tabanlı çerçevelerle daha kolay kullanım için olarak Attribute tanımlanır. Koda giden yol kullanılırken:

  • Meta veriler bir oluşturucu API'siyle eklenir.
  • Sınıf tabanlı çerçeveler, uç noktaları oluştururken ilgili yöntem ve sınıftaki tüm öznitelikleri içerir.

Meta veri türleri için en iyi yöntemler bunları arabirim veya öznitelik olarak tanımlamaktır. Arabirimler ve öznitelikler kodun yeniden kullanılmasına izin verir. Meta veri sistemi esnektir ve herhangi bir sınırlama getirmez.

Terminal ara yazılımını yönlendirme ile karşılaştırma

Aşağıdaki örnekte hem terminal ara yazılımı hem de yönlendirme gösterilmektedir:

// Approach 1: Terminal Middleware.
app.Use(async (context, next) =>
{
    if (context.Request.Path == "/")
    {
        await context.Response.WriteAsync("Terminal Middleware.");
        return;
    }

    await next(context);
});

app.UseRouting();

// Approach 2: Routing.
app.MapGet("/Routing", () => "Routing.");

ile Approach 1: gösterilen ara yazılım stili, terminal ara yazılımıdır. Eşleşen bir işlem yaptığı için buna terminal ara yazılımı denir:

  • Yukarıdaki örnekteki eşleştirme işlemi ara yazılıma ve Path == "/Routing" yönlendirmeye yöneliktirPath == "/".
  • Eşleşme başarılı olduğunda ara yazılımı çağırmak next yerine bazı işlevleri yürütür ve döndürür.

Aramayı sonlandırdığından, bazı işlevler yürüttüğünden ve ardından döndürdüğünden terminal ara yazılımı olarak adlandırılır.

Aşağıdaki liste, terminal ara yazılımını yönlendirme ile karşılaştırır:

  • Her iki yaklaşım da işlem hattını sonlandırmaya olanak sağlar:
    • Ara yazılım, çağırmak yerine döndürerek işlem hattını sonlandırır next.
    • Uç noktalar her zaman terminaldir.
  • Terminal ara yazılımı, ara yazılımı işlem hattında rastgele bir yere konumlandırmaya olanak tanır:
  • Terminal ara yazılımı, ara yazılımın ne zaman eşleşeceğini belirlemek için rastgele koda izin verir:
    • Özel yol eşleştirme kodu ayrıntılı olabilir ve doğru yazılması zor olabilir.
    • Yönlendirme, tipik uygulamalar için basit çözümler sağlar. Çoğu uygulama özel yol eşleştirme kodu gerektirmez.
  • ve UseCorsgibi UseAuthorization ara yazılımlarla uç noktalar arabirimi.
    • veya ile UseAuthorizationUseCors terminal ara yazılımı kullanmak için yetkilendirme sistemiyle el ile birlikte çalışma gerekir.

nokta her ikisini de tanımlar:

  • İstekleri işlemek için bir temsilci.
  • Rastgele meta veriler koleksiyonu. Meta veriler, her uç noktaya eklenen ilkelere ve yapılandırmaya göre çapraz kesme endişeleri uygulamak için kullanılır.

Terminal ara yazılımı etkili bir araç olabilir, ancak şunları gerektirebilir:

  • Önemli miktarda kodlama ve test.
  • İstenen esneklik düzeyine ulaşmak için diğer sistemlerle el ile tümleştirme.

Terminal ara yazılımı yazmadan önce yönlendirmeyle tümleştirmeyi göz önünde bulundurun.

Map ile tümleşen veya MapWhen genellikle yönlendirme kullanan bir uç noktaya dönüştürülebilen mevcut terminal ara yazılımı. MapHealthChecks , yönlendirici yazılımı desenini gösterir:

  • üzerinde IEndpointRouteBuilderbir uzantı yöntemi yazın.
  • kullanarak CreateApplicationBuilderiç içe bir ara yazılım işlem hattı oluşturun.
  • Ara yazılımı yeni işlem hattına ekleyin. Bu durumda, UseHealthChecks.
  • Buildara yazılım işlem hattı içine .RequestDelegate
  • Yeni ara yazılım işlem hattını çağırın Map ve sağlayın.
  • uzantı yönteminden tarafından Map sağlanan oluşturucu nesnesini döndürür.

Aşağıdaki kod MapHealthChecks kullanımını gösterir:

app.UseAuthentication();
app.UseAuthorization();

app.MapHealthChecks("/healthz").RequireAuthorization();

Yukarıdaki örnek, oluşturucu nesnesini döndürmenin neden önemli olduğunu gösterir. Oluşturucu nesnesini döndürmek, uygulama geliştiricisinin uç nokta için yetkilendirme gibi ilkeleri yapılandırmasına olanak tanır. Bu örnekte sistem durumu denetimleri ara yazılımının yetkilendirme sistemiyle doğrudan tümleştirmesi yoktur.

Meta veri sistemi, terminal ara yazılımı kullanılarak genişletilebilirlik yazarlarının karşılaştığı sorunlara yanıt olarak oluşturulmuştur. Her ara yazılım için yetkilendirme sistemiyle kendi tümleştirmesini uygulamak sorunludur.

URL eşleştirme

  • Yönlendirmenin bir uç noktaya gelen istekle eşleşmesi işlemidir.
  • URL yolundaki verileri ve üst bilgileri temel alır.
  • İstekteki tüm verileri dikkate almak için genişletilebilir.

Yönlendirme ara yazılımı yürütürken, geçerli istekten bir istek özelliğine HttpContext ve yönlendirme değerleri ayarlar:Endpoint

  • HttpContext.GetEndpoint çağrısı uç noktayı alır.
  • HttpRequest.RouteValues yol değerlerinin koleksiyonunu alır.

Yönlendirme ara yazılımından sonra çalışan ara yazılım uç noktayı inceleyebilir ve işlem yapabilir. Örneğin, yetkilendirme ara yazılımı bir yetkilendirme ilkesi için uç noktanın meta veri koleksiyonunu sorgulayabilir. İstek işleme işlem hattındaki ara yazılımların tümü yürütüldükten sonra seçili uç noktanın temsilcisi çağrılır.

Uç nokta yönlendirmesindeki yönlendirme sistemi, tüm gönderme kararlarının sorumluluğundadır. Ara yazılım, seçili uç noktayı temel alan ilkeler uyguladığından aşağıdakiler önemlidir:

  • Göndermeyi veya güvenlik ilkelerinin uygulanmasını etkileyebilecek tüm karar yönlendirme sistemi içinde alınır.

Uyarı

Geriye dönük uyumluluk için, denetleyici veya Razor Sayfalar uç noktası temsilcisi yürütülürken özellikleri, RouteContext.RouteData şu ana kadar gerçekleştirilen istek işlemeye göre uygun değerlere ayarlanır.

Tür RouteContext , gelecekteki bir sürümde kullanım dışı olarak işaretlenecektir:

  • öğesine geçiş.RouteData.ValuesHttpRequest.RouteValues
  • Uç nokta meta verilerinden almak IDataTokensMetadata için geçişRouteData.DataTokens.

URL eşleştirme, yapılandırılabilir bir aşama kümesinde çalışır. Her aşamada çıkış, bir eşleşme kümesidir. Eşleşme kümesi bir sonraki aşamaya kadar daraltılabilir. Yönlendirme uygulaması, eşleşen uç noktalar için işleme sırasını garanti etmez. Tüm olası eşleşmeler aynı anda işlenir. URL eşleştirme aşamaları aşağıdaki sırada gerçekleşir. ASP.NET Core:

  1. URL yolunu, tüm eşleşmeleri toplayarak uç noktalar kümesine ve bunların yol şablonlarına göre işler.
  2. Önceki listeyi alır ve yol kısıtlamaları uygulanarak başarısız olan eşleşmeleri kaldırır.
  3. Önceki listeyi alır ve örnek kümesinde MatcherPolicy başarısız olan eşleşmeleri kaldırır.
  4. Önceki listeden EndpointSelector son kararı vermek için öğesini kullanır.

Uç nokta listesi aşağıdakilere göre önceliklendirilir:

Eşleşen tüm uç noktalar, öğesine ulaşılana EndpointSelector kadar her aşamada işlenir. EndpointSelector son aşamadır. Eşleşmeler arasından en yüksek öncelikli uç noktayı en iyi eşleşme olarak seçer. En iyi eşleşmeyle aynı önceliğe sahip başka eşleşmeler varsa, belirsiz bir eşleşme özel durumu oluşturulur.

Yol önceliği, daha yüksek önceliğe sahip daha belirli bir yol şablonuna göre hesaplanır. Örneğin, ve şablonlarını /hello/{message}göz önünde bulundurun:

  • Her ikisi de URL yolu ile eşleşer /hello.
  • /hello daha belirgindir ve bu nedenle daha yüksek önceliklidir.

Genel olarak, rota önceliği, uygulamada kullanılan URL düzenleri türleri için en iyi eşleşmeyi seçmek için iyi bir iştir. Yalnızca belirsizlikten kaçınmak için gerektiğinde kullanın Order .

Yönlendirme tarafından sağlanan genişletilebilirlik türleri nedeniyle, yönlendirme sisteminin belirsiz yolları önceden hesaplaması mümkün değildir. Yol şablonları /{message:alpha} ve /{message:int}gibi bir örneği göz önünde bulundurun:

  • Kısıtlama alpha yalnızca alfabetik karakterlerle eşleşir.
  • Kısıtlama int yalnızca sayılarla eşleşir.
  • Bu şablonlar aynı yol önceliğine sahiptir, ancak her ikisi de eşleşen tek bir URL yoktur.
  • Yönlendirme sistemi başlangıçta bir belirsizlik hatası bildirdiyse, bu geçerli kullanım örneğini engeller.

Uyarı

içindeki UseEndpoints işlemlerin sırası, bir özel durum dışında yönlendirme davranışını etkilemez. MapControllerRoute ve MapAreaRoute çağrıldıkları sırayla uç noktalarına otomatik olarak bir sipariş değeri atayın. Bu, eski yönlendirme uygulamalarıyla aynı garantileri sağlayan yönlendirme sistemi olmadan denetleyicilerin uzun süreli davranışının benzetimini oluşturur.

ASP.NET Core'da uç nokta yönlendirme:

  • Rota kavramı yoktur.
  • Sipariş garantisi sağlamaz. Tüm uç noktalar aynı anda işlenir.

Rota şablonu önceliği ve uç nokta seçim sırası

Yol şablonu önceliği , her yol şablonuna ne kadar özel olduğuna göre bir değer atayan bir sistemdir. Yol şablonu önceliği:

  • Sık karşılaşılan durumlarda uç noktaların sırasını ayarlama gereğini önler.
  • Yönlendirme davranışıyla ilgili sağduyunun beklentilerini eşleştirmeye çalışır.

Örneğin, ve /Products/{id}şablonlarını /Products/List göz önünde bulundurun. URL yolundan /Products/Listdaha iyi bir eşleşme /Products/{id} olduğunu /Products/List varsaymak mantıklı olacaktır. Sabit segmentin parametre kesiminden /List/{id}daha iyi önceliğe sahip olduğu kabul edildiğinden bu işe yarar.

Önceliğin nasıl çalıştığına ilişkin ayrıntılar, yol şablonlarının nasıl tanımlandığına göre belirlenir:

  • Daha fazla segmente sahip şablonlar daha belirgin olarak kabul edilir.
  • Değişmez metin içeren bir kesim, parametre kesiminden daha özel olarak kabul edilir.
  • Kısıtlaması olan bir parametre kesimi, olmadan birden fazla özel olarak kabul edilir.
  • Karmaşık bir kesim, kısıtlaması olan bir parametre kesimi olarak özel olarak kabul edilir.
  • Tümünü yakala parametreleri en az belirlidir. Tümünü yakalayolları hakkında önemli bilgiler için Yol şablonları bölümünde tümünü yakala bölümüne bakın.

URL oluşturma kavramları

URL oluşturma:

  • Yönlendirmenin bir yol değerleri kümesine dayalı bir URL yolu oluşturabildiği işlemdir.
  • Uç noktalar ile bunlara erişen URL'ler arasında mantıksal ayrım yapılmasını sağlar.

Uç nokta yönlendirme api'sini LinkGenerator içerir. LinkGenerator , DI'den kullanılabilen tek bir hizmettir. API, LinkGenerator yürütme isteği bağlamının dışında kullanılabilir. Mvc.IUrlHelper ve kullanan Etiket Yardımcıları, HTML Yardımcıları ve Eylem Sonuçları gibi senaryolarIUrlHelper, bağlantı oluşturma özellikleri sağlamak için API'yi dahili olarak kullanırLinkGenerator.

Bağlantı oluşturucu, adres ve adres düzenleri kavramı tarafından yedeklenmiştir. Adres düzeni, bağlantı oluşturma için dikkate alınması gereken uç noktaları belirlemenin bir yoludur. Örneğin, birçok kullanıcının denetleyicilerden aşina olduğu yol adı ve yol değerleri senaryoları ve Razor Sayfalar bir adres düzeni olarak uygulanır.

Bağlantı oluşturucu, aşağıdaki uzantı yöntemleri aracılığıyla denetleyicilere ve Razor Sayfalara bağlanabilir:

Bu yöntemlerin aşırı yüklemeleri, öğesini içeren HttpContextbağımsız değişkenleri kabul eder. Bu yöntemler işlevsel olarak Url.Action ve Url.Page eşdeğerdir, ancak ek esneklik ve seçenekler sunar.

GetPath* Yöntemler, mutlak yol içeren bir URI oluşturmaları için Url.Action ve Url.Pageile en benzerleridir. GetUri* Yöntemler her zaman bir düzen ve konak içeren mutlak bir URI oluşturur. Kabul HttpContext eden yöntemler, yürütme isteği bağlamında bir URI oluşturur. Geçersiz kılınmadıkça, yürütülen istekten ortam yolu değerleri, URL temel yolu, şema ve konak kullanılır.

LinkGenerator bir adresle çağrılır. URI oluşturma işlemi iki adımda gerçekleşir:

  1. Adres, adresle eşleşen uç noktaların listesine bağlıdır.
  2. Sağlanan değerlerle eşleşen bir yol deseni bulunana kadar her uç noktanın RoutePattern değerleri değerlendirilir. Sonuçta elde edilen çıkış, bağlantı oluşturucuya sağlanan diğer URI parçalarıyla birleştirilir ve döndürülür.

tarafından LinkGenerator sağlanan yöntemler, her tür adres için standart bağlantı oluşturma özelliklerini destekler. Bağlantı oluşturucuyu kullanmanın en kolay yolu, belirli bir adres türü için işlemler gerçekleştiren uzantı yöntemleridir:

Uzantı Yöntemi Açıklama
GetPathByAddress Sağlanan değerleri temel alan mutlak bir yola sahip bir URI oluşturur.
GetUriByAddress Sağlanan değerlere göre mutlak bir URI oluşturur.

Uyarı

Çağırma LinkGenerator yöntemlerinin aşağıdaki etkilerine dikkat edin:

  • Gelen isteklerin üst bilgisini doğrulamayan Host bir uygulama yapılandırmasında uzantı yöntemlerini dikkatli kullanınGetUri*. Gelen isteklerin Host üst bilgisi doğrulanmazsa, güvenilmeyen istek girişi bir görünüm veya sayfadaki URI'lerde istemciye geri gönderilebilir. Tüm üretim uygulamalarının, üst bilgiyi bilinen geçerli değerlerle doğrulayacak Host şekilde yapılandırmalarını öneririz.

  • veya ile MapMapWhenbirlikte ara yazılımda dikkatli kullanınLinkGenerator. Map* , bağlantı oluşturmanın çıkışını etkileyen yürütme isteğinin temel yolunu değiştirir. Tüm API'ler LinkGenerator bir temel yol belirtmeye izin verir. Bağlantı oluşturma üzerindeki etkiyi Map* geri almak için boş bir temel yol belirtin.

Ara yazılım örneği

Aşağıdaki örnekte ara yazılım, depo ürünlerini listeleyen bir eylem yöntemine bağlantı oluşturmak için API'yi kullanır LinkGenerator . Bağlantı oluşturucuyu bir sınıfa ekleyerek kullanma ve bir uygulamadaki herhangi bir sınıf için çağrısı GenerateLink yapmak mümkündür:

public class ProductsMiddleware
{
    private readonly LinkGenerator _linkGenerator;

    public ProductsMiddleware(RequestDelegate next, LinkGenerator linkGenerator) =>
        _linkGenerator = linkGenerator;

    public async Task InvokeAsync(HttpContext httpContext)
    {
        httpContext.Response.ContentType = MediaTypeNames.Text.Plain;

        var productsPath = _linkGenerator.GetPathByAction("Products", "Store");

        await httpContext.Response.WriteAsync(
            $"Go to {productsPath} to see our products.");
    }
}

Yol şablonları

içindeki {} belirteçler, yol eşleşirse bağlı olan yol parametrelerini tanımlar. Yol kesiminde birden fazla yol parametresi tanımlanabilir, ancak yol parametreleri değişmez değerle ayrılmalıdır. Örneğin:

{controller=Home}{action=Index}

geçerli bir yol değildir, çünkü ile {action}arasında {controller} değişmez değer yoktur. Yol parametreleri bir ada sahip olmalı ve ek öznitelikler belirtilmiş olabilir.

Yol parametreleri dışındaki değişmez metin (örneğin, {id}) ve yol ayırıcı / url'deki metinle eşleşmelidir. Metin eşleştirme büyük/küçük harfe duyarlı değildir ve URL'nin yolunun kod çözülen gösterimine dayanır. Sabit yol parametresi sınırlayıcısı { veya }ile eşleştirmek için, karakteri yineleyerek sınırlayıcıdan kaçın. Örneğin {{ veya }}.

Yıldız işareti * veya çift yıldız **işareti:

  • URI'nin geri kalanına bağlanmak için bir yol parametresine ön ek olarak kullanılabilir.
  • Tümünü yakala parametreleri olarak adlandırılır. Örneğin, blog/{**slug}:
    • ile başlayan ve onu izleyen herhangi bir değere sahip URI'lerle blog/ eşleşir.
    • Aşağıdaki blog/ değer, bilgi yolu değerine atanır.

Uyarı

Tümünü yakala parametresi, yönlendirmedeki bir hata nedeniyle yolları yanlış eşleştirebilir. Bu hatadan etkilenen uygulamalar aşağıdaki özelliklere sahiptir:

  • Tümünü yakala yolu, örneğin, {**slug}"
  • Tümünü yakala yolu eşleşmesi gereken isteklerle eşleşemiyor.
  • Diğer yolların kaldırılması, tümünü yakala yolunun çalışmaya başlamasını sağlar.

Bu hataya isabet eden durumlar için bkz. GitHub hataları 18677 ve 16579 .

Bu hata için bir kabul düzeltmesi .NET Core 3.1.301 SDK ve sonraki sürümlerde yer alır. Aşağıdaki kod, bu hatayı düzelten bir iç anahtar ayarlar:

public static void Main(string[] args)
{
   AppContext.SetSwitch("Microsoft.AspNetCore.Routing.UseCorrectCatchAllBehavior", 
                         true);
   CreateHostBuilder(args).Build().Run();
}
// Remaining code removed for brevity.

Tümünü yakala parametreleri de boş dizeyle eşleşebilir.

Yol ayırıcı / karakterleri de dahil olmak üzere bir URL oluşturmak için yol kullanıldığında tümünü yakala parametresi uygun karakterlerin kaçışını verir. Örneğin, yol değerlerine { path = "my/path" } sahip yol foo/{*path} oluştururfoo/my%2Fpath. Kaçış eğik çizgisine dikkat edin. Gidiş dönüş yol ayırıcı karakterleri için yol parametresi ön ekini ** kullanın. ile { path = "my/path" } yolu foo/{**path} oluştururfoo/my/path.

İsteğe bağlı dosya uzantısına sahip bir dosya adını yakalamaya çalışan URL desenlerinin dikkate alınması gereken ek noktalar vardır. Örneğin, şablonunu files/{filename}.{ext?}göz önünde bulundurun. Hem hem de filenameext değerleri mevcut olduğunda, her iki değer de doldurulur. URL'de yalnızca için filename bir değer varsa, yol eşleşir çünkü sondaki . isteğe bağlıdır. Aşağıdaki URL'ler bu yolla eşleşti:

  • /files/myFile.txt
  • /files/myFile

Yol parametrelerinde, parametre adından sonra eşittir işaretiyle (= ) ayrılmış varsayılan değer belirtilerek varsayılan değerler belirlenebilir. Örneğin, {controller=Home} için controllervarsayılan değer olarak tanımlarHome. Parametresinin URL'sinde değer yoksa varsayılan değer kullanılır. Yol parametreleri, parametre adının sonuna bir soru işareti (?) eklenerek isteğe bağlıdır. Örneğin, id?. İsteğe bağlı değerler ile varsayılan yol parametreleri arasındaki fark:

  • Varsayılan değere sahip bir yol parametresi her zaman bir değer üretir.
  • İsteğe bağlı bir parametre yalnızca istek URL'si tarafından bir değer sağlandığında bir değere sahiptir.

Yol parametreleri, URL'den bağlanan yol değeriyle eşleşmesi gereken kısıtlamalara sahip olabilir. Yol parametresi adından sonra ekleme : ve kısıtlama adı, bir yol parametresinde satır içi kısıtlama belirtir. Kısıtlama bağımsız değişkenler gerektiriyorsa, bunlar kısıtlama adından sonra parantez (...) içine alınır. Başka bir : ve kısıtlama adı eklenerek birden çok satır içi kısıtlama belirtilebilir.

Kısıtlama adı ve bağımsız değişkenleri, URL işlemede IInlineConstraintResolver kullanılacak örneğini IRouteConstraint oluşturmak için hizmete geçirilir. Örneğin, yol şablonu blog/{article:minlength(10)} bağımsız değişkeniyle 10bir minlength kısıtlama belirtir. Yol kısıtlamaları hakkında daha fazla bilgi ve çerçeve tarafından sağlanan kısıtlamaların listesi için Yol kısıtlamaları bölümüne bakın.

Rota parametrelerinde de parametre transformatörleri olabilir. Parametre transformatörleri, url'lere bağlantılar ve eşleşen eylemler ve sayfalar oluştururken parametrenin değerini dönüştürür. Kısıtlamalar gibi parametre transformatörleri de rota parametresi adından sonra bir : ve transformatör adı eklenerek bir yol parametresine satır içi olarak eklenebilir. Örneğin, yol şablonu blog/{article:slugify} bir slugify transformatör belirtir. Parametre transformatörleri hakkında daha fazla bilgi için Parametre transformatörleri bölümüne bakın.

Aşağıdaki tabloda örnek yol şablonları ve davranışları gösterilmektedir:

Rota Şablonu Örnek Eşleşen URI İstek URI'si...
hello /hello Yalnızca tek yol ile eşleşir /hello.
{Page=Home} / ile eşleşir ve ile eşleşir PageHome.
{Page=Home} /Contact ile eşleşir ve ile eşleşir PageContact.
{controller}/{action}/{id?} /Products/List Denetleyiciye ve List eyleme Products Haritalar.
{controller}/{action}/{id?} /Products/Details/123 Denetleyiciye Products Haritalar ve Details 123 olarak ayarlanmış eylemid.
{controller=Home}/{action=Index}/{id?} / Denetleyiciye ve Index yönteme Home Haritalar. id yoksayılır.
{controller=Home}/{action=Index}/{id?} /Products Denetleyiciye ve Index yönteme Products Haritalar. id yoksayılır.

Şablon kullanmak genellikle yönlendirmeye en basit yaklaşımdır. Kısıtlamalar ve varsayılanlar, yol şablonunun dışında da belirtilebilir.

Karmaşık segmentler

Karmaşık segmentler, doyumsuz olmayan bir şekilde sağdan sola sabit sınırlayıcıları eşleştirerek işlenir. Örneğin, [Route("/a{b}c{d}")] karmaşık bir kesimdir. Karmaşık segmentler, bunları başarıyla kullanmak için anlaşılması gereken belirli bir şekilde çalışır. Bu bölümdeki örnekte, karmaşık segmentlerin neden yalnızca sınırlayıcı metin parametre değerlerinin içinde görünmediğinde gerçekten iyi çalıştığı gösterilmektedir. Daha karmaşık durumlar için bir regex kullanmak ve sonra değerleri el ile ayıklamak gerekir.

Uyarı

Güvenilmeyen girişi işlemek için kullanırken System.Text.RegularExpressions bir zaman aşımı geçirin. Kötü amaçlı bir kullanıcı Hizmet Reddi saldırısına neden olacak RegularExpressionsgirişler sağlayabilir. ASP.NET Zaman aşımı kullanan RegularExpressions Core framework API'leri.

Bu, yönlendirmenin şablon /a{b}c{d} ve URL yolu /abcdile gerçekleştirdiği adımların özetidir. |, algoritmanın nasıl çalıştığını görselleştirmeye yardımcı olmak için kullanılır:

  • İlk değişmez değer, sağdan sola, şeklindedir c. Bu nedenle /abcd sağdan aranıp öğesini bulur /ab|c|d.
  • Sağdaki (d) her şey artık yol parametresiyle {d}eşleştirilir.
  • Sağdan sola doğru sonraki değişmez değer olur a. Kaldığımız /ab|c|d yerden başlayarak arandı, sonra a bulunur /|a|b|c|d.
  • Sağındaki (b) değeri artık route parametresiyle {b}eşleştirilir.
  • Kalan metin ve kalan yol şablonu olmadığından bu bir eşleşmedir.

Aşağıda, aynı şablonu /a{b}c{d} ve URL yolunu kullanan negatif bir durum örneği verilmişti /aabcd. |, algoritmanın nasıl çalıştığını görselleştirmeye yardımcı olmak için kullanılır. Bu durum aynı algoritmayla açıklanan bir eşleşme değildir:

  • İlk değişmez değer, sağdan sola, şeklindedir c. Bu nedenle /aabcd sağdan aranıp öğesini bulur /aab|c|d.
  • Sağdaki (d) her şey artık yol parametresiyle {d}eşleştirilir.
  • Sağdan sola doğru sonraki değişmez değer olur a. Kaldığımız /aab|c|d yerden başlayarak arandı, sonra a bulunur /a|a|b|c|d.
  • Sağındaki (b) değeri artık route parametresiyle {b}eşleştirilir.
  • Bu noktada kalan metin avardır, ancak algoritmada ayrıştırılacak yol şablonu tükendi, bu nedenle bu eşleşme değildir.

Eşleşen algoritma doyumsuz olmadığından:

  • Her adımda mümkün olan en küçük metin miktarıyla eşleşir.
  • Sınırlayıcı değerinin parametre değerlerinin içinde göründüğü her durumda eşleşmez.

Normal ifadeler, eşleşen davranışları üzerinde çok daha fazla denetim sağlar.

Giriş metninde regex desenini karşılayan en uzun olası eşleşmeyi bulmaya yönelik en büyük eşleştirme denemeleri olarak da bilinen doyumsuz eşleştirme. Yavaş eşleştirme olarak da bilinen doyumsuz olmayan eşleştirme, regex desenini karşılayan giriş metninde mümkün olan en kısa eşleşmeyi arar.

Özel karakterlerle yönlendirme

Özel karakterlerle yönlendirme beklenmeyen sonuçlara yol açabilir. Örneğin, aşağıdaki eylem yöntemine sahip bir denetleyici düşünün:

[HttpGet("{id?}/name")]
public async Task<ActionResult<string>> GetName(string id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null || todoItem.Name == null)
    {
        return NotFound();
    }

    return todoItem.Name;
}

string id Aşağıdaki kodlanmış değerleri içerdiğinde beklenmeyen sonuçlar oluşabilir:

ASCII Encoded
/ %2F
+

Yol parametreleri her zaman URL kodunu çözmez. Bu sorun gelecekte giderilebilir. Daha fazla bilgi için bu GitHub sorununa bakın;

Yol kısıtlamaları

Yönlendirme kısıtlamaları, gelen URL'de bir eşleşme oluştuğunda ve URL yolu yol değerlerine belirteç olarak ayarlandığında yürütülür. Yol kısıtlamaları genellikle yol şablonu aracılığıyla ilişkili yol değerini inceler ve değerin kabul edilebilir olup olmadığı konusunda doğru veya yanlış bir karar verir. Bazı yol kısıtlamaları, isteğin yönlendirilip yönlendirilemeyeceğini göz önünde bulundurmak için yol değerinin dışındaki verileri kullanır. Örneğin, HttpMethodRouteConstraint http fiiline göre bir isteği kabul edebilir veya reddedebilir. Kısıtlamalar yönlendirme isteklerinde ve bağlantı oluşturmada kullanılır.

Uyarı

Giriş doğrulaması için kısıtlamaları kullanmayın. Giriş doğrulaması için kısıtlamalar kullanılıyorsa geçersiz giriş Bulunamadı yanıtında 404 sonuçlanıyor. Geçersiz giriş, uygun bir 400 hata iletisiyle Hatalı İstek oluşturmalıdır. Yol kısıtlamaları, belirli bir yolun girişlerini doğrulamak için değil, benzer yolların belirsizliğini belirlemek için kullanılır.

Aşağıdaki tabloda örnek yol kısıtlamaları ve beklenen davranışları gösterilmektedir:

kısıtlama Örnek Örnek Eşleşmeler Notlar
int {id:int} 123456789, -123456789 Herhangi bir tamsayıyla eşleşir
bool {active:bool} true, FALSE veya falseile eşleşirtrue. Duyarlı
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm Sabit kültürdeki geçerli DateTime bir değerle eşleşir. Önceki uyarıya bakın.
decimal {price:decimal} 49.99, -1,000.01 Sabit kültürdeki geçerli decimal bir değerle eşleşir. Önceki uyarıya bakın.
double {weight:double} 1.234, -1,001.01e8 Sabit kültürdeki geçerli double bir değerle eşleşir. Önceki uyarıya bakın.
float {weight:float} 1.234, -1,001.01e8 Sabit kültürdeki geçerli float bir değerle eşleşir. Önceki uyarıya bakın.
guid {id:guid} CD2C1638-1638-72D5-1638-DEADBEEF1638 Geçerli Guid bir değerle eşleşir
long {ticks:long} 123456789, -123456789 Geçerli long bir değerle eşleşir
minlength(value) {username:minlength(4)} Rick Dize en az 4 karakter olmalıdır
maxlength(value) {filename:maxlength(8)} MyFile Dize 8 karakterden fazla olmamalıdır
length(length) {filename:length(12)} somefile.txt Dize tam olarak 12 karakter uzunluğunda olmalıdır
length(min,max) {filename:length(8,16)} somefile.txt Dize en az 8 ve en fazla 16 karakter uzunluğunda olmalıdır
min(value) {age:min(18)} 19 Tamsayı değeri en az 18 olmalıdır
max(value) {age:max(120)} 91 Tamsayı değeri en fazla 120 olmalıdır
range(min,max) {age:range(18,120)} 91 Tamsayı değeri en az 18, en fazla 120 olmalıdır
alpha {name:alpha} Rick Dize bir a-z veya daha fazla alfabetik karakterden ve büyük/küçük harfe duyarsız karakterden oluşmalıdır.
regex(expression) {ssn:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)} 123-45-6789 Dize normal ifadeyle eşleşmelidir. Normal ifade tanımlama hakkındaki ipuçlarına bakın.
required {name:required} Rick URL oluşturma sırasında parametre olmayan bir değerin mevcut olmasını zorunlu kılmak için kullanılır

Uyarı

Güvenilmeyen girişi işlemek için kullanırken System.Text.RegularExpressions bir zaman aşımı geçirin. Kötü amaçlı bir kullanıcı Hizmet Reddi saldırısına neden olacak RegularExpressionsgirişler sağlayabilir. ASP.NET Zaman aşımı kullanan RegularExpressions Core framework API'leri.

Tek bir parametreye birden çok iki nokta üst üste sınırlandırılmış kısıtlama uygulanabilir. Örneğin, aşağıdaki kısıtlama bir parametreyi 1 veya daha büyük bir tamsayı değeriyle kısıtlar:

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

Uyarı

URL'yi doğrulayan ve CLR türüne dönüştürülen yol kısıtlamaları her zaman sabit kültürü kullanır. Örneğin, CLR türüne int veya DateTimedönüştürme. Bu kısıtlamalar URL'nin yerelleştirilebilir olmadığını varsayar. Çerçeve tarafından sağlanan yol kısıtlamaları, yol değerlerinde depolanan değerleri değiştirmez. URL'den ayrıştırılan tüm yol değerleri dize olarak depolanır. Örneğin kısıtlama, float yol değerini kayan değere dönüştürmeye çalışır, ancak dönüştürülen değer yalnızca float'a dönüştürülebileceğini doğrulamak için kullanılır.

Kısıtlamalardaki normal ifadeler

Uyarı

Güvenilmeyen girişi işlemek için kullanırken System.Text.RegularExpressions bir zaman aşımı geçirin. Kötü amaçlı bir kullanıcı Hizmet Reddi saldırısına neden olacak RegularExpressionsgirişler sağlayabilir. ASP.NET Zaman aşımı kullanan RegularExpressions Core framework API'leri.

Normal ifadeler, yol kısıtlaması kullanılarak regex(...) satır içi kısıtlamalar olarak belirtilebilir. Ailedeki yöntemler, kısıtlamaların MapControllerRoute nesne değişmez değerlerini de kabul eder. Bu form kullanılırsa, dize değerleri normal ifadeler olarak yorumlanır.

Aşağıdaki kod satır içi bir regex kısıtlaması kullanır:

app.MapGet("{message:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)}",
    () => "Inline Regex Constraint Matched");

Aşağıdaki kod, bir regex kısıtlaması belirtmek için bir nesne değişmez değeri kullanır:

app.MapControllerRoute(
    name: "people",
    pattern: "people/{ssn}",
    constraints: new { ssn = "^\\d{3}-\\d{2}-\\d{4}$", },
    defaults: new { controller = "People", action = "List" });

ASP.NET Core çerçevesi normal ifade oluşturucuya ekler RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant . Bu üyelerin açıklaması için bkz RegexOptions .

Normal ifadeler, yönlendirme ve C# dili tarafından kullanılanlara benzer sınırlayıcılar ve belirteçler kullanır. Normal ifade belirteçlerinin kaçılması gerekir. Normal ifadeyi ^\d{3}-\d{2}-\d{4}$ satır içi kısıtlamada kullanmak için aşağıdakilerden birini kullanın:

Yönlendirme parametresi sınırlayıcı karakterlerini {, , [}, , ]kaçış olarak kullanmak için ifadedeki karakterleri (örneğin, {{, }}, , [[]]) iki katına çıkarır. Aşağıdaki tabloda normal bir ifade ve kaçış sürümü gösterilmektedir:

Regular expression Kaçış normal ifadesi
^\d{3}-\d{2}-\d{4}$ ^\\d{{3}}-\\d{{2}}-\\d{{4}}$
^[a-z]{2}$ ^[[a-z]]{{2}}$

Yönlendirmede kullanılan normal ifadeler genellikle karakterle ^ başlar ve dizenin başlangıç konumuyla eşleşer. İfadeler genellikle karakterle biter ve dizenin sonuyla $ eşleşer. ^ ve $ karakterleri normal ifadenin yol parametresi değerinin tamamıyla eşleşmesini sağlar. ^ ve $ karakterleri olmadan, normal ifade dizedeki alt dizelerle eşleşir ve bu genellikle istenmeyen bir durumdur. Aşağıdaki tabloda örnekler ve bunların neden eşleştikleri veya eşleşmedikleri açıklanmaktadır:

Expression String Eşleştir Yorum
[a-z]{2} merhaba Yes Alt dize eşleşmeleri
[a-z]{2} 123abc456 Yes Alt dize eşleşmeleri
[a-z]{2} Mz Yes İfadeyle eşleşir
[a-z]{2} MZ Yes Büyük/küçük harfe duyarlı değil
^[a-z]{2}$ merhaba Hayır Bkz ^ . ve $ üzeri
^[a-z]{2}$ 123abc456 Hayır Bkz ^ . ve $ üzeri

Normal ifade söz dizimi hakkında daha fazla bilgi için bkz . .NET Framework Normal İfadeleri.

Bir parametreyi bilinen bir olası değer kümesiyle sınırlamak için normal bir ifade kullanın. Örneğin, {action:regex(^(list|get|create)$)} yalnızca yol değeri listile action , getveya createile eşleşir. Kısıtlamalar sözlüğüne geçirilirse dize ^(list|get|create)$ eşdeğerdir. Bilinen kısıtlamalardan biriyle eşleşmeyen kısıtlama sözlüğünde geçirilen kısıtlamalar da normal ifadeler olarak kabul edilir. Bilinen kısıtlamalardan biriyle eşleşmeyen bir şablon içinde geçirilen kısıtlamalar normal ifadeler olarak kabul edilmemektedir.

Özel yol kısıtlamaları

Özel yol kısıtlamaları, arabirimi uygulanarak IRouteConstraint oluşturulabilir. Arabirimi, IRouteConstraint kısıtlamanın karşılanması durumunda döndüren ve false aksi halde döndüren true öğesini içerirMatch.

Özel yol kısıtlamalarına nadiren ihtiyaç duyulduğu görülür. Özel yol kısıtlaması uygulamadan önce model bağlama gibi alternatifleri göz önünde bulundurun.

ASP.NET Core Constraints klasörü, kısıtlama oluşturmaya yönelik iyi örnekler sağlar. Örneğin, GuidRouteConstraint.

Özel IRouteConstraintbir kullanmak için, yol kısıtlama türünün hizmet kapsayıcısında uygulamanınkilere ConstraintMap kaydedilmesi gerekir. A ConstraintMap , yönlendirme kısıtlama anahtarlarını bu kısıtlamaları doğrulayan uygulamalarla IRouteConstraint eşleyen bir sözlüktür. Bir uygulamanın uygulamasıConstraintMap, bir çağrının AddRouting parçası olarak veya ile builder.Services.Configure<RouteOptions>doğrudan yapılandırılarak RouteOptions güncelleştirilebilirProgram.cs. Örneğin:

builder.Services.AddRouting(options =>
    options.ConstraintMap.Add("noZeroes", typeof(NoZeroesRouteConstraint)));

Yukarıdaki kısıtlama aşağıdaki kodda uygulanır:

[ApiController]
[Route("api/[controller]")]
public class NoZeroesController : ControllerBase
{
    [HttpGet("{id:noZeroes}")]
    public IActionResult Get(string id) =>
        Content(id);
}

uygulaması NoZeroesRouteConstraint , bir yol parametresinde kullanılmasını engeller 0 :

public class NoZeroesRouteConstraint : IRouteConstraint
{
    private static readonly Regex _regex = new(
        @"^[1-9]*$",
        RegexOptions.CultureInvariant | RegexOptions.IgnoreCase,
        TimeSpan.FromMilliseconds(100));

    public bool Match(
        HttpContext? httpContext, IRouter? route, string routeKey,
        RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (!values.TryGetValue(routeKey, out var routeValue))
        {
            return false;
        }

        var routeValueString = Convert.ToString(routeValue, CultureInfo.InvariantCulture);

        if (routeValueString is null)
        {
            return false;
        }

        return _regex.IsMatch(routeValueString);
    }
}

Uyarı

Güvenilmeyen girişi işlemek için kullanırken System.Text.RegularExpressions bir zaman aşımı geçirin. Kötü amaçlı bir kullanıcı Hizmet Reddi saldırısına neden olacak RegularExpressionsgirişler sağlayabilir. ASP.NET Zaman aşımı kullanan RegularExpressions Core framework API'leri.

Yukarıdaki kod:

  • Yolun segmentinde {id} engeller0.
  • Özel kısıtlama uygulamanın temel bir örneğini sağlamak için gösterilir. Üretim uygulamasında kullanılmamalıdır.

Aşağıdaki kod, içeren bir kodun işlenmesini önlemeye yönelik daha iyi bir id0 yaklaşımdır:

[HttpGet("{id}")]
public IActionResult Get(string id)
{
    if (id.Contains('0'))
    {
        return StatusCode(StatusCodes.Status406NotAcceptable);
    }

    return Content(id);
}

Yukarıdaki kod, yaklaşıma göre aşağıdaki avantajlara NoZeroesRouteConstraint sahiptir:

  • Özel bir kısıtlama gerektirmez.
  • Yol parametresi içerdiğinde 0daha açıklayıcı bir hata döndürür.

Parametre transformatörleri

Parametre transformatörleri:

Örneğin, ile Url.Action(new { article = "MyTestArticle" }) yol deseninde blog\{article:slugify} özel slugify bir parametre transformatörü oluştururblog\my-test-article.

Aşağıdaki IOutboundParameterTransformer uygulamayı göz önünde bulundurun:

public class SlugifyParameterTransformer : IOutboundParameterTransformer
{
    public string? TransformOutbound(object? value)
    {
        if (value is null)
        {
            return null;
        }

        return Regex.Replace(
            value.ToString()!,
                "([a-z])([A-Z])",
            "$1-$2",
            RegexOptions.CultureInvariant,
            TimeSpan.FromMilliseconds(100))
            .ToLowerInvariant();
    }
}

Rota deseninde bir parametre transformatörü kullanmak için içinde kullanarak ConstraintMapProgram.csyapılandırın:

builder.Services.AddRouting(options =>
    options.ConstraintMap["slugify"] = typeof(SlugifyParameterTransformer));

ASP.NET Core çerçevesi, bir uç noktanın çözümlendiği URI'yi dönüştürmek için parametre dönüştürücülerini kullanır. Örneğin, parametre transformatörleri , area, controlleractionve pageile eşleştirmek için kullanılan yol değerlerini dönüştürür:

app.MapControllerRoute(
    name: "default",
    pattern: "{controller:slugify=Home}/{action:slugify=Index}/{id?}");

Önceki yol şablonuyla, eylem SubscriptionManagementController.GetAll URI /subscription-management/get-allile eşleştirilir. Parametre transformatörü, bağlantı oluşturmak için kullanılan yol değerlerini değiştirmez. Örneğin, Url.Action("GetAll", "SubscriptionManagement") çıkışları /subscription-management/get-all.

ASP.NET Core, oluşturulan yollar ile parametre dönüştürücülerini kullanmaya yönelik API kuralları sağlar:

URL oluşturma başvurusu

Bu bölüm, URL oluşturma tarafından uygulanan algoritma için bir başvuru içerir. Uygulamada, URL oluşturmanın en karmaşık örneklerinde denetleyiciler veya Razor Sayfalar kullanılır. Ek bilgi için bkz . denetleyicilerde yönlendirme.

URL oluşturma işlemi bir LinkGenerator.GetPathByAddress çağrısı veya benzer bir yöntemle başlar. yöntemi bir adres, yol değerleri kümesi ve isteğe bağlı olarak geçerli HttpContextistek hakkında bilgi ile sağlanır.

İlk adım, adresi kullanarak adresin türüyle eşleşen bir aday uç nokta IEndpointAddressScheme<TAddress> kümesini çözümlemektir.

Adaylar kümesi adres düzeni tarafından bulunduktan sonra, URL oluşturma işlemi başarılı olana kadar uç noktalar yinelemeli olarak sıralanır ve işlenir. URL oluşturma belirsizlikleri denetlemez, döndürülen ilk sonuç nihai sonuç olur.

Günlüğe kaydetme ile URL oluşturma sorunlarını giderme

URL oluşturma sorunlarını gidermenin ilk adımı, günlük düzeyini Microsoft.AspNetCore.Routing olarak TRACEayarlamaktır. LinkGenerator sorunları gidermek için yararlı olabilecek işlemesiyle ilgili birçok ayrıntıyı günlüğe kaydeder.

URL oluşturmayla ilgili ayrıntılar için bkz . URL oluşturma başvurusu .

Adresler

Adresler, bir çağrıyı bağlantı oluşturucusuna bir dizi aday uç noktaya bağlamak için kullanılan URL oluşturma kavramıdır.

Adresler, varsayılan olarak iki uygulamayla birlikte gelen genişletilebilir bir kavramdır:

  • Adres olarak uç nokta adını (string) kullanma:
    • MVC'nin yol adına benzer işlevler sağlar.
    • IEndpointNameMetadata Meta veri türünü kullanır.
    • Sağlanan dizeyi tüm kayıtlı uç noktaların meta verilerine karşı çözümler.
    • Birden çok uç nokta aynı adı kullanıyorsa başlangıçta bir özel durum oluşturur.
    • Denetleyiciler ve Razor Sayfalar dışında genel amaçlı kullanım için önerilir.
  • Adres olarak yol değerlerini (RouteValuesAddress) kullanma:
    • Denetleyiciler ve Razor Sayfalar eski URL oluşturma için benzer işlevler sağlar.
    • Genişletmek ve hata ayıklamak çok karmaşık.
    • , Etiket Yardımcıları, HTML Yardımcıları, Eylem Sonuçları vb. tarafından IUrlHelperkullanılan uygulamayı sağlar.

Adres düzeninin rolü, adres ve eşleşen uç noktalar arasındaki ilişkilendirmeyi rastgele ölçütlerle yapmaktır:

  • Uç nokta adı düzeni temel bir sözlük araması gerçekleştirir.
  • Yol değerleri şeması, küme algoritmasının karmaşık en iyi alt kümesine sahiptir.

Ortam değerleri ve açık değerler

Geçerli istekten yönlendirme, geçerli isteğin HttpContext.Request.RouteValuesyol değerlerine erişir. Geçerli istekle ilişkili değerler ortam değerleri olarak adlandırılır. Netlik sağlamak amacıyla belgeler, yöntemlere açık değerler olarak geçirilen yol değerlerini ifade eder.

Aşağıdaki örnekte ortam değerleri ve açık değerler gösterilmektedir. Geçerli istekten ortam değerleri ve açık değerler sağlar:

public class WidgetController : ControllerBase
{
    private readonly LinkGenerator _linkGenerator;

    public WidgetController(LinkGenerator linkGenerator) =>
        _linkGenerator = linkGenerator;

    public IActionResult Index()
    {
        var indexPath = _linkGenerator.GetPathByAction(
            HttpContext, values: new { id = 17 })!;

        return Content(indexPath);
    }

    // ...

Yukarıdaki kod:

Aşağıdaki kod yalnızca açık değerler sağlar ve ortam değerleri sağlamaz:

var subscribePath = _linkGenerator.GetPathByAction(
    "Subscribe", "Home", new { id = 17 })!;

Yukarıdaki yöntem döndürür /Home/Subscribe/17

içindeki aşağıdaki kod WidgetController döndürür /Widget/Subscribe/17:

var subscribePath = _linkGenerator.GetPathByAction(
    HttpContext, "Subscribe", null, new { id = 17 });

Aşağıdaki kod, denetleyiciyi geçerli istekteki ortam değerlerinden ve açık değerlerden sağlar:

public class GadgetController : ControllerBase
{
    public IActionResult Index() =>
        Content(Url.Action("Edit", new { id = 17 })!);
}

Önceki kodda:

  • /Gadget/Edit/17 döndürülür.
  • Url alır IUrlHelper.
  • Action bir eylem yöntemi için mutlak yola sahip bir URL oluşturur. URL belirtilen action adı ve route değerleri içerir.

Aşağıdaki kod, geçerli istekten gelen ortam değerlerini ve açık değerleri sağlar:

public class IndexModel : PageModel
{
    public void OnGet()
    {
        var editUrl = Url.Page("./Edit", new { id = 17 });

        // ...
    }
}

Yukarıdaki kod, SayfaYı Düzenle Razor aşağıdaki sayfa yönergesini içerdiğinde olarak ayarlır:url/Edit/17

@page "{id:int}"

Düzenle sayfası yol şablonunu içermiyorsa "{id:int}" , url şeklindedir /Edit?id=17.

MVC'nin IUrlHelper davranışı, burada açıklanan kurallara ek olarak bir karmaşıklık katmanı ekler:

  • IUrlHelper her zaman geçerli istekten yol değerlerini ortam değerleri olarak sağlar.
  • IUrlHelper.Action , geliştirici tarafından geçersiz kılınmadığı sürece her zaman geçerli action ve controller yol değerlerini açık değerler olarak kopyalar.
  • IUrlHelper.Page geçersiz kılınmadığı sürece geçerli page yol değerini her zaman açık bir değer olarak kopyalar.
  • IUrlHelper.Page geçersiz kılınmadığı sürece geçerli handler yol değerini null her zaman ile açık değerler olarak geçersiz kılar.

MVC kendi kurallarına uymadığından kullanıcılar genellikle ortam değerlerinin davranışsal ayrıntılarına şaşırır. Geçmiş ve uyumluluk nedenleriyle, , controller, pageve handler gibi actionbelirli yol değerlerinin kendi özel durum davranışları vardır.

tarafından LinkGenerator.GetPathByAction sağlanan eşdeğer işlevsellik ve LinkGenerator.GetPathByPage uyumluluk için bu anomalilerini IUrlHelper yineler.

URL oluşturma işlemi

Aday uç nokta kümesi bulunduktan sonra URL oluşturma algoritması:

  • Uç noktaları yinelemeli olarak işler.
  • İlk başarılı sonucu döndürür.

Bu işlemin ilk adımı, yol değeri geçersizleştirmesi olarak adlandırılır. Yol değeri geçersiz kılınması, yönlendirmenin ortam değerlerinden hangi yol değerlerinin kullanılacağına ve hangilerinin yoksayılacağına karar verdiği işlemdir. Her ortam değeri kabul edilir ve açık değerlerle birleştirilir veya yoksayılır.

Ortam değerlerinin rolü hakkında düşünmenin en iyi yolu, bazı yaygın durumlarda uygulama geliştiricilerini yazmaya kaydetmeyi denemeleridir. Geleneksel olarak ortam değerlerinin yararlı olduğu senaryolar MVC ile ilgilidir:

  • Aynı denetleyicideki başka bir eyleme bağlanırken, denetleyici adının belirtilmesi gerekmez.
  • Aynı alandaki başka bir denetleyiciye bağlanırken alan adının belirtilmesi gerekmez.
  • Aynı eylem yöntemine bağlanırken yol değerlerinin belirtilmesi gerekmez.
  • Uygulamanın başka bir bölümüne bağlanırken, uygulamanın bu bölümünde hiçbir anlamı olmayan rota değerlerini taşımak istemezsiniz.

LinkGenerator veya IUrlHelper döndüren null çağrıların nedeni genellikle yol değeri geçersizleştirmesini anlamamaktır. Bunun sorunu çözüp çözmediğini görmek için yol değerlerinden daha fazlasını açıkça belirterek yol değeri geçersizliği sorunlarını giderin.

Yol değeri geçersiz kılınması, uygulamanın URL düzeninin hiyerarşik olduğu varsayımıyla çalışır ve soldan sağa bir hiyerarşi oluşturulur. Bunun pratikte nasıl çalıştığına ilişkin sezgisel bir fikir edinmek için temel denetleyici rota şablonunu {controller}/{action}/{id?} göz önünde bulundurun. Bir değerde yapılan değişiklik, sağda görünen tüm yol değerlerini geçersiz kıldığını gösterir. Bu, hiyerarşi hakkındaki varsayımı yansıtır. Uygulamanın için idbir ortam değeri varsa ve işlem için controllerfarklı bir değer belirtir:

  • idöğesinin solunda {id?}olduğundan {controller} yeniden kullanılamaz.

Bu ilkeyi gösteren bazı örnekler:

  • Açık değerler için idbir değer içeriyorsa, için id ortam değeri yoksayılır. ve action ortam controller değerleri kullanılabilir.
  • Açık değerler için actionbir değer içeriyorsa, için action ortam değerleri yoksayılır. için controller ortam değerleri kullanılabilir. için action açık değer için ortam değerinden actionid farklıysa, değeri kullanılmaz. için action açık değer için ortam değeri actionid ile aynıysa, değeri kullanılabilir.
  • Açık değerler için controllerbir değer içeriyorsa, için controller ortam değerleri yoksayılır. için controller açık değer için ortam değerinden controlleraction farklıysa ve id değerleri kullanılmaz. için controller açık değer, için ortam değeriyle controlleraction aynıysa ve id değerleri kullanılabilir.

Bu işlem, öznitelik yollarının ve ayrılmış geleneksel yolların varlığıyla daha karmaşıktır. Yol parametrelerini kullanarak hiyerarşi belirtme gibi {controller}/{action}/{id?} denetleyici geleneksel yolları. Denetleyicilere ve Sayfalara ayrılmış geleneksel yollar ve Razor öznitelik yolları için:

  • Yol değerleri hiyerarşisi vardır.
  • Bunlar şablonda görünmez.

Bu durumlarda, URL oluşturma gerekli değerler kavramını tanımlar. Denetleyiciler ve Razor Sayfalar tarafından oluşturulan uç noktaların, yol değeri geçersiz kılınmasına izin veren gerekli değerler belirtilmiştir.

Yol değeri geçersizleştirme algoritması ayrıntılı olarak:

  • Gerekli değer adları yol parametreleriyle birleştirilir ve ardından soldan sağa işlenir.
  • Her parametre için ortam değeri ve açık değer karşılaştırılır:
    • Ortam değeri ve açık değer aynıysa işlem devam eder.
    • Ortam değeri mevcutsa ve açık değer yoksa, URL oluşturulurken ortam değeri kullanılır.
    • Ortam değeri yoksa ve açık değer ise, ortam değerini ve sonraki tüm ortam değerlerini reddedin.
    • Ortam değeri ve açık değer varsa ve iki değer farklıysa, ortam değerini ve sonraki tüm ortam değerlerini reddedin.

Bu noktada, URL oluşturma işlemi yol kısıtlamalarını değerlendirmeye hazırdır. Kabul edilen değerler kümesi, kısıtlamalara sağlanan parametre varsayılan değerleriyle birleştirilir. Kısıtlamaların tümü geçerse işlem devam eder.

Ardından, kabul edilen değerler yol şablonunu genişletmek için kullanılabilir. Yol şablonu işlenir:

  • Soldan sağa.
  • Her parametrenin yerine kabul edilen değeri vardır.
  • Aşağıdaki özel durumlarla:
    • Kabul edilen değerlerde bir değer eksikse ve parametrenin varsayılan değeri varsa, varsayılan değer kullanılır.
    • Kabul edilen değerlerde bir değer eksikse ve parametre isteğe bağlıysa işleme devam eder.
    • Eksik isteğe bağlı parametrenin sağındaki herhangi bir yol parametresinin değeri varsa, işlem başarısız olur.
    • Bitişik varsayılan değerli parametreler ve isteğe bağlı parametreler mümkün olduğunca daraltılır.

Yolun bir kesimiyle eşleşmeyen açıkça sağlanan değerler sorgu dizesine eklenir. Aşağıdaki tabloda yol şablonu {controller}/{action}/{id?}kullanılırken elde edilen sonuç gösterilmektedir.

Ortam Değerleri Açık Değerler Sonuç
controller = "Home" action = "About" /Home/About
controller = "Home" controller = "Order", action = "About" /Order/About
denetleyici = "Home", renk = "Kırmızı" action = "About" /Home/About
controller = "Home" action = "About", color = "Red" /Home/About?color=Red

İsteğe bağlı yol parametresi sırası

İsteğe bağlı yol parametreleri tüm gerekli yol parametreleri ve değişmez değerlerden sonra gelmelidir. Aşağıdaki kodda id ve name parametreleri parametresinden color sonra gelmelidir:

using Microsoft.AspNetCore.Mvc;

namespace WebApplication1.Controllers;

[Route("api/[controller]")]
public class MyController : ControllerBase
{
    // GET /api/my/red/2/joe
    // GET /api/my/red/2
    // GET /api/my
    [HttpGet("{color}/{id:int?}/{name?}")]
    public IActionResult GetByIdAndOptionalName(string color, int id = 1, string? name = null)
    {
        return Ok($"{color} {id} {name ?? ""}");
    }
}

Yol değeri geçersiz kılınmasıyla ilgili sorunlar

Aşağıdaki kod, yönlendirme tarafından desteklenmeyen bir URL oluşturma şeması örneği gösterir:

app.MapControllerRoute(
    "default",
    "{culture}/{controller=Home}/{action=Index}/{id?}");

app.MapControllerRoute(
    "blog",
    "{culture}/{**slug}",
    new { controller = "Blog", action = "ReadPost" });

Yukarıdaki kodda culture , yerelleştirme için yol parametresi kullanılır. Parametrenin culture her zaman bir ortam değeri olarak kabul edilmiş olmasını istemeniz gerekir. Ancak, gerekli değerlerin culture çalışma şekli nedeniyle parametre ortam değeri olarak kabul edilmemektedir:

  • Yol şablonunda "default" , culture yol parametresi solundadır controller, bu nedenle olarak değişir controller ve geçersiz kılmaz culture.
  • Yol şablonunda "blog" , culture yol parametresinin, gerekli değerlerde görünen sağında controllerolduğu kabul edilir.

ILE URL yollarını ayrıştırma LinkParser

sınıfı, LinkParser URL yolunu bir yol değerleri kümesine ayrıştırma desteği ekler. ParsePathByEndpointName yöntemi bir uç nokta adı ve URL yolu alır ve URL yolundan ayıklanan bir yol değerleri kümesi döndürür.

Aşağıdaki örnek denetleyicide GetProduct , eylem bir yol şablonu api/Products/{id} kullanır ve öğesinin bir Name öğesine GetProductsahiptir:

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    [HttpGet("{id}", Name = nameof(GetProduct))]
    public IActionResult GetProduct(string id)
    {
        // ...

Aynı denetleyici sınıfında, AddRelatedProduct eylem sorgu dizesi parametresi olarak sağlanabilen bir URL yolu pathToRelatedProductbekler:

[HttpPost("{id}/Related")]
public IActionResult AddRelatedProduct(
    string id, string pathToRelatedProduct, [FromServices] LinkParser linkParser)
{
    var routeValues = linkParser.ParsePathByEndpointName(
        nameof(GetProduct), pathToRelatedProduct);
    var relatedProductId = routeValues?["id"];

    // ...

Yukarıdaki örnekte, AddRelatedProduct eylem URL yolundan id yol değerini ayıklar. Örneğin, url yolu /api/Products/1relatedProductId ile değeri olarak 1ayarlanır. Bu yaklaşım, API istemcilerinin kaynaklara başvururken URL yollarını kullanmasına olanak tanır ve bu tür bir URL'nin nasıl yapılandırıldığı hakkında bilgi sahibi olmak zorunda değildir.

Uç nokta meta verilerini yapılandırma

Aşağıdaki bağlantılar, uç nokta meta verilerini yapılandırma hakkında bilgi sağlar:

RequireHost ile yollarda konak eşleştirme

RequireHost belirtilen konağı gerektiren yola bir kısıtlama uygular. RequireHost veya [Host] parametresi şu olabilir:

  • Ana bilgisayar: www.domain.com, herhangi bir bağlantı noktasıyla eşleşir www.domain.com .
  • Joker karakterli konak: *.domain.com, , subdomain.domain.comveya www.subdomain.domain.com herhangi bir bağlantı noktasında eşleşirwww.domain.com.
  • Bağlantı noktası: *:5000, 5000 numaralı bağlantı noktasını herhangi bir konakla eşleştirir.
  • Konak ve bağlantı noktası: www.domain.com:5000 veya *.domain.com:5000, konak ve bağlantı noktasıyla eşleşir.

veya [Host]kullanılarak RequireHost birden çok parametre belirtilebilir. Kısıtlama, parametrelerden herhangi biri için geçerli olan konaklarla eşleşir. Örneğin, [Host("domain.com", "*.domain.com")] , www.domain.comve subdomain.domain.comile eşleşirdomain.com.

Aşağıdaki kod, belirtilen konağın yolda gerekli olmasını sağlamak için kullanır RequireHost :

app.MapGet("/", () => "Contoso").RequireHost("contoso.com");
app.MapGet("/", () => "AdventureWorks").RequireHost("adventure-works.com");

app.MapHealthChecks("/healthz").RequireHost("*:8080");

Aşağıdaki kod, belirtilen konaklardan herhangi birini gerektirmek için denetleyicideki özniteliğini kullanır [Host] :

[Host("contoso.com", "adventure-works.com")]
public class HostsController : Controller
{
    public IActionResult Index() =>
        View();

    [Host("example.com")]
    public IActionResult Example() =>
        View();
}

[Host] Özniteliği hem denetleyiciye hem de eylem yöntemine uygulandığında:

  • Eylemdeki özniteliği kullanılır.
  • Denetleyici özniteliği yoksayılır.

Uyarı

ve RequireHostgibi HttpRequest.Host Konak üst bilgisini kullanan API, istemciler tarafından olası kimlik sahtekarlığına tabidir.

Konak ve bağlantı noktası kimlik sahtekarlığına engel olmak için aşağıdaki yaklaşımlardan birini kullanın:

Yol grupları

Uzantı yöntemi, MapGroup ortak bir ön eke sahip uç nokta gruplarını düzenlemeye yardımcı olur. Yinelenen kodu azaltır ve uç nokta meta verilerini ekleyen ve WithMetadata gibi RequireAuthorization yöntemlere tek bir çağrıyla tüm uç nokta gruplarını özelleştirmeye olanak tanır.

Örneğin, aşağıdaki kod iki benzer uç nokta grubu oluşturur:

app.MapGroup("/public/todos")
    .MapTodosApi()
    .WithTags("Public");

app.MapGroup("/private/todos")
    .MapTodosApi()
    .WithTags("Private")
    .AddEndpointFilterFactory(QueryPrivateTodos)
    .RequireAuthorization();


EndpointFilterDelegate QueryPrivateTodos(EndpointFilterFactoryContext factoryContext, EndpointFilterDelegate next)
{
    var dbContextIndex = -1;

    foreach (var argument in factoryContext.MethodInfo.GetParameters())
    {
        if (argument.ParameterType == typeof(TodoDb))
        {
            dbContextIndex = argument.Position;
            break;
        }
    }

    // Skip filter if the method doesn't have a TodoDb parameter.
    if (dbContextIndex < 0)
    {
        return next;
    }

    return async invocationContext =>
    {
        var dbContext = invocationContext.GetArgument<TodoDb>(dbContextIndex);
        dbContext.IsPrivate = true;

        try
        {
            return await next(invocationContext);
        }
        finally
        {
            // This should only be relevant if you're pooling or otherwise reusing the DbContext instance.
            dbContext.IsPrivate = false;
        }
    };
}
public static RouteGroupBuilder MapTodosApi(this RouteGroupBuilder group)
{
    group.MapGet("/", GetAllTodos);
    group.MapGet("/{id}", GetTodo);
    group.MapPost("/", CreateTodo);
    group.MapPut("/{id}", UpdateTodo);
    group.MapDelete("/{id}", DeleteTodo);

    return group;
}

Bu senaryoda, sonuçta üst bilgi 201 Created için Location göreli bir adres kullanabilirsiniz:

public static async Task<Created<Todo>> CreateTodo(Todo todo, TodoDb database)
{
    await database.AddAsync(todo);
    await database.SaveChangesAsync();

    return TypedResults.Created($"{todo.Id}", todo);
}

İlk uç nokta grubu yalnızca ön ekli /public/todos isteklerle eşleşir ve kimlik doğrulaması olmadan erişilebilir. İkinci uç nokta grubu yalnızca ön ekli isteklerle /private/todos eşleşir ve kimlik doğrulaması gerektirir.

QueryPrivateTodosUç nokta filtresi fabrikası, özel todo verilerine erişmeye ve bunları depolamaya izin vermek için yol işleyicisinin TodoDb parametrelerini değiştiren yerel bir işlevdir.

Yol grupları, yol parametreleri ve kısıtlamalarıyla iç içe grupları ve karmaşık ön ek desenlerini de destekler. Aşağıdaki örnekte, gruba eşlenen user ve yol işleyicisi dış grup ön eklerinde tanımlanan ve {group} yol parametrelerini yakalayabilir{org}.

Ön ek de boş olabilir. Bu, yol desenini değiştirmeden bir uç nokta grubuna uç nokta meta verileri veya filtreleri eklemek için yararlı olabilir.

var all = app.MapGroup("").WithOpenApi();
var org = all.MapGroup("{org}");
var user = org.MapGroup("{user}");
user.MapGet("", (string org, string user) => $"{org}/{user}");

Bir gruba filtre veya meta veri eklemek, bir iç gruba veya belirli bir uç noktaya eklenmiş olabilecek ek filtreler veya meta veriler eklemeden önce bunları her uç noktaya tek tek eklemekle aynı şekilde davranır.

var outer = app.MapGroup("/outer");
var inner = outer.MapGroup("/inner");

inner.AddEndpointFilter((context, next) =>
{
    app.Logger.LogInformation("/inner group filter");
    return next(context);
});

outer.AddEndpointFilter((context, next) =>
{
    app.Logger.LogInformation("/outer group filter");
    return next(context);
});

inner.MapGet("/", () => "Hi!").AddEndpointFilter((context, next) =>
{
    app.Logger.LogInformation("MapGet filter");
    return next(context);
});

Yukarıdaki örnekte dış filtre, ikinci kez eklenmiş olsa bile gelen isteği iç filtreden önce günlüğe kaydeder. Filtreler farklı gruplara uygulandığından, birbirlerine göre eklendikleri sıra önemli değildir. Sipariş filtrelerinin eklenmesi, aynı gruba veya belirli bir uç noktaya uygulandığında önemlidir.

için bir istek /outer/inner/ aşağıdakileri günlüğe kaydeder:

/outer group filter
/inner group filter
MapGet filter

Yönlendirme için performans kılavuzu

Bir uygulamada performans sorunları olduğunda, yönlendirme genellikle sorun olarak şüphelenilir. Yönlendirmenin nedeni, denetleyiciler ve Razor Sayfalar gibi çerçevelerin günlüğe kaydetme iletilerinde çerçeve içinde harcanan süreyi raporlamasıdır. Denetleyiciler tarafından bildirilen süre ile isteğin toplam süresi arasında önemli bir fark olduğunda:

  • Geliştiriciler, sorunun kaynağı olarak uygulama kodlarını ortadan kaldırır.
  • Bunun nedeninin yönlendirme olduğunu varsaymak yaygın bir durumdur.

Yönlendirme, binlerce uç nokta kullanılarak performans testi yapılır. Tipik bir uygulamanın yalnızca çok büyük olmasıyla bir performans sorunuyla karşılaşma olasılığı düşüktür. Yavaş yönlendirme performansının en yaygın kök nedeni genellikle kötü davranan bir özel ara yazılımdır.

Aşağıdaki kod örneği, gecikme kaynağını daraltmayla ilgili temel bir tekniği gösterir:

var logger = app.Services.GetRequiredService<ILogger<Program>>();

app.Use(async (context, next) =>
{
    var stopwatch = Stopwatch.StartNew();
    await next(context);
    stopwatch.Stop();

    logger.LogInformation("Time 1: {ElapsedMilliseconds}ms", stopwatch.ElapsedMilliseconds);
});

app.UseRouting();

app.Use(async (context, next) =>
{
    var stopwatch = Stopwatch.StartNew();
    await next(context);
    stopwatch.Stop();

    logger.LogInformation("Time 2: {ElapsedMilliseconds}ms", stopwatch.ElapsedMilliseconds);
});

app.UseAuthorization();

app.Use(async (context, next) =>
{
    var stopwatch = Stopwatch.StartNew();
    await next(context);
    stopwatch.Stop();

    logger.LogInformation("Time 3: {ElapsedMilliseconds}ms", stopwatch.ElapsedMilliseconds);
});

app.MapGet("/", () => "Timing Test.");

Zaman yönlendirme:

  • Önceki kodda gösterilen zamanlama ara yazılımının bir kopyasıyla her ara yazılımı birbirine ekleyin.
  • Zamanlama verilerini kodla ilişkilendirmek için benzersiz bir tanımlayıcı ekleyin.

Bu, örneğin değerinden daha 10msönemli olduğunda gecikmeyi daraltmak için temel bir yoldur. Raporlardan Time 1 ara yazılım içinde harcanan UseRouting süreyi çıkarmaTime 2.

Aşağıdaki kod, önceki zamanlama koduna daha kompakt bir yaklaşım kullanır:

public sealed class AutoStopwatch : IDisposable
{
    private readonly ILogger _logger;
    private readonly string _message;
    private readonly Stopwatch _stopwatch;
    private bool _disposed;

    public AutoStopwatch(ILogger logger, string message) =>
        (_logger, _message, _stopwatch) = (logger, message, Stopwatch.StartNew());

    public void Dispose()
    {
        if (_disposed)
        {
            return;
        }

        _logger.LogInformation("{Message}: {ElapsedMilliseconds}ms",
            _message, _stopwatch.ElapsedMilliseconds);

        _disposed = true;
    }
}
var logger = app.Services.GetRequiredService<ILogger<Program>>();
var timerCount = 0;

app.Use(async (context, next) =>
{
    using (new AutoStopwatch(logger, $"Time {++timerCount}"))
    {
        await next(context);
    }
});

app.UseRouting();

app.Use(async (context, next) =>
{
    using (new AutoStopwatch(logger, $"Time {++timerCount}"))
    {
        await next(context);
    }
});

app.UseAuthorization();

app.Use(async (context, next) =>
{
    using (new AutoStopwatch(logger, $"Time {++timerCount}"))
    {
        await next(context);
    }
});

app.MapGet("/", () => "Timing Test.");

Potansiyel olarak pahalı yönlendirme özellikleri

Aşağıdaki liste, temel yol şablonlarıyla karşılaştırıldığında nispeten pahalı yönlendirme özellikleri hakkında bazı içgörüler sağlar:

  • Normal ifadeler: Karmaşık olan veya az miktarda girişle uzun süre çalışan normal ifadeler yazmak mümkündür.
  • Karmaşık segmentler ({x}-{y}-{z}):
    • Normal URL yolu kesimini ayrıştırmaktan çok daha pahalıdır.
    • Daha fazla alt dizenin ayrılmasına neden olur.
  • Zaman uyumlu veri erişimi: Birçok karmaşık uygulamanın yönlendirmesinin bir parçası olarak veritabanı erişimi vardır. zaman uyumsuz olan ve EndpointSelectorContextgibi MatcherPolicy genişletilebilirlik noktalarını kullanın.

Büyük rota tabloları için rehberlik

Varsayılan olarak ASP.NET Core, belleği CPU süresiyle takas eden bir yönlendirme algoritması kullanır. Bu, yol eşleştirme zamanının yol sayısına değil, yalnızca eşleşecek yolun uzunluğuna bağlı olması iyi bir etkiye sahiptir. Ancak, uygulamanın çok fazla sayıda yolu (binler) olduğunda ve yollarda yüksek miktarda değişken ön eki bulunduğunda, bu yaklaşım bazı durumlarda sorunlu olabilir. Örneğin, yolların yolunun erken segmentlerinde parametreleri varsa, örneğin {parameter}/some/literal.

Bir uygulamanın aşağıdakiler dışında bunun bir sorun olduğu bir durumla karşılaşmış olma olasılığı düşüktür:

  • Uygulamada bu deseni kullanan çok sayıda yol vardır.
  • Uygulamada çok sayıda yol vardır.

Bir uygulamanın büyük yol tablosu sorunuyla karşılaşıp karşılaşmadığını belirleme

  • Aranacak iki belirti vardır:
    • Uygulama ilk istekte yavaş başlatılıyor.
      • Bunun gerekli olduğunu ancak yeterli olmadığını unutmayın. Yavaş uygulama başlatmaya neden olabilecekden çok daha fazla yol dışı sorun vardır. Uygulamanın bu durumla karşılaştığını doğru bir şekilde belirlemek için aşağıdaki koşulu denetleyin.
    • Uygulama, başlatma sırasında çok fazla bellek tüketir ve bellek dökümü çok sayıda Microsoft.AspNetCore.Routing.Matching.DfaNode örnek gösterir.

Bu sorunu giderme

Bu senaryoya büyük ölçüde iyileştiren yollara uygulanabilecek çeşitli teknikler ve iyileştirmeler vardır:

  • Mümkün olduğunda parametrelerinize {parameter:int}{parameter:guid}, , {parameter:regex(\\d+)}vb. yol kısıtlamaları uygulayın.
    • Bu, yönlendirme algoritmasının eşleştirme için kullanılan yapıları dahili olarak iyileştirmesini ve kullanılan belleği önemli ölçüde azaltmasını sağlar.
    • Çoğu durumda bu, kabul edilebilir bir davranışa geri dönmek için yeterli olacaktır.
  • Parametreleri şablondaki sonraki segmentlere taşımak için yolları değiştirin.
    • Bu, olası "yol" sayısını bir yol verilen uç noktayla eşleşecek şekilde azaltır.
  • Dinamik bir yol kullanın ve bir denetleyici/sayfaya eşlemeyi dinamik olarak gerçekleştirin.
    • Bu, ve MapDynamicPageRoutekullanılarak MapDynamicControllerRoute gerçekleştirilebilir.

Yönlendirmeden sonra kısa devre ara yazılımı

Yönlendirme bir uç noktayla eşleştiğinde, genellikle uç nokta mantığını çağırmadan önce ara yazılım işlem hattının geri kalanının çalıştırılmasına izin verir. Hizmetler, bilinen istekleri işlem hattının başlarında filtreleyerek kaynak kullanımını azaltabilir. Yönlendirmenin ShortCircuit uç nokta mantığını hemen çağırmasına ve ardından isteği sonlandırmasına neden olmak için uzantı yöntemini kullanın. Örneğin, belirli bir yolun kimlik doğrulaması veya CORS ara yazılımından geçmesi gerekmeyebilir. Aşağıdaki örnek, rotayla /short-circuit eşleşen kısa devre istekleri:

app.MapGet("/short-circuit", () => "Short circuiting!").ShortCircuit();

ShortCircuit(IEndpointConventionBuilder, Nullable<Int32>) yöntemi isteğe bağlı olarak bir durum kodu alabilir.

MapShortCircuit Url ön eklerinin params dizisini geçirerek aynı anda birden çok yol için kısa devre ayarlamak için yöntemini kullanın. Örneğin, tarayıcılar ve botlar genellikle ve favicon.icogibi robots.txt iyi bilinen yollar için sunucuları yoklar. Uygulamada bu dosyalar yoksa, bir kod satırı her iki yolu da yapılandırabilir:

app.MapShortCircuit(404, "robots.txt", "favicon.ico");

MapShortCircuit , IEndpointConventionBuilder konak filtreleme gibi ek yol kısıtlamalarının eklenebilmesini sağlar.

ShortCircuit ve MapShortCircuit yöntemleri, önüne UseRoutingyerleştirilen ara yazılımları etkilemez. Bu yöntemleri veya meta verileri olan [Authorize][RequireCors] uç noktalarla kullanmaya çalışmak isteklerin ile InvalidOperationExceptionbaşarısız olmasına neden olur. Bu meta veriler, veya öznitelikleri ya da [EnableCors] ya da RequireAuthorization yöntemleri tarafından RequireCors uygulanır[Authorize].

Kısa devre ara yazılımının etkisini görmek için , içinde "Microsoft" günlük kategorisini "Bilgi" appsettings.Development.jsonolarak ayarlayın:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Information",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

Aşağıdaki kodu çalıştırın:

var app = WebApplication.Create();

app.UseHttpLogging();

app.MapGet("/", () => "No short-circuiting!");
app.MapGet("/short-circuit", () => "Short circuiting!").ShortCircuit();
app.MapShortCircuit(404, "robots.txt", "favicon.ico");

app.Run();

Aşağıdaki örnek, uç nokta çalıştırılarak oluşturulan konsol günlüklerinden alınıyor / . Günlüğe kaydetme ara yazılımının çıkışını içerir:

info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
      Executing endpoint 'HTTP: GET /'
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
      Executed endpoint 'HTTP: GET /'
info: Microsoft.AspNetCore.HttpLogging.HttpLoggingMiddleware[2]
      Response:
      StatusCode: 200
      Content-Type: text/plain; charset=utf-8
      Date: Wed, 03 May 2023 21:05:59 GMT
      Server: Kestrel
      Alt-Svc: h3=":5182"; ma=86400
      Transfer-Encoding: chunked

Aşağıdaki örnek, uç noktanın çalıştırılmasından kaynaklanır /short-circuit . Ara yazılım kısa devreli olduğundan günlüğe kaydetme ara yazılımından hiçbir şey içermez:

info: Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware[4]
      The endpoint 'HTTP: GET /short-circuit' is being executed without running additional middleware.
info: Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware[5]
      The endpoint 'HTTP: GET /short-circuit' has been executed without running additional middleware.

Kitaplık yazarları için rehberlik

Bu bölüm, yönlendirmenin üzerine inşa eden kitaplık yazarları için rehberlik içerir. Bu ayrıntılar, uygulama geliştiricilerinin yönlendirmeyi genişleten kitaplıkları ve çerçeveleri kullanarak iyi bir deneyim elde etmelerini sağlamaya yöneliktir.

Uç noktaları tanımlama

URL eşleştirmesi için yönlendirme kullanan bir çerçeve oluşturmak için, üzerinde UseEndpointsderleyen bir kullanıcı deneyimi tanımlayarak başlayın.

DO , üzerinde derleyin IEndpointRouteBuilder. Bu, kullanıcıların kafa karışıklığı olmadan diğer ASP.NET Core özellikleriyle çerçevenizi oluşturmasına olanak tanır. Her ASP.NET Core şablonu yönlendirme içerir. Yönlendirmenin kullanıcılar için mevcut ve tanıdık olduğunu varsayın.

// Your framework
app.MapMyFramework(...);

app.MapHealthChecks("/healthz");

DO, uygulayan IEndpointConventionBuilderçağrısından korumalı bir MapMyFramework(...) beton türü döndürür. Çoğu çerçeve Map... yöntemi bu deseni izler. Arabirim IEndpointConventionBuilder :

  • Meta verilerin oluşmasına izin verir.
  • Çeşitli uzantı yöntemleri tarafından hedeflenmiştir.

Kendi türünüzü bildirmeniz, oluşturucuya kendi çerçeveye özgü işlevselliğinizi eklemenize olanak tanır. Çerçeve tarafından bildirilen bir oluşturucuyu sarmalayıp çağrıları ona iletmenin bir sakıncası yok.

// Your framework
app.MapMyFramework(...)
    .RequireAuthorization()
    .WithMyFrameworkFeature(awesome: true);

app.MapHealthChecks("/healthz");

Kendi EndpointDataSourceyazınızı yazmayı göz önünde bulundurun. EndpointDataSource , bir uç nokta koleksiyonunu bildirmeye ve güncelleştirmeye yönelik alt düzey temel öğedir. EndpointDataSource , denetleyiciler ve Razor Sayfalar tarafından kullanılan güçlü bir API'dir. Daha fazla bilgi için bkz . Dinamik uç nokta yönlendirme.

Yönlendirme testlerinin temel bir güncelleştirilmemiş veri kaynağı örneği vardır.

uygulamayı GetGroupedEndpointsGÖZ ÖNÜNDE BULUNDURUN. Bu, grup kurallarını çalıştırma ve gruplandırılmış uç noktalarda son meta veriler üzerinde tam denetim sağlar. Örneğin bu, özel EndpointDataSource uygulamaların gruplara eklenen uç nokta filtrelerini çalıştırmasına olanak tanır.

Varsayılan olarak bir EndpointDataSource kaydetmeyi DENEMEYİN. Kullanıcıların çerçevenizi ' UseEndpointsye kaydetmesini gerektirin. Yönlendirmenin felsefesi, varsayılan olarak hiçbir şeyin dahil olmadığını ve uç noktaların kaydedildiği yerdir UseEndpoints .

Yönlendirmeyle tümleşik ara yazılım oluşturma

Meta veri türlerini arabirim olarak tanımlamayı GÖZ ÖNÜNDE BULUNDURUN .

DO , meta veri türlerini sınıflarda ve yöntemlerde öznitelik olarak kullanmayı mümkün hale getirir.

public interface ICoolMetadata
{
    bool IsCool { get; }
}

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CoolMetadataAttribute : Attribute, ICoolMetadata
{
    public bool IsCool => true;
}

Denetleyiciler ve Razor Sayfalar gibi çerçeveler, meta veri özniteliklerinin türlere ve yöntemlere uygulanmasını destekler. Meta veri türlerini bildirirseniz:

  • Bunları öznitelik olarak erişilebilir hale getirin.
  • Kullanıcıların çoğu öznitelikleri uygulama konusunda bilgi sahibidir.

Bir meta veri türünün arabirim olarak bildirilmesi başka bir esneklik katmanı ekler:

  • Arabirimler birleştirilebilir.
  • Geliştiriciler, birden çok ilkeyi birleştiren kendi türlerini bildirebilir.

AŞAĞıDAKI örnekte gösterildiği gibi meta verileri geçersiz kılmayı mümkün kılamaz:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class SuppressCoolMetadataAttribute : Attribute, ICoolMetadata
{
    public bool IsCool => false;
}

[CoolMetadata]
public class MyController : Controller
{
    public void MyCool() { }

    [SuppressCoolMetadata]
    public void Uncool() { }
}

Bu yönergeleri izlemenin en iyi yolu, işaretçi meta verilerini tanımlamaktan kaçınmaktır:

  • Yalnızca meta veri türünün varlığına bakmayın.
  • Meta verilerde bir özellik tanımlayın ve özelliğini denetleyin.

Meta veri koleksiyonu sıralanır ve önceliğe göre geçersiz kılmayı destekler. Denetleyiciler söz konusu olduğunda, eylem yöntemindeki meta veriler en belirgindir.

DO , ara yazılımları yönlendirme ile ve yönlendirme olmadan kullanışlı hale getirir:

app.UseAuthorization(new AuthorizationPolicy() { ... });

// Your framework
app.MapMyFramework(...).RequireAuthorization();

Bu kılavuza örnek olarak ara yazılımı göz önünde bulundurun UseAuthorization . Yetkilendirme ara yazılımı bir geri dönüş ilkesi geçirmenizi sağlar. Geri dönüş ilkesi belirtilirse her ikisi için de geçerlidir:

  • Belirtilen ilke olmayan uç noktalar.
  • Uç noktayla eşleşmeyen istekler.

Bu, yetkilendirme ara yazılımını yönlendirme bağlamı dışında kullanışlı hale getirir. Yetkilendirme ara yazılımı geleneksel ara yazılım programlama için kullanılabilir.

Tanılama hatalarını ayıklama

Ayrıntılı yönlendirme tanılama çıktısı için olarak DebugayarlayınLogging:LogLevel:Microsoft. Geliştirme ortamında, içinde günlük düzeyini appsettings.Development.jsonayarlayın:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Debug",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

Ek kaynaklar

Yönlendirme, gelen HTTP isteklerini eşleştirmek ve bu istekleri uygulamanın yürütülebilir uç noktalarına göndermekle sorumludur. Uç noktalar , uygulamanın yürütülebilir istek işleme kodu birimleridir. Uç noktalar uygulamada tanımlanır ve uygulama başlatıldığında yapılandırılır. Uç nokta eşleştirme işlemi, isteğin URL'sinden değerleri ayıklayabilir ve istek işleme için bu değerleri sağlayabilir. Yönlendirme, uygulamadaki uç nokta bilgilerini kullanarak uç noktalara eşleyen URL'ler de oluşturabilir.

Uygulamalar yönlendirmeyi şu şekilde yapılandırabilir:

  • Denetleyiciler
  • Razor Pages
  • SignalR
  • gRPC Hizmetleri
  • Sistem Durumu Denetimleri gibi uç nokta özellikli ara yazılım.
  • Yönlendirme ile kaydedilen temsilciler ve lambdalar.

Bu makale, ASP.NET Core yönlendirmesinin alt düzey ayrıntılarını kapsar. Yönlendirmeyi yapılandırma hakkında bilgi için:

Yönlendirmeyle ilgili temel bilgiler

Aşağıdaki kod, yönlendirmenin temel bir örneğini gösterir:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

Yukarıdaki örnek, yöntemini kullanan MapGet tek bir uç nokta içerir:

  • Kök URL'ye /bir HTTP GET isteği gönderildiğinde:
    • İstek temsilcisi yürütülür.
    • Hello World! HTTP yanıtına yazılır.
  • İstek yöntemi değilse GET veya kök URL değilse /, hiçbir yol eşleşmez ve bir HTTP 404 döndürülür.

Yönlendirme, ve UseEndpointstarafından UseRouting kaydedilen bir ara yazılım çifti kullanır:

  • UseRouting ara yazılım işlem hattına yol eşleştirmesi ekler. Bu ara yazılım, uygulamada tanımlanan uç nokta kümesine bakar ve isteğe göre en iyi eşleşmeyi seçer.
  • UseEndpoints ara yazılım işlem hattına uç nokta yürütme ekler. Seçili uç noktayla ilişkili temsilciyi çalıştırır.

Uygulamaların genellikle veya UseEndpointsaraması UseRouting gerekmez. WebApplicationBuilderve UseEndpointsile UseRouting eklenen Program.cs ara yazılımı sarmalayan bir ara yazılım işlem hattı yapılandırıyor. Ancak, uygulamalar bu yöntemleri açıkça çağırarak ve UseEndpoints çalıştırma sırasını UseRouting değiştirebilir. Örneğin, aşağıdaki kod için UseRoutingaçık bir çağrı yapar:

app.Use(async (context, next) =>
{
    // ...
    await next(context);
});

app.UseRouting();

app.MapGet("/", () => "Hello World!");

Önceki kodda:

  • çağrısı app.Use , işlem hattının başında çalışan özel bir ara yazılımı kaydeder.
  • çağrısıUseRouting, özel ara yazılımdan sonra çalıştırılacak yol eşleştirme ara yazılımını yapılandırıyor.
  • ile MapGet kaydedilen uç nokta işlem hattının sonunda çalışır.

Yukarıdaki örnekte çağrısı UseRoutingyoksa, özel ara yazılım yol eşleştirme ara yazılımından sonra çalıştırılırdı.

Uç Noktalar

MapGet yöntemi bir uç nokta tanımlamak için kullanılır. Uç nokta şu şekilde olabilir:

  • URL ve HTTP yöntemiyle eşleştirilerek seçilir.
  • Temsilci çalıştırılarak yürütülür.

Uygulama tarafından eşleştirilebilen ve yürütülebilen uç noktalar içinde UseEndpointsyapılandırılır. Örneğin, MapGet, MapPostve benzer yöntemler istek temsilcilerini yönlendirme sistemine bağlar. ASP.NET Core çerçeve özelliklerini yönlendirme sistemine bağlamak için ek yöntemler kullanılabilir:

Aşağıdaki örnekte daha gelişmiş bir yol şablonuyla yönlendirme gösterilmektedir:

app.MapGet("/hello/{name:alpha}", (string name) => $"Hello {name}!");

Dize /hello/{name:alpha} bir yol şablonudur. Uç noktanın nasıl eşleşeceklerini yapılandırmak için bir yol şablonu kullanılır. Bu durumda şablon aşağıdakiyle eşleşir:

  • Gibi bir URL /hello/Docs
  • ile /hello/ başlayan ve ardından alfabetik karakter dizisi gelen herhangi bir URL yolu. :alpha yalnızca alfabetik karakterlerle eşleşen bir yol kısıtlaması uygular. Yol kısıtlamaları bu makalenin devamında açıklanmıştır.

URL yolunun ikinci kesimi: {name:alpha}

Aşağıdaki örnekte sistem durumu denetimleri ve yetkilendirme ile yönlendirme gösterilmektedir:

app.UseAuthentication();
app.UseAuthorization();

app.MapHealthChecks("/healthz").RequireAuthorization();
app.MapGet("/", () => "Hello World!");

Yukarıdaki örnekte aşağıdakiler gösterilmiştir:

  • Yetkilendirme ara yazılımı yönlendirme ile kullanılabilir.
  • Yetkilendirme davranışını yapılandırmak için uç noktalar kullanılabilir.

Çağrısı bir MapHealthChecks sistem durumu denetimi uç noktası ekler. Bu çağrıya zincirleme RequireAuthorization , uç noktaya bir yetkilendirme ilkesi ekler.

Arama UseAuthentication ve UseAuthorization kimlik doğrulama ve yetkilendirme ara yazılımını ekler. Bu ara yazılım, şunları yapabilecekleri şekilde ve UseEndpoints arasına UseRouting yerleştirilir:

  • tarafından UseRoutinghangi uç noktanın seçildiğini görün.
  • Uç noktaya göndermeden önce UseEndpoints bir yetkilendirme ilkesi uygulayın.

Uç nokta meta verileri

Yukarıdaki örnekte iki uç nokta vardır, ancak yalnızca sistem durumu denetimi uç noktasının bir yetkilendirme ilkesi eklenmiştir. İstek sistem durumu denetimi uç noktasıyla /healthzeşleşiyorsa yetkilendirme denetimi gerçekleştirilir. Bu, uç noktaların bunlara ek veri ekleyebileceğini gösterir. Bu ek veriler uç nokta meta verileri olarak adlandırılır:

  • Meta veriler yönlendirme kullanan ara yazılım tarafından işlenebilir.
  • Meta veriler herhangi bir .NET türünde olabilir.

Yönlendirme kavramları

Yönlendirme sistemi, güçlü uç nokta kavramını ekleyerek ara yazılım işlem hattının üzerine inşa eder. Uç noktalar yönlendirme, yetkilendirme ve herhangi bir sayıda ASP.NET Core sistemi açısından birbirinden ayrı olan uygulama işlevlerinin birimlerini temsil eder.

ASP.NET Temel uç nokta tanımı

ASP.NET Core uç noktası:

Aşağıdaki kod, geçerli istekle eşleşen uç noktanın nasıl alınıp denetlendiğini gösterir:

app.Use(async (context, next) =>
{
    var currentEndpoint = context.GetEndpoint();

    if (currentEndpoint is null)
    {
        await next(context);
        return;
    }

    Console.WriteLine($"Endpoint: {currentEndpoint.DisplayName}");

    if (currentEndpoint is RouteEndpoint routeEndpoint)
    {
        Console.WriteLine($"  - Route Pattern: {routeEndpoint.RoutePattern}");
    }

    foreach (var endpointMetadata in currentEndpoint.Metadata)
    {
        Console.WriteLine($"  - Metadata: {endpointMetadata}");
    }

    await next(context);
});

app.MapGet("/", () => "Inspect Endpoint.");

Uç nokta seçilirse öğesinden HttpContextalınabilir. Özellikleri incelenebilir. Uç nokta nesneleri sabittir ve oluşturulduktan sonra değiştirilemez. En yaygın uç nokta türü bir RouteEndpoint'dir. RouteEndpoint , yönlendirme sistemi tarafından seçilmesini sağlayan bilgileri içerir.

Önceki kodda, uygulama. Kullan , satır içi ara yazılımı yapılandırıyor.

Aşağıdaki kod, işlem hattında çağrılan yere app.Use bağlı olarak bir uç nokta bulunmayabileceğini gösterir:

// Location 1: before routing runs, endpoint is always null here.
app.Use(async (context, next) =>
{
    Console.WriteLine($"1. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    await next(context);
});

app.UseRouting();

// Location 2: after routing runs, endpoint will be non-null if routing found a match.
app.Use(async (context, next) =>
{
    Console.WriteLine($"2. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    await next(context);
});

// Location 3: runs when this endpoint matches
app.MapGet("/", (HttpContext context) =>
{
    Console.WriteLine($"3. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    return "Hello World!";
}).WithDisplayName("Hello");

app.UseEndpoints(_ => { });

// Location 4: runs after UseEndpoints - will only run if there was no match.
app.Use(async (context, next) =>
{
    Console.WriteLine($"4. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    await next(context);
});

Yukarıdaki örnek, bir uç noktanın seçili olup olmadığını görüntüleyen deyimler ekler Console.WriteLine . Netlik sağlamak için örnek, sağlanan / uç noktaya bir görünen ad atar.

Yukarıdaki örnek ayrıca, bu ara yazılımların işlem hattı içinde tam olarak ne zaman çalıştığını denetlemek için ve UseEndpoints çağrılarını UseRouting içerir.

Bu kodu ekranların URL'si / ile çalıştırma:

1. Endpoint: (null)
2. Endpoint: Hello
3. Endpoint: Hello

Bu kodu başka herhangi bir URL ile çalıştırmak şunu görüntüler:

1. Endpoint: (null)
2. Endpoint: (null)
4. Endpoint: (null)

Bu çıkış şunları gösterir:

  • Çağrılmadan önce UseRouting uç nokta her zaman null'tır.
  • Eşleşme bulunursa, ile UseEndpointsarasında UseRouting uç nokta null değildir.
  • Bir UseEndpoints eşleşme bulunduğunda ara yazılım terminaldir . Terminal ara yazılımı bu makalenin devamında tanımlanmıştır.
  • Yürüttkten sonra UseEndpoints ara yazılım yalnızca eşleşme bulunamadığında yürütülür.

Ara yazılım, UseRouting uç noktayı geçerli bağlama eklemek için yöntemini kullanır SetEndpoint . Ara yazılımı özel mantıkla değiştirmek UseRouting ve yine de uç noktaları kullanmanın avantajlarından yararlanmak mümkündür. Uç noktalar ara yazılım gibi alt düzey bir temel öğedir ve yönlendirme uygulamasıyla birleştirilmiş değildir. Çoğu uygulamanın özel mantıkla değiştirilmesi UseRouting gerekmez.

Ara UseEndpoints yazılım, ara yazılımla UseRouting birlikte kullanılacak şekilde tasarlanmıştır. Bir uç noktayı yürütmek için temel mantık karmaşık değildir. Uç noktayı almak ve ardından özelliğini RequestDelegate çağırmak için kullanınGetEndpoint.

Aşağıdaki kodda ara yazılımların yönlendirmeyi nasıl etkilediği veya buna nasıl tepki gösterebileceği gösterilmektedir:

app.UseHttpMethodOverride();
app.UseRouting();

app.Use(async (context, next) =>
{
    if (context.GetEndpoint()?.Metadata.GetMetadata<RequiresAuditAttribute>() is not null)
    {
        Console.WriteLine($"ACCESS TO SENSITIVE DATA AT: {DateTime.UtcNow}");
    }

    await next(context);
});

app.MapGet("/", () => "Audit isn't required.");
app.MapGet("/sensitive", () => "Audit required for sensitive data.")
    .WithMetadata(new RequiresAuditAttribute());
public class RequiresAuditAttribute : Attribute { }

Yukarıdaki örnekte iki önemli kavram gösterilmektedir:

  • Ara yazılım, yönlendirmenin üzerinde çalıştığı verileri değiştirmek için daha önce UseRouting çalışabilir.
  • Ara yazılım, uç nokta yürütülmeden önce yönlendirme sonuçlarını işlemek için ve UseEndpoints arasında UseRouting çalışabilir.
    • ile UseEndpointsarasında UseRouting çalışan ara yazılım:
      • Genellikle uç noktaları anlamak için meta verileri inceler.
      • ve tarafından UseAuthorizationUseCorsyapıldığı gibi genellikle güvenlik kararları alır.
    • Ara yazılım ve meta verilerin birleşimi, uç nokta başına ilkelerin yapılandırılmasına olanak tanır.

Yukarıdaki kod, uç nokta başına ilkeleri destekleyen özel bir ara yazılım örneğini gösterir. Ara yazılım, konsola hassas verilere erişimin denetim günlüğünü yazar. Ara yazılım, meta verilerle RequiresAuditAttribute bir uç noktayı denetleyecek şekilde yapılandırılabilir. Bu örnek, yalnızca hassas olarak işaretlenmiş uç noktaların denetlendiği bir kabul etme deseni gösterir. Bu mantığı tersten tanımlamak, örneğin güvenli olarak işaretlenmemiş her şeyi denetlemek mümkündür. Uç nokta meta veri sistemi esnektir. Bu mantık, kullanım örneğine uygun şekilde tasarlanabilir.

Yukarıdaki örnek kod, uç noktaların temel kavramlarını göstermeye yöneliktir. Örnek, üretim kullanımı için tasarlanmamıştır. Denetim günlüğü ara yazılımının daha eksiksiz bir sürümü şunları yapar:

  • Bir dosyada veya veritabanında oturum açın.
  • Kullanıcı, IP adresi, hassas uç noktanın adı ve daha fazlası gibi ayrıntıları ekleyin.

Denetim ilkesi meta verileriRequiresAuditAttribute, denetleyiciler ve SignalRgibi sınıf tabanlı çerçevelerle daha kolay kullanım için olarak Attribute tanımlanır. Koda giden yol kullanılırken:

  • Meta veriler bir oluşturucu API'siyle eklenir.
  • Sınıf tabanlı çerçeveler, uç noktaları oluştururken ilgili yöntem ve sınıftaki tüm öznitelikleri içerir.

Meta veri türleri için en iyi yöntemler bunları arabirim veya öznitelik olarak tanımlamaktır. Arabirimler ve öznitelikler kodun yeniden kullanılmasına izin verir. Meta veri sistemi esnektir ve herhangi bir sınırlama getirmez.

Terminal ara yazılımını yönlendirme ile karşılaştırma

Aşağıdaki örnekte hem terminal ara yazılımı hem de yönlendirme gösterilmektedir:

// Approach 1: Terminal Middleware.
app.Use(async (context, next) =>
{
    if (context.Request.Path == "/")
    {
        await context.Response.WriteAsync("Terminal Middleware.");
        return;
    }

    await next(context);
});

app.UseRouting();

// Approach 2: Routing.
app.MapGet("/Routing", () => "Routing.");

ile Approach 1: gösterilen ara yazılım stili, terminal ara yazılımıdır. Eşleşen bir işlem yaptığı için buna terminal ara yazılımı denir:

  • Yukarıdaki örnekteki eşleştirme işlemi ara yazılıma ve Path == "/Routing" yönlendirmeye yöneliktirPath == "/".
  • Eşleşme başarılı olduğunda ara yazılımı çağırmak next yerine bazı işlevleri yürütür ve döndürür.

Aramayı sonlandırdığından, bazı işlevler yürüttüğünden ve ardından döndürdüğünden terminal ara yazılımı olarak adlandırılır.

Aşağıdaki liste, terminal ara yazılımını yönlendirme ile karşılaştırır:

  • Her iki yaklaşım da işlem hattını sonlandırmaya olanak sağlar:
    • Ara yazılım, çağırmak yerine döndürerek işlem hattını sonlandırır next.
    • Uç noktalar her zaman terminaldir.
  • Terminal ara yazılımı, ara yazılımı işlem hattında rastgele bir yere konumlandırmaya olanak tanır:
  • Terminal ara yazılımı, ara yazılımın ne zaman eşleşeceğini belirlemek için rastgele koda izin verir:
    • Özel yol eşleştirme kodu ayrıntılı olabilir ve doğru yazılması zor olabilir.
    • Yönlendirme, tipik uygulamalar için basit çözümler sağlar. Çoğu uygulama özel yol eşleştirme kodu gerektirmez.
  • ve UseCorsgibi UseAuthorization ara yazılımlarla uç noktalar arabirimi.
    • veya ile UseAuthorizationUseCors terminal ara yazılımı kullanmak için yetkilendirme sistemiyle el ile birlikte çalışma gerekir.

nokta her ikisini de tanımlar:

  • İstekleri işlemek için bir temsilci.
  • Rastgele meta veriler koleksiyonu. Meta veriler, her uç noktaya eklenen ilkelere ve yapılandırmaya göre çapraz kesme endişeleri uygulamak için kullanılır.

Terminal ara yazılımı etkili bir araç olabilir, ancak şunları gerektirebilir:

  • Önemli miktarda kodlama ve test.
  • İstenen esneklik düzeyine ulaşmak için diğer sistemlerle el ile tümleştirme.

Terminal ara yazılımı yazmadan önce yönlendirmeyle tümleştirmeyi göz önünde bulundurun.

Map ile tümleşen veya MapWhen genellikle yönlendirme kullanan bir uç noktaya dönüştürülebilen mevcut terminal ara yazılımı. MapHealthChecks , yönlendirici yazılımı desenini gösterir:

  • üzerinde IEndpointRouteBuilderbir uzantı yöntemi yazın.
  • kullanarak CreateApplicationBuilderiç içe bir ara yazılım işlem hattı oluşturun.
  • Ara yazılımı yeni işlem hattına ekleyin. Bu durumda, UseHealthChecks.
  • Buildara yazılım işlem hattı içine .RequestDelegate
  • Yeni ara yazılım işlem hattını çağırın Map ve sağlayın.
  • uzantı yönteminden tarafından Map sağlanan oluşturucu nesnesini döndürür.

Aşağıdaki kod MapHealthChecks kullanımını gösterir:

app.UseAuthentication();
app.UseAuthorization();

app.MapHealthChecks("/healthz").RequireAuthorization();

Yukarıdaki örnek, oluşturucu nesnesini döndürmenin neden önemli olduğunu gösterir. Oluşturucu nesnesini döndürmek, uygulama geliştiricisinin uç nokta için yetkilendirme gibi ilkeleri yapılandırmasına olanak tanır. Bu örnekte sistem durumu denetimleri ara yazılımının yetkilendirme sistemiyle doğrudan tümleştirmesi yoktur.

Meta veri sistemi, terminal ara yazılımı kullanılarak genişletilebilirlik yazarlarının karşılaştığı sorunlara yanıt olarak oluşturulmuştur. Her ara yazılım için yetkilendirme sistemiyle kendi tümleştirmesini uygulamak sorunludur.

URL eşleştirme

  • Yönlendirmenin bir uç noktaya gelen istekle eşleşmesi işlemidir.
  • URL yolundaki verileri ve üst bilgileri temel alır.
  • İstekteki tüm verileri dikkate almak için genişletilebilir.

Yönlendirme ara yazılımı yürütürken, geçerli istekten bir istek özelliğine HttpContext ve yönlendirme değerleri ayarlar:Endpoint

  • HttpContext.GetEndpoint çağrısı uç noktayı alır.
  • HttpRequest.RouteValues yol değerlerinin koleksiyonunu alır.

Ara yazılım , yönlendirme ara yazılımı uç noktayı inceleyip işlem gerçekleştirdikten sonra çalışır. Örneğin, yetkilendirme ara yazılımı bir yetkilendirme ilkesi için uç noktanın meta veri koleksiyonunu sorgulayabilir. İstek işleme işlem hattındaki ara yazılımların tümü yürütüldükten sonra seçili uç noktanın temsilcisi çağrılır.

Uç nokta yönlendirmesindeki yönlendirme sistemi, tüm gönderme kararlarının sorumluluğundadır. Ara yazılım, seçili uç noktayı temel alan ilkeler uyguladığından aşağıdakiler önemlidir:

  • Göndermeyi veya güvenlik ilkelerinin uygulanmasını etkileyebilecek tüm karar yönlendirme sistemi içinde alınır.

Uyarı

Geriye dönük uyumluluk için, denetleyici veya Razor Sayfalar uç noktası temsilcisi yürütülürken özellikleri, RouteContext.RouteData şu ana kadar gerçekleştirilen istek işlemeye göre uygun değerlere ayarlanır.

Tür RouteContext , gelecekteki bir sürümde kullanım dışı olarak işaretlenecektir:

  • öğesine geçiş.RouteData.ValuesHttpRequest.RouteValues
  • Uç nokta meta verilerinden almak IDataTokensMetadata için geçişRouteData.DataTokens.

URL eşleştirme, yapılandırılabilir bir aşama kümesinde çalışır. Her aşamada çıkış, bir eşleşme kümesidir. Eşleşme kümesi bir sonraki aşamaya kadar daraltılabilir. Yönlendirme uygulaması, eşleşen uç noktalar için işleme sırasını garanti etmez. Tüm olası eşleşmeler aynı anda işlenir. URL eşleştirme aşamaları aşağıdaki sırada gerçekleşir. ASP.NET Core:

  1. URL yolunu, tüm eşleşmeleri toplayarak uç noktalar kümesine ve bunların yol şablonlarına göre işler.
  2. Önceki listeyi alır ve yol kısıtlamaları uygulanarak başarısız olan eşleşmeleri kaldırır.
  3. Önceki listeyi alır ve örnek kümesinde MatcherPolicy başarısız olan eşleşmeleri kaldırır.
  4. Önceki listeden EndpointSelector son kararı vermek için öğesini kullanır.

Uç nokta listesi aşağıdakilere göre önceliklendirilir:

Eşleşen tüm uç noktalar, öğesine ulaşılana EndpointSelector kadar her aşamada işlenir. EndpointSelector son aşamadır. Eşleşmeler arasından en yüksek öncelikli uç noktayı en iyi eşleşme olarak seçer. En iyi eşleşmeyle aynı önceliğe sahip başka eşleşmeler varsa, belirsiz bir eşleşme özel durumu oluşturulur.

Yol önceliği, daha yüksek önceliğe sahip daha belirli bir yol şablonuna göre hesaplanır. Örneğin, ve şablonlarını /hello/{message}göz önünde bulundurun:

  • Her ikisi de URL yolu ile eşleşer /hello.
  • /hello daha belirgindir ve bu nedenle daha yüksek önceliklidir.

Genel olarak, rota önceliği, uygulamada kullanılan URL düzenleri türleri için en iyi eşleşmeyi seçmek için iyi bir iştir. Yalnızca belirsizlikten kaçınmak için gerektiğinde kullanın Order .

Yönlendirme tarafından sağlanan genişletilebilirlik türleri nedeniyle, yönlendirme sisteminin belirsiz yolları önceden hesaplaması mümkün değildir. Yol şablonları /{message:alpha} ve /{message:int}gibi bir örneği göz önünde bulundurun:

  • Kısıtlama alpha yalnızca alfabetik karakterlerle eşleşir.
  • Kısıtlama int yalnızca sayılarla eşleşir.
  • Bu şablonlar aynı yol önceliğine sahiptir, ancak her ikisi de eşleşen tek bir URL yoktur.
  • Yönlendirme sistemi başlangıçta bir belirsizlik hatası bildirdiyse, bu geçerli kullanım örneğini engeller.

Uyarı

içindeki UseEndpoints işlemlerin sırası, bir özel durum dışında yönlendirme davranışını etkilemez. MapControllerRoute ve MapAreaRoute çağrıldıkları sırayla uç noktalarına otomatik olarak bir sipariş değeri atayın. Bu, eski yönlendirme uygulamalarıyla aynı garantileri sağlayan yönlendirme sistemi olmadan denetleyicilerin uzun süreli davranışının benzetimini oluşturur.

ASP.NET Core'da uç nokta yönlendirme:

  • Rota kavramı yoktur.
  • Sipariş garantisi sağlamaz. Tüm uç noktalar aynı anda işlenir.

Rota şablonu önceliği ve uç nokta seçim sırası

Yol şablonu önceliği , her yol şablonuna ne kadar özel olduğuna göre bir değer atayan bir sistemdir. Yol şablonu önceliği:

  • Sık karşılaşılan durumlarda uç noktaların sırasını ayarlama gereğini önler.
  • Yönlendirme davranışıyla ilgili sağduyunun beklentilerini eşleştirmeye çalışır.

Örneğin, ve /Products/{id}şablonlarını /Products/List göz önünde bulundurun. URL yolundan /Products/Listdaha iyi bir eşleşme /Products/{id} olduğunu /Products/List varsaymak mantıklı olacaktır. Sabit segmentin parametre kesiminden /List/{id}daha iyi önceliğe sahip olduğu kabul edildiğinden bu işe yarar.

Önceliğin nasıl çalıştığına ilişkin ayrıntılar, yol şablonlarının nasıl tanımlandığına göre belirlenir:

  • Daha fazla segmente sahip şablonlar daha belirgin olarak kabul edilir.
  • Değişmez metin içeren bir kesim, parametre kesiminden daha özel olarak kabul edilir.
  • Kısıtlaması olan bir parametre kesimi, olmadan birden fazla özel olarak kabul edilir.
  • Karmaşık bir kesim, kısıtlaması olan bir parametre kesimi olarak özel olarak kabul edilir.
  • Tümünü yakala parametreleri en az belirlidir. Tümünü yakalayolları hakkında önemli bilgiler için Yol şablonları bölümünde tümünü yakala bölümüne bakın.

URL oluşturma kavramları

URL oluşturma:

  • Yönlendirmenin bir yol değerleri kümesine dayalı bir URL yolu oluşturabildiği işlemdir.
  • Uç noktalar ile bunlara erişen URL'ler arasında mantıksal ayrım yapılmasını sağlar.

Uç nokta yönlendirme api'sini LinkGenerator içerir. LinkGenerator , DI'den kullanılabilen tek bir hizmettir. API, LinkGenerator yürütme isteği bağlamının dışında kullanılabilir. Mvc.IUrlHelper ve kullanan Etiket Yardımcıları, HTML Yardımcıları ve Eylem Sonuçları gibi senaryolarIUrlHelper, bağlantı oluşturma özellikleri sağlamak için API'yi dahili olarak kullanırLinkGenerator.

Bağlantı oluşturucu, adres ve adres düzenleri kavramı tarafından yedeklenmiştir. Adres düzeni, bağlantı oluşturma için dikkate alınması gereken uç noktaları belirlemenin bir yoludur. Örneğin, birçok kullanıcının denetleyicilerden aşina olduğu yol adı ve yol değerleri senaryoları ve Razor Sayfalar bir adres düzeni olarak uygulanır.

Bağlantı oluşturucu, aşağıdaki uzantı yöntemleri aracılığıyla denetleyicilere ve Razor Sayfalara bağlanabilir:

Bu yöntemlerin aşırı yüklemeleri, öğesini içeren HttpContextbağımsız değişkenleri kabul eder. Bu yöntemler işlevsel olarak Url.Action ve Url.Page eşdeğerdir, ancak ek esneklik ve seçenekler sunar.

GetPath* Yöntemler, mutlak yol içeren bir URI oluşturmaları için Url.Action ve Url.Pageile en benzerleridir. GetUri* Yöntemler her zaman bir düzen ve konak içeren mutlak bir URI oluşturur. Kabul HttpContext eden yöntemler, yürütme isteği bağlamında bir URI oluşturur. Geçersiz kılınmadıkça, yürütülen istekten ortam yolu değerleri, URL temel yolu, şema ve konak kullanılır.

LinkGenerator bir adresle çağrılır. URI oluşturma işlemi iki adımda gerçekleşir:

  1. Adres, adresle eşleşen uç noktaların listesine bağlıdır.
  2. Sağlanan değerlerle eşleşen bir yol deseni bulunana kadar her uç noktanın RoutePattern değerleri değerlendirilir. Sonuçta elde edilen çıkış, bağlantı oluşturucuya sağlanan diğer URI parçalarıyla birleştirilir ve döndürülür.

tarafından LinkGenerator sağlanan yöntemler, her tür adres için standart bağlantı oluşturma özelliklerini destekler. Bağlantı oluşturucuyu kullanmanın en kolay yolu, belirli bir adres türü için işlemler gerçekleştiren uzantı yöntemleridir:

Uzantı Yöntemi Açıklama
GetPathByAddress Sağlanan değerleri temel alan mutlak bir yola sahip bir URI oluşturur.
GetUriByAddress Sağlanan değerlere göre mutlak bir URI oluşturur.

Uyarı

Çağırma LinkGenerator yöntemlerinin aşağıdaki etkilerine dikkat edin:

  • Gelen isteklerin üst bilgisini doğrulamayan Host bir uygulama yapılandırmasında uzantı yöntemlerini dikkatli kullanınGetUri*. Gelen isteklerin Host üst bilgisi doğrulanmazsa, güvenilmeyen istek girişi bir görünüm veya sayfadaki URI'lerde istemciye geri gönderilebilir. Tüm üretim uygulamalarının, üst bilgiyi bilinen geçerli değerlerle doğrulayacak Host şekilde yapılandırmalarını öneririz.

  • veya ile MapMapWhenbirlikte ara yazılımda dikkatli kullanınLinkGenerator. Map* , bağlantı oluşturmanın çıkışını etkileyen yürütme isteğinin temel yolunu değiştirir. Tüm API'ler LinkGenerator bir temel yol belirtmeye izin verir. Bağlantı oluşturma üzerindeki etkiyi Map* geri almak için boş bir temel yol belirtin.

Ara yazılım örneği

Aşağıdaki örnekte ara yazılım, depo ürünlerini listeleyen bir eylem yöntemine bağlantı oluşturmak için API'yi kullanır LinkGenerator . Bağlantı oluşturucuyu bir sınıfa ekleyerek kullanma ve bir uygulamadaki herhangi bir sınıf için çağrısı GenerateLink yapmak mümkündür:

public class ProductsMiddleware
{
    private readonly LinkGenerator _linkGenerator;

    public ProductsMiddleware(RequestDelegate next, LinkGenerator linkGenerator) =>
        _linkGenerator = linkGenerator;

    public async Task InvokeAsync(HttpContext httpContext)
    {
        httpContext.Response.ContentType = MediaTypeNames.Text.Plain;

        var productsPath = _linkGenerator.GetPathByAction("Products", "Store");

        await httpContext.Response.WriteAsync(
            $"Go to {productsPath} to see our products.");
    }
}

Yol şablonları

içindeki {} belirteçler, yol eşleşirse bağlı olan yol parametrelerini tanımlar. Yol kesiminde birden fazla yol parametresi tanımlanabilir, ancak yol parametreleri değişmez değerle ayrılmalıdır. Örneğin:

{controller=Home}{action=Index}

geçerli bir yol değildir, çünkü ile {action}arasında {controller} değişmez değer yoktur. Yol parametreleri bir ada sahip olmalı ve ek öznitelikler belirtilmiş olabilir.

Yol parametreleri dışındaki değişmez metin (örneğin, {id}) ve yol ayırıcı / url'deki metinle eşleşmelidir. Metin eşleştirme büyük/küçük harfe duyarlı değildir ve URL'nin yolunun kod çözülen gösterimine dayanır. Sabit yol parametresi sınırlayıcısı { veya }ile eşleştirmek için, karakteri yineleyerek sınırlayıcıdan kaçın. Örneğin {{ veya }}.

Yıldız işareti * veya çift yıldız **işareti:

  • URI'nin geri kalanına bağlanmak için bir yol parametresine ön ek olarak kullanılabilir.
  • Tümünü yakala parametreleri olarak adlandırılır. Örneğin, blog/{**slug}:
    • ile başlayan ve onu izleyen herhangi bir değere sahip URI'lerle blog/ eşleşir.
    • Aşağıdaki blog/ değer, bilgi yolu değerine atanır.

Uyarı

Tümünü yakala parametresi, yönlendirmedeki bir hata nedeniyle yolları yanlış eşleştirebilir. Bu hatadan etkilenen uygulamalar aşağıdaki özelliklere sahiptir:

  • Tümünü yakala yolu, örneğin, {**slug}"
  • Tümünü yakala yolu eşleşmesi gereken isteklerle eşleşemiyor.
  • Diğer yolların kaldırılması, tümünü yakala yolunun çalışmaya başlamasını sağlar.

Bu hataya isabet eden durumlar için bkz. GitHub hataları 18677 ve 16579 .

Bu hata için bir kabul düzeltmesi .NET Core 3.1.301 SDK ve sonraki sürümlerde yer alır. Aşağıdaki kod, bu hatayı düzelten bir iç anahtar ayarlar:

public static void Main(string[] args)
{
   AppContext.SetSwitch("Microsoft.AspNetCore.Routing.UseCorrectCatchAllBehavior", 
                         true);
   CreateHostBuilder(args).Build().Run();
}
// Remaining code removed for brevity.

Tümünü yakala parametreleri de boş dizeyle eşleşebilir.

Yol ayırıcı / karakterleri de dahil olmak üzere bir URL oluşturmak için yol kullanıldığında tümünü yakala parametresi uygun karakterlerin kaçışını verir. Örneğin, yol değerlerine { path = "my/path" } sahip yol foo/{*path} oluştururfoo/my%2Fpath. Kaçış eğik çizgisine dikkat edin. Gidiş dönüş yol ayırıcı karakterleri için yol parametresi ön ekini ** kullanın. ile { path = "my/path" } yolu foo/{**path} oluştururfoo/my/path.

İsteğe bağlı dosya uzantısına sahip bir dosya adını yakalamaya çalışan URL desenlerinin dikkate alınması gereken ek noktalar vardır. Örneğin, şablonunu files/{filename}.{ext?}göz önünde bulundurun. Hem hem de filenameext değerleri mevcut olduğunda, her iki değer de doldurulur. URL'de yalnızca için filename bir değer varsa, yol eşleşir çünkü sondaki . isteğe bağlıdır. Aşağıdaki URL'ler bu yolla eşleşti:

  • /files/myFile.txt
  • /files/myFile

Yol parametrelerinde, parametre adından sonra eşittir işaretiyle (= ) ayrılmış varsayılan değer belirtilerek varsayılan değerler belirlenebilir. Örneğin, {controller=Home} için controllervarsayılan değer olarak tanımlarHome. Parametresinin URL'sinde değer yoksa varsayılan değer kullanılır. Yol parametreleri, parametre adının sonuna bir soru işareti (?) eklenerek isteğe bağlıdır. Örneğin, id?. İsteğe bağlı değerler ile varsayılan yol parametreleri arasındaki fark:

  • Varsayılan değere sahip bir yol parametresi her zaman bir değer üretir.
  • İsteğe bağlı bir parametre yalnızca istek URL'si tarafından bir değer sağlandığında bir değere sahiptir.

Yol parametreleri, URL'den bağlanan yol değeriyle eşleşmesi gereken kısıtlamalara sahip olabilir. Yol parametresi adından sonra ekleme : ve kısıtlama adı, bir yol parametresinde satır içi kısıtlama belirtir. Kısıtlama bağımsız değişkenler gerektiriyorsa, bunlar kısıtlama adından sonra parantez (...) içine alınır. Başka bir : ve kısıtlama adı eklenerek birden çok satır içi kısıtlama belirtilebilir.

Kısıtlama adı ve bağımsız değişkenleri, URL işlemede IInlineConstraintResolver kullanılacak örneğini IRouteConstraint oluşturmak için hizmete geçirilir. Örneğin, yol şablonu blog/{article:minlength(10)} bağımsız değişkeniyle 10bir minlength kısıtlama belirtir. Yol kısıtlamaları hakkında daha fazla bilgi ve çerçeve tarafından sağlanan kısıtlamaların listesi için Yol kısıtlamaları bölümüne bakın.

Rota parametrelerinde de parametre transformatörleri olabilir. Parametre transformatörleri, url'lere bağlantılar ve eşleşen eylemler ve sayfalar oluştururken parametrenin değerini dönüştürür. Kısıtlamalar gibi parametre transformatörleri de rota parametresi adından sonra bir : ve transformatör adı eklenerek bir yol parametresine satır içi olarak eklenebilir. Örneğin, yol şablonu blog/{article:slugify} bir slugify transformatör belirtir. Parametre transformatörleri hakkında daha fazla bilgi için Parametre transformatörleri bölümüne bakın.

Aşağıdaki tabloda örnek yol şablonları ve davranışları gösterilmektedir:

Rota Şablonu Örnek Eşleşen URI İstek URI'si...
hello /hello Yalnızca tek yol ile eşleşir /hello.
{Page=Home} / ile eşleşir ve ile eşleşir PageHome.
{Page=Home} /Contact ile eşleşir ve ile eşleşir PageContact.
{controller}/{action}/{id?} /Products/List Denetleyiciye ve List eyleme Products Haritalar.
{controller}/{action}/{id?} /Products/Details/123 Denetleyiciye Products Haritalar ve Details 123 olarak ayarlanmış eylemid.
{controller=Home}/{action=Index}/{id?} / Denetleyiciye ve Index yönteme Home Haritalar. id yoksayılır.
{controller=Home}/{action=Index}/{id?} /Products Denetleyiciye ve Index yönteme Products Haritalar. id yoksayılır.

Şablon kullanmak genellikle yönlendirmeye en basit yaklaşımdır. Kısıtlamalar ve varsayılanlar, yol şablonunun dışında da belirtilebilir.

Karmaşık segmentler

Karmaşık segmentler, doyumsuz olmayan bir şekilde sağdan sola sabit sınırlayıcıları eşleştirerek işlenir. Örneğin, [Route("/a{b}c{d}")] karmaşık bir kesimdir. Karmaşık segmentler, bunları başarıyla kullanmak için anlaşılması gereken belirli bir şekilde çalışır. Bu bölümdeki örnekte, karmaşık segmentlerin neden yalnızca sınırlayıcı metin parametre değerlerinin içinde görünmediğinde gerçekten iyi çalıştığı gösterilmektedir. Daha karmaşık durumlar için bir regex kullanmak ve sonra değerleri el ile ayıklamak gerekir.

Uyarı

Güvenilmeyen girişi işlemek için kullanırken System.Text.RegularExpressions bir zaman aşımı geçirin. Kötü amaçlı bir kullanıcı Hizmet Reddi saldırısına neden olacak RegularExpressionsgirişler sağlayabilir. ASP.NET Zaman aşımı kullanan RegularExpressions Core framework API'leri.

Bu, yönlendirmenin şablon /a{b}c{d} ve URL yolu /abcdile gerçekleştirdiği adımların özetidir. |, algoritmanın nasıl çalıştığını görselleştirmeye yardımcı olmak için kullanılır:

  • İlk değişmez değer, sağdan sola, şeklindedir c. Bu nedenle /abcd sağdan aranıp öğesini bulur /ab|c|d.
  • Sağdaki (d) her şey artık yol parametresiyle {d}eşleştirilir.
  • Sağdan sola doğru sonraki değişmez değer olur a. Kaldığımız /ab|c|d yerden başlayarak arandı, sonra a bulunur /|a|b|c|d.
  • Sağındaki (b) değeri artık route parametresiyle {b}eşleştirilir.
  • Kalan metin ve kalan yol şablonu olmadığından bu bir eşleşmedir.

Aşağıda, aynı şablonu /a{b}c{d} ve URL yolunu kullanan negatif bir durum örneği verilmişti /aabcd. |, algoritmanın nasıl çalıştığını görselleştirmeye yardımcı olmak için kullanılır. Bu durum aynı algoritmayla açıklanan bir eşleşme değildir:

  • İlk değişmez değer, sağdan sola, şeklindedir c. Bu nedenle /aabcd sağdan aranıp öğesini bulur /aab|c|d.
  • Sağdaki (d) her şey artık yol parametresiyle {d}eşleştirilir.
  • Sağdan sola doğru sonraki değişmez değer olur a. Kaldığımız /aab|c|d yerden başlayarak arandı, sonra a bulunur /a|a|b|c|d.
  • Sağındaki (b) değeri artık route parametresiyle {b}eşleştirilir.
  • Bu noktada kalan metin avardır, ancak algoritmada ayrıştırılacak yol şablonu tükendi, bu nedenle bu eşleşme değildir.

Eşleşen algoritma doyumsuz olmadığından:

  • Her adımda mümkün olan en küçük metin miktarıyla eşleşir.
  • Sınırlayıcı değerinin parametre değerlerinin içinde göründüğü her durumda eşleşmez.

Normal ifadeler, eşleşen davranışları üzerinde çok daha fazla denetim sağlar.

Yavaş eşleştirme olarak da bilinen doyumsuz eşleştirme, mümkün olan en büyük dizeyle eşleşir. Doyumsuz olmayan, mümkün olan en küçük dizeyle eşleşir.

Özel karakterlerle yönlendirme

Özel karakterlerle yönlendirme beklenmeyen sonuçlara yol açabilir. Örneğin, aşağıdaki eylem yöntemine sahip bir denetleyici düşünün:

[HttpGet("{id?}/name")]
public async Task<ActionResult<string>> GetName(string id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null || todoItem.Name == null)
    {
        return NotFound();
    }

    return todoItem.Name;
}

string id Aşağıdaki kodlanmış değerleri içerdiğinde beklenmeyen sonuçlar oluşabilir:

ASCII Encoded
/ %2F
+

Yol parametreleri her zaman URL kodunu çözmez. Bu sorun gelecekte giderilebilir. Daha fazla bilgi için bu GitHub sorununa bakın;

Yol kısıtlamaları

Yönlendirme kısıtlamaları, gelen URL'de bir eşleşme oluştuğunda ve URL yolu yol değerlerine belirteç olarak ayarlandığında yürütülür. Yol kısıtlamaları genellikle yol şablonu aracılığıyla ilişkili yol değerini inceler ve değerin kabul edilebilir olup olmadığı konusunda doğru veya yanlış bir karar verir. Bazı yol kısıtlamaları, isteğin yönlendirilip yönlendirilemeyeceğini göz önünde bulundurmak için yol değerinin dışındaki verileri kullanır. Örneğin, HttpMethodRouteConstraint http fiiline göre bir isteği kabul edebilir veya reddedebilir. Kısıtlamalar yönlendirme isteklerinde ve bağlantı oluşturmada kullanılır.

Uyarı

Giriş doğrulaması için kısıtlamaları kullanmayın. Giriş doğrulaması için kısıtlamalar kullanılıyorsa geçersiz giriş Bulunamadı yanıtında 404 sonuçlanıyor. Geçersiz giriş, uygun bir 400 hata iletisiyle Hatalı İstek oluşturmalıdır. Yol kısıtlamaları, belirli bir yolun girişlerini doğrulamak için değil, benzer yolların belirsizliğini belirlemek için kullanılır.

Aşağıdaki tabloda örnek yol kısıtlamaları ve beklenen davranışları gösterilmektedir:

kısıtlama Örnek Örnek Eşleşmeler Notlar
int {id:int} 123456789, -123456789 Herhangi bir tamsayıyla eşleşir
bool {active:bool} true, FALSE veya falseile eşleşirtrue. Duyarlı
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm Sabit kültürdeki geçerli DateTime bir değerle eşleşir. Önceki uyarıya bakın.
decimal {price:decimal} 49.99, -1,000.01 Sabit kültürdeki geçerli decimal bir değerle eşleşir. Önceki uyarıya bakın.
double {weight:double} 1.234, -1,001.01e8 Sabit kültürdeki geçerli double bir değerle eşleşir. Önceki uyarıya bakın.
float {weight:float} 1.234, -1,001.01e8 Sabit kültürdeki geçerli float bir değerle eşleşir. Önceki uyarıya bakın.
guid {id:guid} CD2C1638-1638-72D5-1638-DEADBEEF1638 Geçerli Guid bir değerle eşleşir
long {ticks:long} 123456789, -123456789 Geçerli long bir değerle eşleşir
minlength(value) {username:minlength(4)} Rick Dize en az 4 karakter olmalıdır
maxlength(value) {filename:maxlength(8)} MyFile Dize 8 karakterden fazla olmamalıdır
length(length) {filename:length(12)} somefile.txt Dize tam olarak 12 karakter uzunluğunda olmalıdır
length(min,max) {filename:length(8,16)} somefile.txt Dize en az 8 ve en fazla 16 karakter uzunluğunda olmalıdır
min(value) {age:min(18)} 19 Tamsayı değeri en az 18 olmalıdır
max(value) {age:max(120)} 91 Tamsayı değeri en fazla 120 olmalıdır
range(min,max) {age:range(18,120)} 91 Tamsayı değeri en az 18, en fazla 120 olmalıdır
alpha {name:alpha} Rick Dize bir a-z veya daha fazla alfabetik karakterden ve büyük/küçük harfe duyarsız karakterden oluşmalıdır.
regex(expression) {ssn:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)} 123-45-6789 Dize normal ifadeyle eşleşmelidir. Normal ifade tanımlama hakkındaki ipuçlarına bakın.
required {name:required} Rick URL oluşturma sırasında parametre olmayan bir değerin mevcut olmasını zorunlu kılmak için kullanılır

Uyarı

Güvenilmeyen girişi işlemek için kullanırken System.Text.RegularExpressions bir zaman aşımı geçirin. Kötü amaçlı bir kullanıcı Hizmet Reddi saldırısına neden olacak RegularExpressionsgirişler sağlayabilir. ASP.NET Zaman aşımı kullanan RegularExpressions Core framework API'leri.

Tek bir parametreye birden çok iki nokta üst üste sınırlandırılmış kısıtlama uygulanabilir. Örneğin, aşağıdaki kısıtlama bir parametreyi 1 veya daha büyük bir tamsayı değeriyle kısıtlar:

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

Uyarı

URL'yi doğrulayan ve CLR türüne dönüştürülen yol kısıtlamaları her zaman sabit kültürü kullanır. Örneğin, CLR türüne int veya DateTimedönüştürme. Bu kısıtlamalar URL'nin yerelleştirilebilir olmadığını varsayar. Çerçeve tarafından sağlanan yol kısıtlamaları, yol değerlerinde depolanan değerleri değiştirmez. URL'den ayrıştırılan tüm yol değerleri dize olarak depolanır. Örneğin kısıtlama, float yol değerini kayan değere dönüştürmeye çalışır, ancak dönüştürülen değer yalnızca float'a dönüştürülebileceğini doğrulamak için kullanılır.

Kısıtlamalardaki normal ifadeler

Uyarı

Güvenilmeyen girişi işlemek için kullanırken System.Text.RegularExpressions bir zaman aşımı geçirin. Kötü amaçlı bir kullanıcı Hizmet Reddi saldırısına neden olacak RegularExpressionsgirişler sağlayabilir. ASP.NET Zaman aşımı kullanan RegularExpressions Core framework API'leri.

Normal ifadeler, yol kısıtlaması kullanılarak regex(...) satır içi kısıtlamalar olarak belirtilebilir. Ailedeki yöntemler, kısıtlamaların MapControllerRoute nesne değişmez değerlerini de kabul eder. Bu form kullanılırsa, dize değerleri normal ifadeler olarak yorumlanır.

Aşağıdaki kod satır içi bir regex kısıtlaması kullanır:

app.MapGet("{message:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)}",
    () => "Inline Regex Constraint Matched");

Aşağıdaki kod, bir regex kısıtlaması belirtmek için bir nesne değişmez değeri kullanır:

app.MapControllerRoute(
    name: "people",
    pattern: "people/{ssn}",
    constraints: new { ssn = "^\\d{3}-\\d{2}-\\d{4}$", },
    defaults: new { controller = "People", action = "List" });

ASP.NET Core çerçevesi normal ifade oluşturucuya ekler RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant . Bu üyelerin açıklaması için bkz RegexOptions .

Normal ifadeler, yönlendirme ve C# dili tarafından kullanılanlara benzer sınırlayıcılar ve belirteçler kullanır. Normal ifade belirteçlerinin kaçılması gerekir. Normal ifadeyi ^\d{3}-\d{2}-\d{4}$ satır içi kısıtlamada kullanmak için aşağıdakilerden birini kullanın:

Yönlendirme parametresi sınırlayıcı karakterlerini {, , [}, , ]kaçış olarak kullanmak için ifadedeki karakterleri (örneğin, {{, }}, , [[]]) iki katına çıkarır. Aşağıdaki tabloda normal bir ifade ve kaçış sürümü gösterilmektedir:

Regular expression Kaçış normal ifadesi
^\d{3}-\d{2}-\d{4}$ ^\\d{{3}}-\\d{{2}}-\\d{{4}}$
^[a-z]{2}$ ^[[a-z]]{{2}}$

Yönlendirmede kullanılan normal ifadeler genellikle karakterle ^ başlar ve dizenin başlangıç konumuyla eşleşer. İfadeler genellikle karakterle biter ve dizenin sonuyla $ eşleşer. ^ ve $ karakterleri normal ifadenin yol parametresi değerinin tamamıyla eşleşmesini sağlar. ^ ve $ karakterleri olmadan, normal ifade dizedeki alt dizelerle eşleşir ve bu genellikle istenmeyen bir durumdur. Aşağıdaki tabloda örnekler ve bunların neden eşleştikleri veya eşleşmedikleri açıklanmaktadır:

Expression String Eşleştir Yorum
[a-z]{2} merhaba Yes Alt dize eşleşmeleri
[a-z]{2} 123abc456 Yes Alt dize eşleşmeleri
[a-z]{2} Mz Yes İfadeyle eşleşir
[a-z]{2} MZ Yes Büyük/küçük harfe duyarlı değil
^[a-z]{2}$ merhaba Hayır Bkz ^ . ve $ üzeri
^[a-z]{2}$ 123abc456 Hayır Bkz ^ . ve $ üzeri

Normal ifade söz dizimi hakkında daha fazla bilgi için bkz . .NET Framework Normal İfadeleri.

Bir parametreyi bilinen bir olası değer kümesiyle sınırlamak için normal bir ifade kullanın. Örneğin, {action:regex(^(list|get|create)$)} yalnızca yol değeri listile action , getveya createile eşleşir. Kısıtlamalar sözlüğüne geçirilirse dize ^(list|get|create)$ eşdeğerdir. Bilinen kısıtlamalardan biriyle eşleşmeyen kısıtlama sözlüğünde geçirilen kısıtlamalar da normal ifadeler olarak kabul edilir. Bilinen kısıtlamalardan biriyle eşleşmeyen bir şablon içinde geçirilen kısıtlamalar normal ifadeler olarak kabul edilmemektedir.

Özel yol kısıtlamaları

Özel yol kısıtlamaları, arabirimi uygulanarak IRouteConstraint oluşturulabilir. Arabirimi, IRouteConstraint kısıtlamanın karşılanması durumunda döndüren ve false aksi halde döndüren true öğesini içerirMatch.

Özel yol kısıtlamalarına nadiren ihtiyaç duyulduğu görülür. Özel yol kısıtlaması uygulamadan önce model bağlama gibi alternatifleri göz önünde bulundurun.

ASP.NET Core Constraints klasörü, kısıtlama oluşturmaya yönelik iyi örnekler sağlar. Örneğin, GuidRouteConstraint.

Özel IRouteConstraintbir kullanmak için, yol kısıtlama türünün hizmet kapsayıcısında uygulamanınkilere ConstraintMap kaydedilmesi gerekir. A ConstraintMap , yönlendirme kısıtlama anahtarlarını bu kısıtlamaları doğrulayan uygulamalarla IRouteConstraint eşleyen bir sözlüktür. Bir uygulamanın uygulamasıConstraintMap, bir çağrının AddRouting parçası olarak veya ile builder.Services.Configure<RouteOptions>doğrudan yapılandırılarak RouteOptions güncelleştirilebilirProgram.cs. Örneğin:

builder.Services.AddRouting(options =>
    options.ConstraintMap.Add("noZeroes", typeof(NoZeroesRouteConstraint)));

Yukarıdaki kısıtlama aşağıdaki kodda uygulanır:

[ApiController]
[Route("api/[controller]")]
public class NoZeroesController : ControllerBase
{
    [HttpGet("{id:noZeroes}")]
    public IActionResult Get(string id) =>
        Content(id);
}

uygulaması NoZeroesRouteConstraint , bir yol parametresinde kullanılmasını engeller 0 :

public class NoZeroesRouteConstraint : IRouteConstraint
{
    private static readonly Regex _regex = new(
        @"^[1-9]*$",
        RegexOptions.CultureInvariant | RegexOptions.IgnoreCase,
        TimeSpan.FromMilliseconds(100));

    public bool Match(
        HttpContext? httpContext, IRouter? route, string routeKey,
        RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (!values.TryGetValue(routeKey, out var routeValue))
        {
            return false;
        }

        var routeValueString = Convert.ToString(routeValue, CultureInfo.InvariantCulture);

        if (routeValueString is null)
        {
            return false;
        }

        return _regex.IsMatch(routeValueString);
    }
}

Uyarı

Güvenilmeyen girişi işlemek için kullanırken System.Text.RegularExpressions bir zaman aşımı geçirin. Kötü amaçlı bir kullanıcı Hizmet Reddi saldırısına neden olacak RegularExpressionsgirişler sağlayabilir. ASP.NET Zaman aşımı kullanan RegularExpressions Core framework API'leri.

Yukarıdaki kod:

  • Yolun segmentinde {id} engeller0.
  • Özel kısıtlama uygulamanın temel bir örneğini sağlamak için gösterilir. Üretim uygulamasında kullanılmamalıdır.

Aşağıdaki kod, içeren bir kodun işlenmesini önlemeye yönelik daha iyi bir id0 yaklaşımdır:

[HttpGet("{id}")]
public IActionResult Get(string id)
{
    if (id.Contains('0'))
    {
        return StatusCode(StatusCodes.Status406NotAcceptable);
    }

    return Content(id);
}

Yukarıdaki kod, yaklaşıma göre aşağıdaki avantajlara NoZeroesRouteConstraint sahiptir:

  • Özel bir kısıtlama gerektirmez.
  • Yol parametresi içerdiğinde 0daha açıklayıcı bir hata döndürür.

Parametre transformatörleri

Parametre transformatörleri:

Örneğin, ile Url.Action(new { article = "MyTestArticle" }) yol deseninde blog\{article:slugify} özel slugify bir parametre transformatörü oluştururblog\my-test-article.

Aşağıdaki IOutboundParameterTransformer uygulamayı göz önünde bulundurun:

public class SlugifyParameterTransformer : IOutboundParameterTransformer
{
    public string? TransformOutbound(object? value)
    {
        if (value is null)
        {
            return null;
        }

        return Regex.Replace(
            value.ToString()!,
                "([a-z])([A-Z])",
            "$1-$2",
            RegexOptions.CultureInvariant,
            TimeSpan.FromMilliseconds(100))
            .ToLowerInvariant();
    }
}

Rota deseninde bir parametre transformatörü kullanmak için içinde kullanarak ConstraintMapProgram.csyapılandırın:

builder.Services.AddRouting(options =>
    options.ConstraintMap["slugify"] = typeof(SlugifyParameterTransformer));

ASP.NET Core çerçevesi, bir uç noktanın çözümlendiği URI'yi dönüştürmek için parametre dönüştürücülerini kullanır. Örneğin, parametre transformatörleri , area, controlleractionve pageile eşleştirmek için kullanılan yol değerlerini dönüştürür:

app.MapControllerRoute(
    name: "default",
    pattern: "{controller:slugify=Home}/{action:slugify=Index}/{id?}");

Önceki yol şablonuyla, eylem SubscriptionManagementController.GetAll URI /subscription-management/get-allile eşleştirilir. Parametre transformatörü, bağlantı oluşturmak için kullanılan yol değerlerini değiştirmez. Örneğin, Url.Action("GetAll", "SubscriptionManagement") çıkışları /subscription-management/get-all.

ASP.NET Core, oluşturulan yollar ile parametre dönüştürücülerini kullanmaya yönelik API kuralları sağlar:

URL oluşturma başvurusu

Bu bölüm, URL oluşturma tarafından uygulanan algoritma için bir başvuru içerir. Uygulamada, URL oluşturmanın en karmaşık örneklerinde denetleyiciler veya Razor Sayfalar kullanılır. Ek bilgi için bkz . denetleyicilerde yönlendirme.

URL oluşturma işlemi bir LinkGenerator.GetPathByAddress çağrısı veya benzer bir yöntemle başlar. yöntemi bir adres, yol değerleri kümesi ve isteğe bağlı olarak geçerli HttpContextistek hakkında bilgi ile sağlanır.

İlk adım, adresi kullanarak adresin türüyle eşleşen bir aday uç nokta IEndpointAddressScheme<TAddress> kümesini çözümlemektir.

Adaylar kümesi adres düzeni tarafından bulunduktan sonra, URL oluşturma işlemi başarılı olana kadar uç noktalar yinelemeli olarak sıralanır ve işlenir. URL oluşturma belirsizlikleri denetlemez, döndürülen ilk sonuç nihai sonuç olur.

Günlüğe kaydetme ile URL oluşturma sorunlarını giderme

URL oluşturma sorunlarını gidermenin ilk adımı, günlük düzeyini Microsoft.AspNetCore.Routing olarak TRACEayarlamaktır. LinkGenerator sorunları gidermek için yararlı olabilecek işlemesiyle ilgili birçok ayrıntıyı günlüğe kaydeder.

URL oluşturmayla ilgili ayrıntılar için bkz . URL oluşturma başvurusu .

Adresler

Adresler, bir çağrıyı bağlantı oluşturucusuna bir dizi aday uç noktaya bağlamak için kullanılan URL oluşturma kavramıdır.

Adresler, varsayılan olarak iki uygulamayla birlikte gelen genişletilebilir bir kavramdır:

  • Adres olarak uç nokta adını (string) kullanma:
    • MVC'nin yol adına benzer işlevler sağlar.
    • IEndpointNameMetadata Meta veri türünü kullanır.
    • Sağlanan dizeyi tüm kayıtlı uç noktaların meta verilerine karşı çözümler.
    • Birden çok uç nokta aynı adı kullanıyorsa başlangıçta bir özel durum oluşturur.
    • Denetleyiciler ve Razor Sayfalar dışında genel amaçlı kullanım için önerilir.
  • Adres olarak yol değerlerini (RouteValuesAddress) kullanma:
    • Denetleyiciler ve Razor Sayfalar eski URL oluşturma için benzer işlevler sağlar.
    • Genişletmek ve hata ayıklamak çok karmaşık.
    • , Etiket Yardımcıları, HTML Yardımcıları, Eylem Sonuçları vb. tarafından IUrlHelperkullanılan uygulamayı sağlar.

Adres düzeninin rolü, adres ve eşleşen uç noktalar arasındaki ilişkilendirmeyi rastgele ölçütlerle yapmaktır:

  • Uç nokta adı düzeni temel bir sözlük araması gerçekleştirir.
  • Yol değerleri şeması, küme algoritmasının karmaşık en iyi alt kümesine sahiptir.

Ortam değerleri ve açık değerler

Geçerli istekten yönlendirme, geçerli isteğin HttpContext.Request.RouteValuesyol değerlerine erişir. Geçerli istekle ilişkili değerler ortam değerleri olarak adlandırılır. Netlik sağlamak amacıyla belgeler, yöntemlere açık değerler olarak geçirilen yol değerlerini ifade eder.

Aşağıdaki örnekte ortam değerleri ve açık değerler gösterilmektedir. Geçerli istekten ortam değerleri ve açık değerler sağlar:

public class WidgetController : ControllerBase
{
    private readonly LinkGenerator _linkGenerator;

    public WidgetController(LinkGenerator linkGenerator) =>
        _linkGenerator = linkGenerator;

    public IActionResult Index()
    {
        var indexPath = _linkGenerator.GetPathByAction(
            HttpContext, values: new { id = 17 })!;

        return Content(indexPath);
    }

    // ...

Yukarıdaki kod:

Aşağıdaki kod yalnızca açık değerler sağlar ve ortam değerleri sağlamaz:

var subscribePath = _linkGenerator.GetPathByAction(
    "Subscribe", "Home", new { id = 17 })!;

Yukarıdaki yöntem döndürür /Home/Subscribe/17

içindeki aşağıdaki kod WidgetController döndürür /Widget/Subscribe/17:

var subscribePath = _linkGenerator.GetPathByAction(
    HttpContext, "Subscribe", null, new { id = 17 });

Aşağıdaki kod, denetleyiciyi geçerli istekteki ortam değerlerinden ve açık değerlerden sağlar:

public class GadgetController : ControllerBase
{
    public IActionResult Index() =>
        Content(Url.Action("Edit", new { id = 17 })!);
}

Önceki kodda:

  • /Gadget/Edit/17 döndürülür.
  • Url alır IUrlHelper.
  • Action bir eylem yöntemi için mutlak yola sahip bir URL oluşturur. URL belirtilen action adı ve route değerleri içerir.

Aşağıdaki kod, geçerli istekten gelen ortam değerlerini ve açık değerleri sağlar:

public class IndexModel : PageModel
{
    public void OnGet()
    {
        var editUrl = Url.Page("./Edit", new { id = 17 });

        // ...
    }
}

Yukarıdaki kod, SayfaYı Düzenle Razor aşağıdaki sayfa yönergesini içerdiğinde olarak ayarlır:url/Edit/17

@page "{id:int}"

Düzenle sayfası yol şablonunu içermiyorsa "{id:int}" , url şeklindedir /Edit?id=17.

MVC'nin IUrlHelper davranışı, burada açıklanan kurallara ek olarak bir karmaşıklık katmanı ekler:

  • IUrlHelper her zaman geçerli istekten yol değerlerini ortam değerleri olarak sağlar.
  • IUrlHelper.Action , geliştirici tarafından geçersiz kılınmadığı sürece her zaman geçerli action ve controller yol değerlerini açık değerler olarak kopyalar.
  • IUrlHelper.Page geçersiz kılınmadığı sürece geçerli page yol değerini her zaman açık bir değer olarak kopyalar.
  • IUrlHelper.Page geçersiz kılınmadığı sürece geçerli handler yol değerini null her zaman ile açık değerler olarak geçersiz kılar.

MVC kendi kurallarına uymadığından kullanıcılar genellikle ortam değerlerinin davranışsal ayrıntılarına şaşırır. Geçmiş ve uyumluluk nedenleriyle, , controller, pageve handler gibi actionbelirli yol değerlerinin kendi özel durum davranışları vardır.

tarafından LinkGenerator.GetPathByAction sağlanan eşdeğer işlevsellik ve LinkGenerator.GetPathByPage uyumluluk için bu anomalilerini IUrlHelper yineler.

URL oluşturma işlemi

Aday uç nokta kümesi bulunduktan sonra URL oluşturma algoritması:

  • Uç noktaları yinelemeli olarak işler.
  • İlk başarılı sonucu döndürür.

Bu işlemin ilk adımı, yol değeri geçersizleştirmesi olarak adlandırılır. Yol değeri geçersiz kılınması, yönlendirmenin ortam değerlerinden hangi yol değerlerinin kullanılacağına ve hangilerinin yoksayılacağına karar verdiği işlemdir. Her ortam değeri kabul edilir ve açık değerlerle birleştirilir veya yoksayılır.

Ortam değerlerinin rolü hakkında düşünmenin en iyi yolu, bazı yaygın durumlarda uygulama geliştiricilerini yazmaya kaydetmeyi denemeleridir. Geleneksel olarak ortam değerlerinin yararlı olduğu senaryolar MVC ile ilgilidir:

  • Aynı denetleyicideki başka bir eyleme bağlanırken, denetleyici adının belirtilmesi gerekmez.
  • Aynı alandaki başka bir denetleyiciye bağlanırken alan adının belirtilmesi gerekmez.
  • Aynı eylem yöntemine bağlanırken yol değerlerinin belirtilmesi gerekmez.
  • Uygulamanın başka bir bölümüne bağlanırken, uygulamanın bu bölümünde hiçbir anlamı olmayan rota değerlerini taşımak istemezsiniz.

LinkGenerator veya IUrlHelper döndüren null çağrıların nedeni genellikle yol değeri geçersizleştirmesini anlamamaktır. Bunun sorunu çözüp çözmediğini görmek için yol değerlerinden daha fazlasını açıkça belirterek yol değeri geçersizliği sorunlarını giderin.

Yol değeri geçersiz kılınması, uygulamanın URL düzeninin hiyerarşik olduğu varsayımıyla çalışır ve soldan sağa bir hiyerarşi oluşturulur. Bunun pratikte nasıl çalıştığına ilişkin sezgisel bir fikir edinmek için temel denetleyici rota şablonunu {controller}/{action}/{id?} göz önünde bulundurun. Bir değerde yapılan değişiklik, sağda görünen tüm yol değerlerini geçersiz kıldığını gösterir. Bu, hiyerarşi hakkındaki varsayımı yansıtır. Uygulamanın için idbir ortam değeri varsa ve işlem için controllerfarklı bir değer belirtir:

  • idöğesinin solunda {id?}olduğundan {controller} yeniden kullanılamaz.

Bu ilkeyi gösteren bazı örnekler:

  • Açık değerler için idbir değer içeriyorsa, için id ortam değeri yoksayılır. ve action ortam controller değerleri kullanılabilir.
  • Açık değerler için actionbir değer içeriyorsa, için action ortam değerleri yoksayılır. için controller ortam değerleri kullanılabilir. için action açık değer için ortam değerinden actionid farklıysa, değeri kullanılmaz. için action açık değer için ortam değeri actionid ile aynıysa, değeri kullanılabilir.
  • Açık değerler için controllerbir değer içeriyorsa, için controller ortam değerleri yoksayılır. için controller açık değer için ortam değerinden controlleraction farklıysa ve id değerleri kullanılmaz. için controller açık değer, için ortam değeriyle controlleraction aynıysa ve id değerleri kullanılabilir.

Bu işlem, öznitelik yollarının ve ayrılmış geleneksel yolların varlığıyla daha karmaşıktır. Yol parametrelerini kullanarak hiyerarşi belirtme gibi {controller}/{action}/{id?} denetleyici geleneksel yolları. Denetleyicilere ve Sayfalara ayrılmış geleneksel yollar ve Razor öznitelik yolları için:

  • Yol değerleri hiyerarşisi vardır.
  • Bunlar şablonda görünmez.

Bu durumlarda, URL oluşturma gerekli değerler kavramını tanımlar. Denetleyiciler ve Razor Sayfalar tarafından oluşturulan uç noktaların, yol değeri geçersiz kılınmasına izin veren gerekli değerler belirtilmiştir.

Yol değeri geçersizleştirme algoritması ayrıntılı olarak:

  • Gerekli değer adları yol parametreleriyle birleştirilir ve ardından soldan sağa işlenir.
  • Her parametre için ortam değeri ve açık değer karşılaştırılır:
    • Ortam değeri ve açık değer aynıysa işlem devam eder.
    • Ortam değeri mevcutsa ve açık değer yoksa, URL oluşturulurken ortam değeri kullanılır.
    • Ortam değeri yoksa ve açık değer ise, ortam değerini ve sonraki tüm ortam değerlerini reddedin.
    • Ortam değeri ve açık değer varsa ve iki değer farklıysa, ortam değerini ve sonraki tüm ortam değerlerini reddedin.

Bu noktada, URL oluşturma işlemi yol kısıtlamalarını değerlendirmeye hazırdır. Kabul edilen değerler kümesi, kısıtlamalara sağlanan parametre varsayılan değerleriyle birleştirilir. Kısıtlamaların tümü geçerse işlem devam eder.

Ardından, kabul edilen değerler yol şablonunu genişletmek için kullanılabilir. Yol şablonu işlenir:

  • Soldan sağa.
  • Her parametrenin yerine kabul edilen değeri vardır.
  • Aşağıdaki özel durumlarla:
    • Kabul edilen değerlerde bir değer eksikse ve parametrenin varsayılan değeri varsa, varsayılan değer kullanılır.
    • Kabul edilen değerlerde bir değer eksikse ve parametre isteğe bağlıysa işleme devam eder.
    • Eksik isteğe bağlı parametrenin sağındaki herhangi bir yol parametresinin değeri varsa, işlem başarısız olur.
    • Bitişik varsayılan değerli parametreler ve isteğe bağlı parametreler mümkün olduğunca daraltılır.

Yolun bir kesimiyle eşleşmeyen açıkça sağlanan değerler sorgu dizesine eklenir. Aşağıdaki tabloda yol şablonu {controller}/{action}/{id?}kullanılırken elde edilen sonuç gösterilmektedir.

Ortam Değerleri Açık Değerler Sonuç
controller = "Home" action = "About" /Home/About
controller = "Home" controller = "Order", action = "About" /Order/About
denetleyici = "Home", renk = "Kırmızı" action = "About" /Home/About
controller = "Home" action = "About", color = "Red" /Home/About?color=Red

İsteğe bağlı yol parametresi sırası

İsteğe bağlı yol parametreleri tüm gerekli yol parametrelerinin ardından gelmelidir. Aşağıdaki kodda id ve name parametreleri parametresinden color sonra gelmelidir:

using Microsoft.AspNetCore.Mvc;

namespace WebApplication1.Controllers;

[Route("api/[controller]")]
public class MyController : ControllerBase
{
    // GET /api/my/red/2/joe
    // GET /api/my/red/2
    // GET /api/my
    [HttpGet("{color}/{id:int?}/{name?}")]
    public IActionResult GetByIdAndOptionalName(string color, int id = 1, string? name = null)
    {
        return Ok($"{color} {id} {name ?? ""}");
    }
}

Yol değeri geçersiz kılınmasıyla ilgili sorunlar

Aşağıdaki kod, yönlendirme tarafından desteklenmeyen bir URL oluşturma şeması örneği gösterir:

app.MapControllerRoute(
    "default",
    "{culture}/{controller=Home}/{action=Index}/{id?}");

app.MapControllerRoute(
    "blog",
    "{culture}/{**slug}",
    new { controller = "Blog", action = "ReadPost" });

Yukarıdaki kodda culture , yerelleştirme için yol parametresi kullanılır. Parametrenin culture her zaman bir ortam değeri olarak kabul edilmiş olmasını istemeniz gerekir. Ancak, gerekli değerlerin culture çalışma şekli nedeniyle parametre ortam değeri olarak kabul edilmemektedir:

  • Yol şablonunda "default" , culture yol parametresi solundadır controller, bu nedenle olarak değişir controller ve geçersiz kılmaz culture.
  • Yol şablonunda "blog" , culture yol parametresinin, gerekli değerlerde görünen sağında controllerolduğu kabul edilir.

ILE URL yollarını ayrıştırma LinkParser

sınıfı, LinkParser URL yolunu bir yol değerleri kümesine ayrıştırma desteği ekler. ParsePathByEndpointName yöntemi bir uç nokta adı ve URL yolu alır ve URL yolundan ayıklanan bir yol değerleri kümesi döndürür.

Aşağıdaki örnek denetleyicide GetProduct , eylem bir yol şablonu api/Products/{id} kullanır ve öğesinin bir Name öğesine GetProductsahiptir:

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    [HttpGet("{id}", Name = nameof(GetProduct))]
    public IActionResult GetProduct(string id)
    {
        // ...

Aynı denetleyici sınıfında, AddRelatedProduct eylem sorgu dizesi parametresi olarak sağlanabilen bir URL yolu pathToRelatedProductbekler:

[HttpPost("{id}/Related")]
public IActionResult AddRelatedProduct(
    string id, string pathToRelatedProduct, [FromServices] LinkParser linkParser)
{
    var routeValues = linkParser.ParsePathByEndpointName(
        nameof(GetProduct), pathToRelatedProduct);
    var relatedProductId = routeValues?["id"];

    // ...

Yukarıdaki örnekte, AddRelatedProduct eylem URL yolundan id yol değerini ayıklar. Örneğin, url yolu /api/Products/1relatedProductId ile değeri olarak 1ayarlanır. Bu yaklaşım, API istemcilerinin kaynaklara başvururken URL yollarını kullanmasına olanak tanır ve bu tür bir URL'nin nasıl yapılandırıldığı hakkında bilgi sahibi olmak zorunda değildir.

Uç nokta meta verilerini yapılandırma

Aşağıdaki bağlantılar, uç nokta meta verilerini yapılandırma hakkında bilgi sağlar:

RequireHost ile yollarda konak eşleştirme

RequireHost belirtilen konağı gerektiren yola bir kısıtlama uygular. RequireHost veya [Host] parametresi şu olabilir:

  • Ana bilgisayar: www.domain.com, herhangi bir bağlantı noktasıyla eşleşir www.domain.com .
  • Joker karakterli konak: *.domain.com, , subdomain.domain.comveya www.subdomain.domain.com herhangi bir bağlantı noktasında eşleşirwww.domain.com.
  • Bağlantı noktası: *:5000, 5000 numaralı bağlantı noktasını herhangi bir konakla eşleştirir.
  • Konak ve bağlantı noktası: www.domain.com:5000 veya *.domain.com:5000, konak ve bağlantı noktasıyla eşleşir.

veya [Host]kullanılarak RequireHost birden çok parametre belirtilebilir. Kısıtlama, parametrelerden herhangi biri için geçerli olan konaklarla eşleşir. Örneğin, [Host("domain.com", "*.domain.com")] , www.domain.comve subdomain.domain.comile eşleşirdomain.com.

Aşağıdaki kod, belirtilen konağın yolda gerekli olmasını sağlamak için kullanır RequireHost :

app.MapGet("/", () => "Contoso").RequireHost("contoso.com");
app.MapGet("/", () => "AdventureWorks").RequireHost("adventure-works.com");

app.MapHealthChecks("/healthz").RequireHost("*:8080");

Aşağıdaki kod, belirtilen konaklardan herhangi birini gerektirmek için denetleyicideki özniteliğini kullanır [Host] :

[Host("contoso.com", "adventure-works.com")]
public class HostsController : Controller
{
    public IActionResult Index() =>
        View();

    [Host("example.com")]
    public IActionResult Example() =>
        View();
}

[Host] Özniteliği hem denetleyiciye hem de eylem yöntemine uygulandığında:

  • Eylemdeki özniteliği kullanılır.
  • Denetleyici özniteliği yoksayılır.

Yol grupları

Uzantı yöntemi, MapGroup ortak bir ön eke sahip uç nokta gruplarını düzenlemeye yardımcı olur. Yinelenen kodu azaltır ve uç nokta meta verilerini ekleyen ve WithMetadata gibi RequireAuthorization yöntemlere tek bir çağrıyla tüm uç nokta gruplarını özelleştirmeye olanak tanır.

Örneğin, aşağıdaki kod iki benzer uç nokta grubu oluşturur:

app.MapGroup("/public/todos")
    .MapTodosApi()
    .WithTags("Public");

app.MapGroup("/private/todos")
    .MapTodosApi()
    .WithTags("Private")
    .AddEndpointFilterFactory(QueryPrivateTodos)
    .RequireAuthorization();


EndpointFilterDelegate QueryPrivateTodos(EndpointFilterFactoryContext factoryContext, EndpointFilterDelegate next)
{
    var dbContextIndex = -1;

    foreach (var argument in factoryContext.MethodInfo.GetParameters())
    {
        if (argument.ParameterType == typeof(TodoDb))
        {
            dbContextIndex = argument.Position;
            break;
        }
    }

    // Skip filter if the method doesn't have a TodoDb parameter.
    if (dbContextIndex < 0)
    {
        return next;
    }

    return async invocationContext =>
    {
        var dbContext = invocationContext.GetArgument<TodoDb>(dbContextIndex);
        dbContext.IsPrivate = true;

        try
        {
            return await next(invocationContext);
        }
        finally
        {
            // This should only be relevant if you're pooling or otherwise reusing the DbContext instance.
            dbContext.IsPrivate = false;
        }
    };
}
public static RouteGroupBuilder MapTodosApi(this RouteGroupBuilder group)
{
    group.MapGet("/", GetAllTodos);
    group.MapGet("/{id}", GetTodo);
    group.MapPost("/", CreateTodo);
    group.MapPut("/{id}", UpdateTodo);
    group.MapDelete("/{id}", DeleteTodo);

    return group;
}

Bu senaryoda, sonuçta üst bilgi 201 Created için Location göreli bir adres kullanabilirsiniz:

public static async Task<Created<Todo>> CreateTodo(Todo todo, TodoDb database)
{
    await database.AddAsync(todo);
    await database.SaveChangesAsync();

    return TypedResults.Created($"{todo.Id}", todo);
}

İlk uç nokta grubu yalnızca ön ekli /public/todos isteklerle eşleşir ve kimlik doğrulaması olmadan erişilebilir. İkinci uç nokta grubu yalnızca ön ekli isteklerle /private/todos eşleşir ve kimlik doğrulaması gerektirir.

QueryPrivateTodosUç nokta filtresi fabrikası, özel todo verilerine erişmeye ve bunları depolamaya izin vermek için yol işleyicisinin TodoDb parametrelerini değiştiren yerel bir işlevdir.

Yol grupları, yol parametreleri ve kısıtlamalarıyla iç içe grupları ve karmaşık ön ek desenlerini de destekler. Aşağıdaki örnekte, gruba eşlenen user ve yol işleyicisi dış grup ön eklerinde tanımlanan ve {group} yol parametrelerini yakalayabilir{org}.

Ön ek de boş olabilir. Bu, yol desenini değiştirmeden bir uç nokta grubuna uç nokta meta verileri veya filtreleri eklemek için yararlı olabilir.

var all = app.MapGroup("").WithOpenApi();
var org = all.MapGroup("{org}");
var user = org.MapGroup("{user}");
user.MapGet("", (string org, string user) => $"{org}/{user}");

Bir gruba filtre veya meta veri eklemek, bir iç gruba veya belirli bir uç noktaya eklenmiş olabilecek ek filtreler veya meta veriler eklemeden önce bunları her uç noktaya tek tek eklemekle aynı şekilde davranır.

var outer = app.MapGroup("/outer");
var inner = outer.MapGroup("/inner");

inner.AddEndpointFilter((context, next) =>
{
    app.Logger.LogInformation("/inner group filter");
    return next(context);
});

outer.AddEndpointFilter((context, next) =>
{
    app.Logger.LogInformation("/outer group filter");
    return next(context);
});

inner.MapGet("/", () => "Hi!").AddEndpointFilter((context, next) =>
{
    app.Logger.LogInformation("MapGet filter");
    return next(context);
});

Yukarıdaki örnekte dış filtre, ikinci kez eklenmiş olsa bile gelen isteği iç filtreden önce günlüğe kaydeder. Filtreler farklı gruplara uygulandığından, birbirlerine göre eklendikleri sıra önemli değildir. Sipariş filtrelerinin eklenmesi, aynı gruba veya belirli bir uç noktaya uygulandığında önemlidir.

için bir istek /outer/inner/ aşağıdakileri günlüğe kaydeder:

/outer group filter
/inner group filter
MapGet filter

Yönlendirme için performans kılavuzu

Bir uygulamada performans sorunları olduğunda, yönlendirme genellikle sorun olarak şüphelenilir. Yönlendirmenin nedeni, denetleyiciler ve Razor Sayfalar gibi çerçevelerin günlüğe kaydetme iletilerinde çerçeve içinde harcanan süreyi raporlamasıdır. Denetleyiciler tarafından bildirilen süre ile isteğin toplam süresi arasında önemli bir fark olduğunda:

  • Geliştiriciler, sorunun kaynağı olarak uygulama kodlarını ortadan kaldırır.
  • Bunun nedeninin yönlendirme olduğunu varsaymak yaygın bir durumdur.

Yönlendirme, binlerce uç nokta kullanılarak performans testi yapılır. Tipik bir uygulamanın yalnızca çok büyük olmasıyla bir performans sorunuyla karşılaşma olasılığı düşüktür. Yavaş yönlendirme performansının en yaygın kök nedeni genellikle kötü davranan bir özel ara yazılımdır.

Aşağıdaki kod örneği, gecikme kaynağını daraltmayla ilgili temel bir tekniği gösterir:

var logger = app.Services.GetRequiredService<ILogger<Program>>();

app.Use(async (context, next) =>
{
    var stopwatch = Stopwatch.StartNew();
    await next(context);
    stopwatch.Stop();

    logger.LogInformation("Time 1: {ElapsedMilliseconds}ms", stopwatch.ElapsedMilliseconds);
});

app.UseRouting();

app.Use(async (context, next) =>
{
    var stopwatch = Stopwatch.StartNew();
    await next(context);
    stopwatch.Stop();

    logger.LogInformation("Time 2: {ElapsedMilliseconds}ms", stopwatch.ElapsedMilliseconds);
});

app.UseAuthorization();

app.Use(async (context, next) =>
{
    var stopwatch = Stopwatch.StartNew();
    await next(context);
    stopwatch.Stop();

    logger.LogInformation("Time 3: {ElapsedMilliseconds}ms", stopwatch.ElapsedMilliseconds);
});

app.MapGet("/", () => "Timing Test.");

Zaman yönlendirme:

  • Önceki kodda gösterilen zamanlama ara yazılımının bir kopyasıyla her ara yazılımı birbirine ekleyin.
  • Zamanlama verilerini kodla ilişkilendirmek için benzersiz bir tanımlayıcı ekleyin.

Bu, örneğin değerinden daha 10msönemli olduğunda gecikmeyi daraltmak için temel bir yoldur. Raporlardan Time 1 ara yazılım içinde harcanan UseRouting süreyi çıkarmaTime 2.

Aşağıdaki kod, önceki zamanlama koduna daha kompakt bir yaklaşım kullanır:

public sealed class AutoStopwatch : IDisposable
{
    private readonly ILogger _logger;
    private readonly string _message;
    private readonly Stopwatch _stopwatch;
    private bool _disposed;

    public AutoStopwatch(ILogger logger, string message) =>
        (_logger, _message, _stopwatch) = (logger, message, Stopwatch.StartNew());

    public void Dispose()
    {
        if (_disposed)
        {
            return;
        }

        _logger.LogInformation("{Message}: {ElapsedMilliseconds}ms",
            _message, _stopwatch.ElapsedMilliseconds);

        _disposed = true;
    }
}
var logger = app.Services.GetRequiredService<ILogger<Program>>();
var timerCount = 0;

app.Use(async (context, next) =>
{
    using (new AutoStopwatch(logger, $"Time {++timerCount}"))
    {
        await next(context);
    }
});

app.UseRouting();

app.Use(async (context, next) =>
{
    using (new AutoStopwatch(logger, $"Time {++timerCount}"))
    {
        await next(context);
    }
});

app.UseAuthorization();

app.Use(async (context, next) =>
{
    using (new AutoStopwatch(logger, $"Time {++timerCount}"))
    {
        await next(context);
    }
});

app.MapGet("/", () => "Timing Test.");

Potansiyel olarak pahalı yönlendirme özellikleri

Aşağıdaki liste, temel yol şablonlarıyla karşılaştırıldığında nispeten pahalı yönlendirme özellikleri hakkında bazı içgörüler sağlar:

  • Normal ifadeler: Karmaşık olan veya az miktarda girişle uzun süre çalışan normal ifadeler yazmak mümkündür.
  • Karmaşık segmentler ({x}-{y}-{z}):
    • Normal URL yolu kesimini ayrıştırmaktan çok daha pahalıdır.
    • Daha fazla alt dizenin ayrılmasına neden olur.
  • Zaman uyumlu veri erişimi: Birçok karmaşık uygulamanın yönlendirmesinin bir parçası olarak veritabanı erişimi vardır. zaman uyumsuz olan ve EndpointSelectorContextgibi MatcherPolicy genişletilebilirlik noktalarını kullanın.

Büyük rota tabloları için rehberlik

Varsayılan olarak ASP.NET Core, belleği CPU süresiyle takas eden bir yönlendirme algoritması kullanır. Bu, yol eşleştirme zamanının yol sayısına değil, yalnızca eşleşecek yolun uzunluğuna bağlı olması iyi bir etkiye sahiptir. Ancak, uygulamanın çok fazla sayıda yolu (binler) olduğunda ve yollarda yüksek miktarda değişken ön eki bulunduğunda, bu yaklaşım bazı durumlarda sorunlu olabilir. Örneğin, yolların yolunun erken segmentlerinde parametreleri varsa, örneğin {parameter}/some/literal.

Bir uygulamanın aşağıdakiler dışında bunun bir sorun olduğu bir durumla karşılaşmış olma olasılığı düşüktür:

  • Uygulamada bu deseni kullanan çok sayıda yol vardır.
  • Uygulamada çok sayıda yol vardır.

Bir uygulamanın büyük yol tablosu sorunuyla karşılaşıp karşılaşmadığını belirleme

  • Aranacak iki belirti vardır:
    • Uygulama ilk istekte yavaş başlatılıyor.
      • Bunun gerekli olduğunu ancak yeterli olmadığını unutmayın. Yavaş uygulama başlatmaya neden olabilecekden çok daha fazla yol dışı sorun vardır. Uygulamanın bu durumla karşılaştığını doğru bir şekilde belirlemek için aşağıdaki koşulu denetleyin.
    • Uygulama, başlatma sırasında çok fazla bellek tüketir ve bellek dökümü çok sayıda Microsoft.AspNetCore.Routing.Matching.DfaNode örnek gösterir.

Bu sorunu giderme

Bu senaryoya büyük ölçüde iyileştirecek yollara çeşitli teknikler ve iyileştirmeler uygulanabilir:

  • Mümkün olduğunda parametrelerinize {parameter:int}{parameter:guid}, , {parameter:regex(\\d+)}vb. yol kısıtlamaları uygulayın.
    • Bu, yönlendirme algoritmasının eşleştirme için kullanılan yapıları dahili olarak iyileştirmesini ve kullanılan belleği önemli ölçüde azaltmasını sağlar.
    • Çoğu durumda bu, kabul edilebilir bir davranışa geri dönmek için yeterli olacaktır.
  • Parametreleri şablondaki sonraki segmentlere taşımak için yolları değiştirin.
    • Bu, olası "yol" sayısını bir yol verilen uç noktayla eşleşecek şekilde azaltır.
  • Dinamik bir yol kullanın ve bir denetleyici/sayfaya eşlemeyi dinamik olarak gerçekleştirin.
    • Bu, ve MapDynamicPageRoutekullanılarak MapDynamicControllerRoute gerçekleştirilebilir.

Kitaplık yazarları için rehberlik

Bu bölüm, yönlendirmenin üzerine inşa eden kitaplık yazarları için rehberlik içerir. Bu ayrıntılar, uygulama geliştiricilerinin yönlendirmeyi genişleten kitaplıkları ve çerçeveleri kullanarak iyi bir deneyim elde etmelerini sağlamaya yöneliktir.

Uç noktaları tanımlama

URL eşleştirmesi için yönlendirme kullanan bir çerçeve oluşturmak için, üzerinde UseEndpointsderleyen bir kullanıcı deneyimi tanımlayarak başlayın.

DO , üzerinde derleyin IEndpointRouteBuilder. Bu, kullanıcıların kafa karışıklığı olmadan diğer ASP.NET Core özellikleriyle çerçevenizi oluşturmasına olanak tanır. Her ASP.NET Core şablonu yönlendirme içerir. Yönlendirmenin kullanıcılar için mevcut ve tanıdık olduğunu varsayın.

// Your framework
app.MapMyFramework(...);

app.MapHealthChecks("/healthz");

DO, uygulayan IEndpointConventionBuilderçağrısından korumalı bir MapMyFramework(...) beton türü döndürür. Çoğu çerçeve Map... yöntemi bu deseni izler. Arabirim IEndpointConventionBuilder :

  • Meta verilerin oluşmasına izin verir.
  • Çeşitli uzantı yöntemleri tarafından hedeflenmiştir.

Kendi türünüzü bildirmeniz, oluşturucuya kendi çerçeveye özgü işlevselliğinizi eklemenize olanak tanır. Çerçeve tarafından bildirilen bir oluşturucuyu sarmalayıp çağrıları ona iletmenin bir sakıncası yok.

// Your framework
app.MapMyFramework(...)
    .RequireAuthorization()
    .WithMyFrameworkFeature(awesome: true);

app.MapHealthChecks("/healthz");

Kendi EndpointDataSourceyazınızı yazmayı göz önünde bulundurun. EndpointDataSource , bir uç nokta koleksiyonunu bildirmeye ve güncelleştirmeye yönelik alt düzey temel öğedir. EndpointDataSource , denetleyiciler ve Razor Sayfalar tarafından kullanılan güçlü bir API'dir.

Yönlendirme testlerinin temel bir güncelleştirilmemiş veri kaynağı örneği vardır.

uygulamayı GetGroupedEndpointsGÖZ ÖNÜNDE BULUNDURUN. Bu, grup kurallarını çalıştırma ve gruplandırılmış uç noktalarda son meta veriler üzerinde tam denetim sağlar. Örneğin bu, özel EndpointDataSource uygulamaların gruplara eklenen uç nokta filtrelerini çalıştırmasına olanak tanır.

Varsayılan olarak bir EndpointDataSource kaydetmeyi DENEMEYİN. Kullanıcıların çerçevenizi ' UseEndpointsye kaydetmesini gerektirin. Yönlendirmenin felsefesi, varsayılan olarak hiçbir şeyin dahil olmadığını ve uç noktaların kaydedildiği yerdir UseEndpoints .

Yönlendirmeyle tümleşik ara yazılım oluşturma

Meta veri türlerini arabirim olarak tanımlamayı GÖZ ÖNÜNDE BULUNDURUN .

DO , meta veri türlerini sınıflarda ve yöntemlerde öznitelik olarak kullanmayı mümkün hale getirir.

public interface ICoolMetadata
{
    bool IsCool { get; }
}

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CoolMetadataAttribute : Attribute, ICoolMetadata
{
    public bool IsCool => true;
}

Denetleyiciler ve Razor Sayfalar gibi çerçeveler, meta veri özniteliklerinin türlere ve yöntemlere uygulanmasını destekler. Meta veri türlerini bildirirseniz:

  • Bunları öznitelik olarak erişilebilir hale getirin.
  • Kullanıcıların çoğu öznitelikleri uygulama konusunda bilgi sahibidir.

Bir meta veri türünün arabirim olarak bildirilmesi başka bir esneklik katmanı ekler:

  • Arabirimler birleştirilebilir.
  • Geliştiriciler, birden çok ilkeyi birleştiren kendi türlerini bildirebilir.

AŞAĞıDAKI örnekte gösterildiği gibi meta verileri geçersiz kılmayı mümkün kılamaz:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class SuppressCoolMetadataAttribute : Attribute, ICoolMetadata
{
    public bool IsCool => false;
}

[CoolMetadata]
public class MyController : Controller
{
    public void MyCool() { }

    [SuppressCoolMetadata]
    public void Uncool() { }
}

Bu yönergeleri izlemenin en iyi yolu, işaretçi meta verilerini tanımlamaktan kaçınmaktır:

  • Yalnızca meta veri türünün varlığına bakmayın.
  • Meta verilerde bir özellik tanımlayın ve özelliğini denetleyin.

Meta veri koleksiyonu sıralanır ve önceliğe göre geçersiz kılmayı destekler. Denetleyiciler söz konusu olduğunda, eylem yöntemindeki meta veriler en belirgindir.

DO , ara yazılımları yönlendirme ile ve yönlendirme olmadan kullanışlı hale getirir:

app.UseAuthorization(new AuthorizationPolicy() { ... });

// Your framework
app.MapMyFramework(...).RequireAuthorization();

Bu kılavuza örnek olarak ara yazılımı göz önünde bulundurun UseAuthorization . Yetkilendirme ara yazılımı bir geri dönüş ilkesi geçirmenizi sağlar. Geri dönüş ilkesi belirtilirse her ikisi için de geçerlidir:

  • Belirtilen ilke olmayan uç noktalar.
  • Uç noktayla eşleşmeyen istekler.

Bu, yetkilendirme ara yazılımını yönlendirme bağlamı dışında kullanışlı hale getirir. Yetkilendirme ara yazılımı geleneksel ara yazılım programlama için kullanılabilir.

Tanılama hatalarını ayıklama

Ayrıntılı yönlendirme tanılama çıktısı için olarak DebugayarlayınLogging:LogLevel:Microsoft. Geliştirme ortamında, içinde günlük düzeyini appsettings.Development.jsonayarlayın:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Debug",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

Ek kaynaklar

Yönlendirme, gelen HTTP isteklerini eşleştirmek ve bu istekleri uygulamanın yürütülebilir uç noktalarına göndermekle sorumludur. Uç noktalar , uygulamanın yürütülebilir istek işleme kodu birimleridir. Uç noktalar uygulamada tanımlanır ve uygulama başlatıldığında yapılandırılır. Uç nokta eşleştirme işlemi, isteğin URL'sinden değerleri ayıklayabilir ve istek işleme için bu değerleri sağlayabilir. Yönlendirme, uygulamadaki uç nokta bilgilerini kullanarak uç noktalara eşleyen URL'ler de oluşturabilir.

Uygulamalar yönlendirmeyi şu şekilde yapılandırabilir:

  • Denetleyiciler
  • Razor Pages
  • SignalR
  • gRPC Hizmetleri
  • Sistem Durumu Denetimleri gibi uç nokta özellikli ara yazılım.
  • Yönlendirme ile kaydedilen temsilciler ve lambdalar.

Bu makale, ASP.NET Core yönlendirmesinin alt düzey ayrıntılarını kapsar. Yönlendirmeyi yapılandırma hakkında bilgi için:

Yönlendirmeyle ilgili temel bilgiler

Aşağıdaki kod, yönlendirmenin temel bir örneğini gösterir:

var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();

app.MapGet("/", () => "Hello World!");

app.Run();

Yukarıdaki örnek, yöntemini kullanan MapGet tek bir uç nokta içerir:

  • Kök URL'ye /bir HTTP GET isteği gönderildiğinde:
    • İstek temsilcisi yürütülür.
    • Hello World! HTTP yanıtına yazılır.
  • İstek yöntemi değilse GET veya kök URL değilse /, hiçbir yol eşleşmez ve bir HTTP 404 döndürülür.

Yönlendirme, ve UseEndpointstarafından UseRouting kaydedilen bir ara yazılım çifti kullanır:

  • UseRouting ara yazılım işlem hattına yol eşleştirmesi ekler. Bu ara yazılım, uygulamada tanımlanan uç nokta kümesine bakar ve isteğe göre en iyi eşleşmeyi seçer.
  • UseEndpoints ara yazılım işlem hattına uç nokta yürütme ekler. Seçili uç noktayla ilişkili temsilciyi çalıştırır.

Uygulamaların genellikle veya UseEndpointsaraması UseRouting gerekmez. WebApplicationBuilderve UseEndpointsile UseRouting eklenen Program.cs ara yazılımı sarmalayan bir ara yazılım işlem hattı yapılandırıyor. Ancak, uygulamalar bu yöntemleri açıkça çağırarak ve UseEndpoints çalıştırma sırasını UseRouting değiştirebilir. Örneğin, aşağıdaki kod için UseRoutingaçık bir çağrı yapar:

app.Use(async (context, next) =>
{
    // ...
    await next(context);
});

app.UseRouting();

app.MapGet("/", () => "Hello World!");

Önceki kodda:

  • çağrısı app.Use , işlem hattının başında çalışan özel bir ara yazılımı kaydeder.
  • çağrısıUseRouting, özel ara yazılımdan sonra çalıştırılacak yol eşleştirme ara yazılımını yapılandırıyor.
  • ile MapGet kaydedilen uç nokta işlem hattının sonunda çalışır.

Yukarıdaki örnekte çağrısı UseRoutingyoksa, özel ara yazılım yol eşleştirme ara yazılımından sonra çalıştırılırdı.

Uç Noktalar

MapGet yöntemi bir uç nokta tanımlamak için kullanılır. Uç nokta şu şekilde olabilir:

  • URL ve HTTP yöntemiyle eşleştirilerek seçilir.
  • Temsilci çalıştırılarak yürütülür.

Uygulama tarafından eşleştirilebilen ve yürütülebilen uç noktalar içinde UseEndpointsyapılandırılır. Örneğin, MapGet, MapPostve benzer yöntemler istek temsilcilerini yönlendirme sistemine bağlar. ASP.NET Core çerçeve özelliklerini yönlendirme sistemine bağlamak için ek yöntemler kullanılabilir:

Aşağıdaki örnekte daha gelişmiş bir yol şablonuyla yönlendirme gösterilmektedir:

app.MapGet("/hello/{name:alpha}", (string name) => $"Hello {name}!");

Dize /hello/{name:alpha} bir yol şablonudur. Uç noktanın nasıl eşleşeceklerini yapılandırmak için bir yol şablonu kullanılır. Bu durumda şablon aşağıdakiyle eşleşir:

  • Gibi bir URL /hello/Docs
  • ile /hello/ başlayan ve ardından alfabetik karakter dizisi gelen herhangi bir URL yolu. :alpha yalnızca alfabetik karakterlerle eşleşen bir yol kısıtlaması uygular. Yol kısıtlamaları bu makalenin devamında açıklanmıştır.

URL yolunun ikinci kesimi: {name:alpha}

Aşağıdaki örnekte sistem durumu denetimleri ve yetkilendirme ile yönlendirme gösterilmektedir:

app.UseAuthentication();
app.UseAuthorization();

app.MapHealthChecks("/healthz").RequireAuthorization();
app.MapGet("/", () => "Hello World!");

Yukarıdaki örnekte aşağıdakiler gösterilmiştir:

  • Yetkilendirme ara yazılımı yönlendirme ile kullanılabilir.
  • Yetkilendirme davranışını yapılandırmak için uç noktalar kullanılabilir.

Çağrısı bir MapHealthChecks sistem durumu denetimi uç noktası ekler. Bu çağrıya zincirleme RequireAuthorization , uç noktaya bir yetkilendirme ilkesi ekler.

Arama UseAuthentication ve UseAuthorization kimlik doğrulama ve yetkilendirme ara yazılımını ekler. Bu ara yazılım, şunları yapabilecekleri şekilde ve UseEndpoints arasına UseRouting yerleştirilir:

  • tarafından UseRoutinghangi uç noktanın seçildiğini görün.
  • Uç noktaya göndermeden önce UseEndpoints bir yetkilendirme ilkesi uygulayın.

Uç nokta meta verileri

Yukarıdaki örnekte iki uç nokta vardır, ancak yalnızca sistem durumu denetimi uç noktasının bir yetkilendirme ilkesi eklenmiştir. İstek sistem durumu denetimi uç noktasıyla /healthzeşleşiyorsa yetkilendirme denetimi gerçekleştirilir. Bu, uç noktaların bunlara ek veri ekleyebileceğini gösterir. Bu ek veriler uç nokta meta verileri olarak adlandırılır:

  • Meta veriler yönlendirme kullanan ara yazılım tarafından işlenebilir.
  • Meta veriler herhangi bir .NET türünde olabilir.

Yönlendirme kavramları

Yönlendirme sistemi, güçlü uç nokta kavramını ekleyerek ara yazılım işlem hattının üzerine inşa eder. Uç noktalar yönlendirme, yetkilendirme ve herhangi bir sayıda ASP.NET Core sistemi açısından birbirinden ayrı olan uygulama işlevlerinin birimlerini temsil eder.

ASP.NET Temel uç nokta tanımı

ASP.NET Core uç noktası:

Aşağıdaki kod, geçerli istekle eşleşen uç noktanın nasıl alınıp denetlendiğini gösterir:

app.Use(async (context, next) =>
{
    var currentEndpoint = context.GetEndpoint();

    if (currentEndpoint is null)
    {
        await next(context);
        return;
    }

    Console.WriteLine($"Endpoint: {currentEndpoint.DisplayName}");

    if (currentEndpoint is RouteEndpoint routeEndpoint)
    {
        Console.WriteLine($"  - Route Pattern: {routeEndpoint.RoutePattern}");
    }

    foreach (var endpointMetadata in currentEndpoint.Metadata)
    {
        Console.WriteLine($"  - Metadata: {endpointMetadata}");
    }

    await next(context);
});

app.MapGet("/", () => "Inspect Endpoint.");

Uç nokta seçilirse öğesinden HttpContextalınabilir. Özellikleri incelenebilir. Uç nokta nesneleri sabittir ve oluşturulduktan sonra değiştirilemez. En yaygın uç nokta türü bir RouteEndpoint'dir. RouteEndpoint , yönlendirme sistemi tarafından seçilmesini sağlayan bilgileri içerir.

Önceki kodda, uygulama. Kullan , satır içi ara yazılımı yapılandırıyor.

Aşağıdaki kod, işlem hattında çağrılan yere app.Use bağlı olarak bir uç nokta bulunmayabileceğini gösterir:

// Location 1: before routing runs, endpoint is always null here.
app.Use(async (context, next) =>
{
    Console.WriteLine($"1. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    await next(context);
});

app.UseRouting();

// Location 2: after routing runs, endpoint will be non-null if routing found a match.
app.Use(async (context, next) =>
{
    Console.WriteLine($"2. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    await next(context);
});

// Location 3: runs when this endpoint matches
app.MapGet("/", (HttpContext context) =>
{
    Console.WriteLine($"3. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    return "Hello World!";
}).WithDisplayName("Hello");

app.UseEndpoints(_ => { });

// Location 4: runs after UseEndpoints - will only run if there was no match.
app.Use(async (context, next) =>
{
    Console.WriteLine($"4. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    await next(context);
});

Yukarıdaki örnek, bir uç noktanın seçili olup olmadığını görüntüleyen deyimler ekler Console.WriteLine . Netlik sağlamak için örnek, sağlanan / uç noktaya bir görünen ad atar.

Yukarıdaki örnek ayrıca, bu ara yazılımların işlem hattı içinde tam olarak ne zaman çalıştığını denetlemek için ve UseEndpoints çağrılarını UseRouting içerir.

Bu kodu ekranların URL'si / ile çalıştırma:

1. Endpoint: (null)
2. Endpoint: Hello
3. Endpoint: Hello

Bu kodu başka herhangi bir URL ile çalıştırmak şunu görüntüler:

1. Endpoint: (null)
2. Endpoint: (null)
4. Endpoint: (null)

Bu çıkış şunları gösterir:

  • Çağrılmadan önce UseRouting uç nokta her zaman null'tır.
  • Eşleşme bulunursa, ile UseEndpointsarasında UseRouting uç nokta null değildir.
  • Bir UseEndpoints eşleşme bulunduğunda ara yazılım terminaldir . Terminal ara yazılımı bu makalenin devamında tanımlanmıştır.
  • Yürüttkten sonra UseEndpoints ara yazılım yalnızca eşleşme bulunamadığında yürütülür.

Ara yazılım, UseRouting uç noktayı geçerli bağlama eklemek için yöntemini kullanır SetEndpoint . Ara yazılımı özel mantıkla değiştirmek UseRouting ve yine de uç noktaları kullanmanın avantajlarından yararlanmak mümkündür. Uç noktalar ara yazılım gibi alt düzey bir temel öğedir ve yönlendirme uygulamasıyla birleştirilmiş değildir. Çoğu uygulamanın özel mantıkla değiştirilmesi UseRouting gerekmez.

Ara UseEndpoints yazılım, ara yazılımla UseRouting birlikte kullanılacak şekilde tasarlanmıştır. Bir uç noktayı yürütmek için temel mantık karmaşık değildir. Uç noktayı almak ve ardından özelliğini RequestDelegate çağırmak için kullanınGetEndpoint.

Aşağıdaki kodda ara yazılımların yönlendirmeyi nasıl etkilediği veya buna nasıl tepki gösterebileceği gösterilmektedir:

app.UseHttpMethodOverride();
app.UseRouting();

app.Use(async (context, next) =>
{
    if (context.GetEndpoint()?.Metadata.GetMetadata<RequiresAuditAttribute>() is not null)
    {
        Console.WriteLine($"ACCESS TO SENSITIVE DATA AT: {DateTime.UtcNow}");
    }

    await next(context);
});

app.MapGet("/", () => "Audit isn't required.");
app.MapGet("/sensitive", () => "Audit required for sensitive data.")
    .WithMetadata(new RequiresAuditAttribute());
public class RequiresAuditAttribute : Attribute { }

Yukarıdaki örnekte iki önemli kavram gösterilmektedir:

  • Ara yazılım, yönlendirmenin üzerinde çalıştığı verileri değiştirmek için daha önce UseRouting çalışabilir.
  • Ara yazılım, uç nokta yürütülmeden önce yönlendirme sonuçlarını işlemek için ve UseEndpoints arasında UseRouting çalışabilir.
    • ile UseEndpointsarasında UseRouting çalışan ara yazılım:
      • Genellikle uç noktaları anlamak için meta verileri inceler.
      • ve tarafından UseAuthorizationUseCorsyapıldığı gibi genellikle güvenlik kararları alır.
    • Ara yazılım ve meta verilerin birleşimi, uç nokta başına ilkelerin yapılandırılmasına olanak tanır.

Yukarıdaki kod, uç nokta başına ilkeleri destekleyen özel bir ara yazılım örneğini gösterir. Ara yazılım, konsola hassas verilere erişimin denetim günlüğünü yazar. Ara yazılım, meta verilerle RequiresAuditAttribute bir uç noktayı denetleyecek şekilde yapılandırılabilir. Bu örnek, yalnızca hassas olarak işaretlenmiş uç noktaların denetlendiği bir kabul etme deseni gösterir. Bu mantığı tersten tanımlamak, örneğin güvenli olarak işaretlenmemiş her şeyi denetlemek mümkündür. Uç nokta meta veri sistemi esnektir. Bu mantık, kullanım örneğine uygun şekilde tasarlanabilir.

Yukarıdaki örnek kod, uç noktaların temel kavramlarını göstermeye yöneliktir. Örnek, üretim kullanımı için tasarlanmamıştır. Denetim günlüğü ara yazılımının daha eksiksiz bir sürümü şunları yapar:

  • Bir dosyada veya veritabanında oturum açın.
  • Kullanıcı, IP adresi, hassas uç noktanın adı ve daha fazlası gibi ayrıntıları ekleyin.

Denetim ilkesi meta verileriRequiresAuditAttribute, denetleyiciler ve SignalRgibi sınıf tabanlı çerçevelerle daha kolay kullanım için olarak Attribute tanımlanır. Koda giden yol kullanılırken:

  • Meta veriler bir oluşturucu API'siyle eklenir.
  • Sınıf tabanlı çerçeveler, uç noktaları oluştururken ilgili yöntem ve sınıftaki tüm öznitelikleri içerir.

Meta veri türleri için en iyi yöntemler bunları arabirim veya öznitelik olarak tanımlamaktır. Arabirimler ve öznitelikler kodun yeniden kullanılmasına izin verir. Meta veri sistemi esnektir ve herhangi bir sınırlama getirmez.

Terminal ara yazılımını yönlendirme ile karşılaştırma

Aşağıdaki örnekte hem terminal ara yazılımı hem de yönlendirme gösterilmektedir:

// Approach 1: Terminal Middleware.
app.Use(async (context, next) =>
{
    if (context.Request.Path == "/")
    {
        await context.Response.WriteAsync("Terminal Middleware.");
        return;
    }

    await next(context);
});

app.UseRouting();

// Approach 2: Routing.
app.MapGet("/Routing", () => "Routing.");

ile Approach 1: gösterilen ara yazılım stili, terminal ara yazılımıdır. Eşleşen bir işlem yaptığı için buna terminal ara yazılımı denir:

  • Yukarıdaki örnekteki eşleştirme işlemi ara yazılıma ve Path == "/Routing" yönlendirmeye yöneliktirPath == "/".
  • Eşleşme başarılı olduğunda ara yazılımı çağırmak next yerine bazı işlevleri yürütür ve döndürür.

Aramayı sonlandırdığından, bazı işlevler yürüttüğünden ve ardından döndürdüğünden terminal ara yazılımı olarak adlandırılır.

Aşağıdaki liste, terminal ara yazılımını yönlendirme ile karşılaştırır:

  • Her iki yaklaşım da işlem hattını sonlandırmaya olanak sağlar:
    • Ara yazılım, çağırmak yerine döndürerek işlem hattını sonlandırır next.
    • Uç noktalar her zaman terminaldir.
  • Terminal ara yazılımı, ara yazılımı işlem hattında rastgele bir yere konumlandırmaya olanak tanır:
  • Terminal ara yazılımı, ara yazılımın ne zaman eşleşeceğini belirlemek için rastgele koda izin verir:
    • Özel yol eşleştirme kodu ayrıntılı olabilir ve doğru yazılması zor olabilir.
    • Yönlendirme, tipik uygulamalar için basit çözümler sağlar. Çoğu uygulama özel yol eşleştirme kodu gerektirmez.
  • ve UseCorsgibi UseAuthorization ara yazılımlarla uç noktalar arabirimi.
    • veya ile UseAuthorizationUseCors terminal ara yazılımı kullanmak için yetkilendirme sistemiyle el ile birlikte çalışma gerekir.

nokta her ikisini de tanımlar:

  • İstekleri işlemek için bir temsilci.
  • Rastgele meta veriler koleksiyonu. Meta veriler, her uç noktaya eklenen ilkelere ve yapılandırmaya göre çapraz kesme endişeleri uygulamak için kullanılır.

Terminal ara yazılımı etkili bir araç olabilir, ancak şunları gerektirebilir:

  • Önemli miktarda kodlama ve test.
  • İstenen esneklik düzeyine ulaşmak için diğer sistemlerle el ile tümleştirme.

Terminal ara yazılımı yazmadan önce yönlendirmeyle tümleştirmeyi göz önünde bulundurun.

Map ile tümleşen veya MapWhen genellikle yönlendirme kullanan bir uç noktaya dönüştürülebilen mevcut terminal ara yazılımı. MapHealthChecks , yönlendirici yazılımı desenini gösterir:

  • üzerinde IEndpointRouteBuilderbir uzantı yöntemi yazın.
  • kullanarak CreateApplicationBuilderiç içe bir ara yazılım işlem hattı oluşturun.
  • Ara yazılımı yeni işlem hattına ekleyin. Bu durumda, UseHealthChecks.
  • Buildara yazılım işlem hattı içine .RequestDelegate
  • Yeni ara yazılım işlem hattını çağırın Map ve sağlayın.
  • uzantı yönteminden tarafından Map sağlanan oluşturucu nesnesini döndürür.

Aşağıdaki kod MapHealthChecks kullanımını gösterir:

app.UseAuthentication();
app.UseAuthorization();

app.MapHealthChecks("/healthz").RequireAuthorization();

Yukarıdaki örnek, oluşturucu nesnesini döndürmenin neden önemli olduğunu gösterir. Oluşturucu nesnesini döndürmek, uygulama geliştiricisinin uç nokta için yetkilendirme gibi ilkeleri yapılandırmasına olanak tanır. Bu örnekte sistem durumu denetimleri ara yazılımının yetkilendirme sistemiyle doğrudan tümleştirmesi yoktur.

Meta veri sistemi, terminal ara yazılımı kullanılarak genişletilebilirlik yazarlarının karşılaştığı sorunlara yanıt olarak oluşturulmuştur. Her ara yazılım için yetkilendirme sistemiyle kendi tümleştirmesini uygulamak sorunludur.

URL eşleştirme

  • Yönlendirmenin bir uç noktaya gelen istekle eşleşmesi işlemidir.
  • URL yolundaki verileri ve üst bilgileri temel alır.
  • İstekteki tüm verileri dikkate almak için genişletilebilir.

Yönlendirme ara yazılımı yürütürken, geçerli istekten bir istek özelliğine HttpContext ve yönlendirme değerleri ayarlar:Endpoint

  • HttpContext.GetEndpoint çağrısı uç noktayı alır.
  • HttpRequest.RouteValues yol değerlerinin koleksiyonunu alır.

Ara yazılım , yönlendirme ara yazılımı uç noktayı inceleyip işlem gerçekleştirdikten sonra çalışır. Örneğin, yetkilendirme ara yazılımı bir yetkilendirme ilkesi için uç noktanın meta veri koleksiyonunu sorgulayabilir. İstek işleme işlem hattındaki ara yazılımların tümü yürütüldükten sonra seçili uç noktanın temsilcisi çağrılır.

Uç nokta yönlendirmesindeki yönlendirme sistemi, tüm gönderme kararlarının sorumluluğundadır. Ara yazılım, seçili uç noktayı temel alan ilkeler uyguladığından aşağıdakiler önemlidir:

  • Göndermeyi veya güvenlik ilkelerinin uygulanmasını etkileyebilecek tüm karar yönlendirme sistemi içinde alınır.

Uyarı

Geriye dönük uyumluluk için, denetleyici veya Razor Sayfalar uç noktası temsilcisi yürütülürken özellikleri, RouteContext.RouteData şu ana kadar gerçekleştirilen istek işlemeye göre uygun değerlere ayarlanır.

Tür RouteContext , gelecekteki bir sürümde kullanım dışı olarak işaretlenecektir:

  • öğesine geçiş.RouteData.ValuesHttpRequest.RouteValues
  • Uç nokta meta verilerinden almak IDataTokensMetadata için geçişRouteData.DataTokens.

URL eşleştirme, yapılandırılabilir bir aşama kümesinde çalışır. Her aşamada çıkış, bir eşleşme kümesidir. Eşleşme kümesi bir sonraki aşamaya kadar daraltılabilir. Yönlendirme uygulaması, eşleşen uç noktalar için işleme sırasını garanti etmez. Tüm olası eşleşmeler aynı anda işlenir. URL eşleştirme aşamaları aşağıdaki sırada gerçekleşir. ASP.NET Core:

  1. URL yolunu, tüm eşleşmeleri toplayarak uç noktalar kümesine ve bunların yol şablonlarına göre işler.
  2. Önceki listeyi alır ve yol kısıtlamaları uygulanarak başarısız olan eşleşmeleri kaldırır.
  3. Önceki listeyi alır ve örnek kümesinde MatcherPolicy başarısız olan eşleşmeleri kaldırır.
  4. Önceki listeden EndpointSelector son kararı vermek için öğesini kullanır.

Uç nokta listesi aşağıdakilere göre önceliklendirilir:

Eşleşen tüm uç noktalar, öğesine ulaşılana EndpointSelector kadar her aşamada işlenir. EndpointSelector son aşamadır. Eşleşmeler arasından en yüksek öncelikli uç noktayı en iyi eşleşme olarak seçer. En iyi eşleşmeyle aynı önceliğe sahip başka eşleşmeler varsa, belirsiz bir eşleşme özel durumu oluşturulur.

Yol önceliği, daha yüksek önceliğe sahip daha belirli bir yol şablonuna göre hesaplanır. Örneğin, ve şablonlarını /hello/{message}göz önünde bulundurun:

  • Her ikisi de URL yolu ile eşleşer /hello.
  • /hello daha belirgindir ve bu nedenle daha yüksek önceliklidir.

Genel olarak, rota önceliği, uygulamada kullanılan URL düzenleri türleri için en iyi eşleşmeyi seçmek için iyi bir iştir. Yalnızca belirsizlikten kaçınmak için gerektiğinde kullanın Order .

Yönlendirme tarafından sağlanan genişletilebilirlik türleri nedeniyle, yönlendirme sisteminin belirsiz yolları önceden hesaplaması mümkün değildir. Yol şablonları /{message:alpha} ve /{message:int}gibi bir örneği göz önünde bulundurun:

  • Kısıtlama alpha yalnızca alfabetik karakterlerle eşleşir.
  • Kısıtlama int yalnızca sayılarla eşleşir.
  • Bu şablonlar aynı yol önceliğine sahiptir, ancak her ikisi de eşleşen tek bir URL yoktur.
  • Yönlendirme sistemi başlangıçta bir belirsizlik hatası bildirdiyse, bu geçerli kullanım örneğini engeller.

Uyarı

içindeki UseEndpoints işlemlerin sırası, bir özel durum dışında yönlendirme davranışını etkilemez. MapControllerRoute ve MapAreaRoute çağrıldıkları sırayla uç noktalarına otomatik olarak bir sipariş değeri atayın. Bu, eski yönlendirme uygulamalarıyla aynı garantileri sağlayan yönlendirme sistemi olmadan denetleyicilerin uzun süreli davranışının benzetimini oluşturur.

ASP.NET Core'da uç nokta yönlendirme:

  • Rota kavramı yoktur.
  • Sipariş garantisi sağlamaz. Tüm uç noktalar aynı anda işlenir.

Rota şablonu önceliği ve uç nokta seçim sırası

Yol şablonu önceliği , her yol şablonuna ne kadar özel olduğuna göre bir değer atayan bir sistemdir. Yol şablonu önceliği:

  • Sık karşılaşılan durumlarda uç noktaların sırasını ayarlama gereğini önler.
  • Yönlendirme davranışıyla ilgili sağduyunun beklentilerini eşleştirmeye çalışır.

Örneğin, ve /Products/{id}şablonlarını /Products/List göz önünde bulundurun. URL yolundan /Products/Listdaha iyi bir eşleşme /Products/{id} olduğunu /Products/List varsaymak mantıklı olacaktır. Sabit segmentin parametre kesiminden /List/{id}daha iyi önceliğe sahip olduğu kabul edildiğinden bu işe yarar.

Önceliğin nasıl çalıştığına ilişkin ayrıntılar, yol şablonlarının nasıl tanımlandığına göre belirlenir:

  • Daha fazla segmente sahip şablonlar daha belirgin olarak kabul edilir.
  • Değişmez metin içeren bir kesim, parametre kesiminden daha özel olarak kabul edilir.
  • Kısıtlaması olan bir parametre kesimi, olmadan birden fazla özel olarak kabul edilir.
  • Karmaşık bir kesim, kısıtlaması olan bir parametre kesimi olarak özel olarak kabul edilir.
  • Tümünü yakala parametreleri en az belirlidir. Tümünü yakalayolları hakkında önemli bilgiler için Yol şablonları bölümünde tümünü yakala bölümüne bakın.

URL oluşturma kavramları

URL oluşturma:

  • Yönlendirmenin bir yol değerleri kümesine dayalı bir URL yolu oluşturabildiği işlemdir.
  • Uç noktalar ile bunlara erişen URL'ler arasında mantıksal ayrım yapılmasını sağlar.

Uç nokta yönlendirme api'sini LinkGenerator içerir. LinkGenerator , DI'den kullanılabilen tek bir hizmettir. API, LinkGenerator yürütme isteği bağlamının dışında kullanılabilir. Mvc.IUrlHelper ve kullanan Etiket Yardımcıları, HTML Yardımcıları ve Eylem Sonuçları gibi senaryolarIUrlHelper, bağlantı oluşturma özellikleri sağlamak için API'yi dahili olarak kullanırLinkGenerator.

Bağlantı oluşturucu, adres ve adres düzenleri kavramı tarafından yedeklenmiştir. Adres düzeni, bağlantı oluşturma için dikkate alınması gereken uç noktaları belirlemenin bir yoludur. Örneğin, birçok kullanıcının denetleyicilerden aşina olduğu yol adı ve yol değerleri senaryoları ve Razor Sayfalar bir adres düzeni olarak uygulanır.

Bağlantı oluşturucu, aşağıdaki uzantı yöntemleri aracılığıyla denetleyicilere ve Razor Sayfalara bağlanabilir:

Bu yöntemlerin aşırı yüklemeleri, öğesini içeren HttpContextbağımsız değişkenleri kabul eder. Bu yöntemler işlevsel olarak Url.Action ve Url.Page eşdeğerdir, ancak ek esneklik ve seçenekler sunar.

GetPath* Yöntemler, mutlak yol içeren bir URI oluşturmaları için Url.Action ve Url.Pageile en benzerleridir. GetUri* Yöntemler her zaman bir düzen ve konak içeren mutlak bir URI oluşturur. Kabul HttpContext eden yöntemler, yürütme isteği bağlamında bir URI oluşturur. Geçersiz kılınmadıkça, yürütülen istekten ortam yolu değerleri, URL temel yolu, şema ve konak kullanılır.

LinkGenerator bir adresle çağrılır. URI oluşturma işlemi iki adımda gerçekleşir:

  1. Adres, adresle eşleşen uç noktaların listesine bağlıdır.
  2. Sağlanan değerlerle eşleşen bir yol deseni bulunana kadar her uç noktanın RoutePattern değerleri değerlendirilir. Sonuçta elde edilen çıkış, bağlantı oluşturucuya sağlanan diğer URI parçalarıyla birleştirilir ve döndürülür.

tarafından LinkGenerator sağlanan yöntemler, her tür adres için standart bağlantı oluşturma özelliklerini destekler. Bağlantı oluşturucuyu kullanmanın en kolay yolu, belirli bir adres türü için işlemler gerçekleştiren uzantı yöntemleridir:

Uzantı Yöntemi Açıklama
GetPathByAddress Sağlanan değerleri temel alan mutlak bir yola sahip bir URI oluşturur.
GetUriByAddress Sağlanan değerlere göre mutlak bir URI oluşturur.

Uyarı

Çağırma LinkGenerator yöntemlerinin aşağıdaki etkilerine dikkat edin:

  • Gelen isteklerin üst bilgisini doğrulamayan Host bir uygulama yapılandırmasında uzantı yöntemlerini dikkatli kullanınGetUri*. Gelen isteklerin Host üst bilgisi doğrulanmazsa, güvenilmeyen istek girişi bir görünüm veya sayfadaki URI'lerde istemciye geri gönderilebilir. Tüm üretim uygulamalarının, üst bilgiyi bilinen geçerli değerlerle doğrulayacak Host şekilde yapılandırmalarını öneririz.

  • veya ile MapMapWhenbirlikte ara yazılımda dikkatli kullanınLinkGenerator. Map* , bağlantı oluşturmanın çıkışını etkileyen yürütme isteğinin temel yolunu değiştirir. Tüm API'ler LinkGenerator bir temel yol belirtmeye izin verir. Bağlantı oluşturma üzerindeki etkiyi Map* geri almak için boş bir temel yol belirtin.

Ara yazılım örneği

Aşağıdaki örnekte ara yazılım, depo ürünlerini listeleyen bir eylem yöntemine bağlantı oluşturmak için API'yi kullanır LinkGenerator . Bağlantı oluşturucuyu bir sınıfa ekleyerek kullanma ve bir uygulamadaki herhangi bir sınıf için çağrısı GenerateLink yapmak mümkündür:

public class ProductsMiddleware
{
    private readonly LinkGenerator _linkGenerator;

    public ProductsMiddleware(RequestDelegate next, LinkGenerator linkGenerator) =>
        _linkGenerator = linkGenerator;

    public async Task InvokeAsync(HttpContext httpContext)
    {
        httpContext.Response.ContentType = MediaTypeNames.Text.Plain;

        var productsPath = _linkGenerator.GetPathByAction("Products", "Store");

        await httpContext.Response.WriteAsync(
            $"Go to {productsPath} to see our products.");
    }
}

Yol şablonları

içindeki {} belirteçler, yol eşleşirse bağlı olan yol parametrelerini tanımlar. Yol kesiminde birden fazla yol parametresi tanımlanabilir, ancak yol parametreleri değişmez değerle ayrılmalıdır. Örneğin:

{controller=Home}{action=Index}

geçerli bir yol değildir, çünkü ile {action}arasında {controller} değişmez değer yoktur. Yol parametreleri bir ada sahip olmalı ve ek öznitelikler belirtilmiş olabilir.

Yol parametreleri dışındaki değişmez metin (örneğin, {id}) ve yol ayırıcı / url'deki metinle eşleşmelidir. Metin eşleştirme büyük/küçük harfe duyarlı değildir ve URL'nin yolunun kod çözülen gösterimine dayanır. Sabit yol parametresi sınırlayıcısı { veya }ile eşleştirmek için, karakteri yineleyerek sınırlayıcıdan kaçın. Örneğin {{ veya }}.

Yıldız işareti * veya çift yıldız **işareti:

  • URI'nin geri kalanına bağlanmak için bir yol parametresine ön ek olarak kullanılabilir.
  • Tümünü yakala parametreleri olarak adlandırılır. Örneğin, blog/{**slug}:
    • ile başlayan ve onu izleyen herhangi bir değere sahip URI'lerle blog/ eşleşir.
    • Aşağıdaki blog/ değer, bilgi yolu değerine atanır.

Uyarı

Tümünü yakala parametresi, yönlendirmedeki bir hata nedeniyle yolları yanlış eşleştirebilir. Bu hatadan etkilenen uygulamalar aşağıdaki özelliklere sahiptir:

  • Tümünü yakala yolu, örneğin, {**slug}"
  • Tümünü yakala yolu eşleşmesi gereken isteklerle eşleşemiyor.
  • Diğer yolların kaldırılması, tümünü yakala yolunun çalışmaya başlamasını sağlar.

Bu hataya isabet eden durumlar için bkz. GitHub hataları 18677 ve 16579 .

Bu hata için bir kabul düzeltmesi .NET Core 3.1.301 SDK ve sonraki sürümlerde yer alır. Aşağıdaki kod, bu hatayı düzelten bir iç anahtar ayarlar:

public static void Main(string[] args)
{
   AppContext.SetSwitch("Microsoft.AspNetCore.Routing.UseCorrectCatchAllBehavior", 
                         true);
   CreateHostBuilder(args).Build().Run();
}
// Remaining code removed for brevity.

Tümünü yakala parametreleri de boş dizeyle eşleşebilir.

Yol ayırıcı / karakterleri de dahil olmak üzere bir URL oluşturmak için yol kullanıldığında tümünü yakala parametresi uygun karakterlerin kaçışını verir. Örneğin, yol değerlerine { path = "my/path" } sahip yol foo/{*path} oluştururfoo/my%2Fpath. Kaçış eğik çizgisine dikkat edin. Gidiş dönüş yol ayırıcı karakterleri için yol parametresi ön ekini ** kullanın. ile { path = "my/path" } yolu foo/{**path} oluştururfoo/my/path.

İsteğe bağlı dosya uzantısına sahip bir dosya adını yakalamaya çalışan URL desenlerinin dikkate alınması gereken ek noktalar vardır. Örneğin, şablonunu files/{filename}.{ext?}göz önünde bulundurun. Hem hem de filenameext değerleri mevcut olduğunda, her iki değer de doldurulur. URL'de yalnızca için filename bir değer varsa, yol eşleşir çünkü sondaki . isteğe bağlıdır. Aşağıdaki URL'ler bu yolla eşleşti:

  • /files/myFile.txt
  • /files/myFile

Yol parametrelerinde, parametre adından sonra eşittir işaretiyle (= ) ayrılmış varsayılan değer belirtilerek varsayılan değerler belirlenebilir. Örneğin, {controller=Home} için controllervarsayılan değer olarak tanımlarHome. Parametresinin URL'sinde değer yoksa varsayılan değer kullanılır. Yol parametreleri, parametre adının sonuna bir soru işareti (?) eklenerek isteğe bağlıdır. Örneğin, id?. İsteğe bağlı değerler ile varsayılan yol parametreleri arasındaki fark:

  • Varsayılan değere sahip bir yol parametresi her zaman bir değer üretir.
  • İsteğe bağlı bir parametre yalnızca istek URL'si tarafından bir değer sağlandığında bir değere sahiptir.

Yol parametreleri, URL'den bağlanan yol değeriyle eşleşmesi gereken kısıtlamalara sahip olabilir. Yol parametresi adından sonra ekleme : ve kısıtlama adı, bir yol parametresinde satır içi kısıtlama belirtir. Kısıtlama bağımsız değişkenler gerektiriyorsa, bunlar kısıtlama adından sonra parantez (...) içine alınır. Başka bir : ve kısıtlama adı eklenerek birden çok satır içi kısıtlama belirtilebilir.

Kısıtlama adı ve bağımsız değişkenleri, URL işlemede IInlineConstraintResolver kullanılacak örneğini IRouteConstraint oluşturmak için hizmete geçirilir. Örneğin, yol şablonu blog/{article:minlength(10)} bağımsız değişkeniyle 10bir minlength kısıtlama belirtir. Yol kısıtlamaları hakkında daha fazla bilgi ve çerçeve tarafından sağlanan kısıtlamaların listesi için Yol kısıtlamaları bölümüne bakın.

Rota parametrelerinde de parametre transformatörleri olabilir. Parametre transformatörleri, url'lere bağlantılar ve eşleşen eylemler ve sayfalar oluştururken parametrenin değerini dönüştürür. Kısıtlamalar gibi parametre transformatörleri de rota parametresi adından sonra bir : ve transformatör adı eklenerek bir yol parametresine satır içi olarak eklenebilir. Örneğin, yol şablonu blog/{article:slugify} bir slugify transformatör belirtir. Parametre transformatörleri hakkında daha fazla bilgi için Parametre transformatörleri bölümüne bakın.

Aşağıdaki tabloda örnek yol şablonları ve davranışları gösterilmektedir:

Rota Şablonu Örnek Eşleşen URI İstek URI'si...
hello /hello Yalnızca tek yol ile eşleşir /hello.
{Page=Home} / ile eşleşir ve ile eşleşir PageHome.
{Page=Home} /Contact ile eşleşir ve ile eşleşir PageContact.
{controller}/{action}/{id?} /Products/List Denetleyiciye ve List eyleme Products Haritalar.
{controller}/{action}/{id?} /Products/Details/123 Denetleyiciye Products Haritalar ve Details 123 olarak ayarlanmış eylemid.
{controller=Home}/{action=Index}/{id?} / Denetleyiciye ve Index yönteme Home Haritalar. id yoksayılır.
{controller=Home}/{action=Index}/{id?} /Products Denetleyiciye ve Index yönteme Products Haritalar. id yoksayılır.

Şablon kullanmak genellikle yönlendirmeye en basit yaklaşımdır. Kısıtlamalar ve varsayılanlar, yol şablonunun dışında da belirtilebilir.

Karmaşık segmentler

Karmaşık segmentler, doyumsuz olmayan bir şekilde sağdan sola sabit sınırlayıcıları eşleştirerek işlenir. Örneğin, [Route("/a{b}c{d}")] karmaşık bir kesimdir. Karmaşık segmentler, bunları başarıyla kullanmak için anlaşılması gereken belirli bir şekilde çalışır. Bu bölümdeki örnekte, karmaşık segmentlerin neden yalnızca sınırlayıcı metin parametre değerlerinin içinde görünmediğinde gerçekten iyi çalıştığı gösterilmektedir. Daha karmaşık durumlar için bir regex kullanmak ve sonra değerleri el ile ayıklamak gerekir.

Uyarı

Güvenilmeyen girişi işlemek için kullanırken System.Text.RegularExpressions bir zaman aşımı geçirin. Kötü amaçlı bir kullanıcı Hizmet Reddi saldırısına neden olacak RegularExpressionsgirişler sağlayabilir. ASP.NET Zaman aşımı kullanan RegularExpressions Core framework API'leri.

Bu, yönlendirmenin şablon /a{b}c{d} ve URL yolu /abcdile gerçekleştirdiği adımların özetidir. |, algoritmanın nasıl çalıştığını görselleştirmeye yardımcı olmak için kullanılır:

  • İlk değişmez değer, sağdan sola, şeklindedir c. Bu nedenle /abcd sağdan aranıp öğesini bulur /ab|c|d.
  • Sağdaki (d) her şey artık yol parametresiyle {d}eşleştirilir.
  • Sağdan sola doğru sonraki değişmez değer olur a. Kaldığımız /ab|c|d yerden başlayarak arandı, sonra a bulunur /|a|b|c|d.
  • Sağındaki (b) değeri artık route parametresiyle {b}eşleştirilir.
  • Kalan metin ve kalan yol şablonu olmadığından bu bir eşleşmedir.

Aşağıda, aynı şablonu /a{b}c{d} ve URL yolunu kullanan negatif bir durum örneği verilmişti /aabcd. |, algoritmanın nasıl çalıştığını görselleştirmeye yardımcı olmak için kullanılır. Bu durum aynı algoritmayla açıklanan bir eşleşme değildir:

  • İlk değişmez değer, sağdan sola, şeklindedir c. Bu nedenle /aabcd sağdan aranıp öğesini bulur /aab|c|d.
  • Sağdaki (d) her şey artık yol parametresiyle {d}eşleştirilir.
  • Sağdan sola doğru sonraki değişmez değer olur a. Kaldığımız /aab|c|d yerden başlayarak arandı, sonra a bulunur /a|a|b|c|d.
  • Sağındaki (b) değeri artık route parametresiyle {b}eşleştirilir.
  • Bu noktada kalan metin avardır, ancak algoritmada ayrıştırılacak yol şablonu tükendi, bu nedenle bu eşleşme değildir.

Eşleşen algoritma doyumsuz olmadığından:

  • Her adımda mümkün olan en küçük metin miktarıyla eşleşir.
  • Sınırlayıcı değerinin parametre değerlerinin içinde göründüğü her durumda eşleşmez.

Normal ifadeler, eşleşen davranışları üzerinde çok daha fazla denetim sağlar.

Yavaş eşleştirme olarak da bilinen doyumsuz eşleştirme, mümkün olan en büyük dizeyle eşleşir. Doyumsuz olmayan, mümkün olan en küçük dizeyle eşleşir.

Özel karakterlerle yönlendirme

Özel karakterlerle yönlendirme beklenmeyen sonuçlara yol açabilir. Örneğin, aşağıdaki eylem yöntemine sahip bir denetleyici düşünün:

[HttpGet("{id?}/name")]
public async Task<ActionResult<string>> GetName(string id)
{
    var todoItem = await _context.TodoItems.FindAsync(id);

    if (todoItem == null || todoItem.Name == null)
    {
        return NotFound();
    }

    return todoItem.Name;
}

string id Aşağıdaki kodlanmış değerleri içerdiğinde beklenmeyen sonuçlar oluşabilir:

ASCII Encoded
/ %2F
+

Yol parametreleri her zaman URL kodunu çözmez. Bu sorun gelecekte giderilebilir. Daha fazla bilgi için bu GitHub sorununa bakın;

Yol kısıtlamaları

Yönlendirme kısıtlamaları, gelen URL'de bir eşleşme oluştuğunda ve URL yolu yol değerlerine belirteç olarak ayarlandığında yürütülür. Yol kısıtlamaları genellikle yol şablonu aracılığıyla ilişkili yol değerini inceler ve değerin kabul edilebilir olup olmadığı konusunda doğru veya yanlış bir karar verir. Bazı yol kısıtlamaları, isteğin yönlendirilip yönlendirilemeyeceğini göz önünde bulundurmak için yol değerinin dışındaki verileri kullanır. Örneğin, HttpMethodRouteConstraint http fiiline göre bir isteği kabul edebilir veya reddedebilir. Kısıtlamalar yönlendirme isteklerinde ve bağlantı oluşturmada kullanılır.

Uyarı

Giriş doğrulaması için kısıtlamaları kullanmayın. Giriş doğrulaması için kısıtlamalar kullanılıyorsa geçersiz giriş Bulunamadı yanıtında 404 sonuçlanıyor. Geçersiz giriş, uygun bir 400 hata iletisiyle Hatalı İstek oluşturmalıdır. Yol kısıtlamaları, belirli bir yolun girişlerini doğrulamak için değil, benzer yolların belirsizliğini belirlemek için kullanılır.

Aşağıdaki tabloda örnek yol kısıtlamaları ve beklenen davranışları gösterilmektedir:

kısıtlama Örnek Örnek Eşleşmeler Notlar
int {id:int} 123456789, -123456789 Herhangi bir tamsayıyla eşleşir
bool {active:bool} true, FALSE veya falseile eşleşirtrue. Duyarlı
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm Sabit kültürdeki geçerli DateTime bir değerle eşleşir. Önceki uyarıya bakın.
decimal {price:decimal} 49.99, -1,000.01 Sabit kültürdeki geçerli decimal bir değerle eşleşir. Önceki uyarıya bakın.
double {weight:double} 1.234, -1,001.01e8 Sabit kültürdeki geçerli double bir değerle eşleşir. Önceki uyarıya bakın.
float {weight:float} 1.234, -1,001.01e8 Sabit kültürdeki geçerli float bir değerle eşleşir. Önceki uyarıya bakın.
guid {id:guid} CD2C1638-1638-72D5-1638-DEADBEEF1638 Geçerli Guid bir değerle eşleşir
long {ticks:long} 123456789, -123456789 Geçerli long bir değerle eşleşir
minlength(value) {username:minlength(4)} Rick Dize en az 4 karakter olmalıdır
maxlength(value) {filename:maxlength(8)} MyFile Dize 8 karakterden fazla olmamalıdır
length(length) {filename:length(12)} somefile.txt Dize tam olarak 12 karakter uzunluğunda olmalıdır
length(min,max) {filename:length(8,16)} somefile.txt Dize en az 8 ve en fazla 16 karakter uzunluğunda olmalıdır
min(value) {age:min(18)} 19 Tamsayı değeri en az 18 olmalıdır
max(value) {age:max(120)} 91 Tamsayı değeri en fazla 120 olmalıdır
range(min,max) {age:range(18,120)} 91 Tamsayı değeri en az 18, en fazla 120 olmalıdır
alpha {name:alpha} Rick Dize bir a-z veya daha fazla alfabetik karakterden ve büyük/küçük harfe duyarsız karakterden oluşmalıdır.
regex(expression) {ssn:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)} 123-45-6789 Dize normal ifadeyle eşleşmelidir. Normal ifade tanımlama hakkındaki ipuçlarına bakın.
required {name:required} Rick URL oluşturma sırasında parametre olmayan bir değerin mevcut olmasını zorunlu kılmak için kullanılır

Uyarı

Güvenilmeyen girişi işlemek için kullanırken System.Text.RegularExpressions bir zaman aşımı geçirin. Kötü amaçlı bir kullanıcı Hizmet Reddi saldırısına neden olacak RegularExpressionsgirişler sağlayabilir. ASP.NET Zaman aşımı kullanan RegularExpressions Core framework API'leri.

Tek bir parametreye birden çok iki nokta üst üste sınırlandırılmış kısıtlama uygulanabilir. Örneğin, aşağıdaki kısıtlama bir parametreyi 1 veya daha büyük bir tamsayı değeriyle kısıtlar:

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

Uyarı

URL'yi doğrulayan ve CLR türüne dönüştürülen yol kısıtlamaları her zaman sabit kültürü kullanır. Örneğin, CLR türüne int veya DateTimedönüştürme. Bu kısıtlamalar URL'nin yerelleştirilebilir olmadığını varsayar. Çerçeve tarafından sağlanan yol kısıtlamaları, yol değerlerinde depolanan değerleri değiştirmez. URL'den ayrıştırılan tüm yol değerleri dize olarak depolanır. Örneğin kısıtlama, float yol değerini kayan değere dönüştürmeye çalışır, ancak dönüştürülen değer yalnızca float'a dönüştürülebileceğini doğrulamak için kullanılır.

Kısıtlamalardaki normal ifadeler

Uyarı

Güvenilmeyen girişi işlemek için kullanırken System.Text.RegularExpressions bir zaman aşımı geçirin. Kötü amaçlı bir kullanıcı Hizmet Reddi saldırısına neden olacak RegularExpressionsgirişler sağlayabilir. ASP.NET Zaman aşımı kullanan RegularExpressions Core framework API'leri.

Normal ifadeler, yol kısıtlaması kullanılarak regex(...) satır içi kısıtlamalar olarak belirtilebilir. Ailedeki yöntemler, kısıtlamaların MapControllerRoute nesne değişmez değerlerini de kabul eder. Bu form kullanılırsa, dize değerleri normal ifadeler olarak yorumlanır.

Aşağıdaki kod satır içi bir regex kısıtlaması kullanır:

app.MapGet("{message:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)}",
    () => "Inline Regex Constraint Matched");

Aşağıdaki kod, bir regex kısıtlaması belirtmek için bir nesne değişmez değeri kullanır:

app.MapControllerRoute(
    name: "people",
    pattern: "people/{ssn}",
    constraints: new { ssn = "^\\d{3}-\\d{2}-\\d{4}$", },
    defaults: new { controller = "People", action = "List" });

ASP.NET Core çerçevesi normal ifade oluşturucuya ekler RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant . Bu üyelerin açıklaması için bkz RegexOptions .

Normal ifadeler, yönlendirme ve C# dili tarafından kullanılanlara benzer sınırlayıcılar ve belirteçler kullanır. Normal ifade belirteçlerinin kaçılması gerekir. Normal ifadeyi ^\d{3}-\d{2}-\d{4}$ satır içi kısıtlamada kullanmak için aşağıdakilerden birini kullanın:

Yönlendirme parametresi sınırlayıcı karakterlerini {, , [}, , ]kaçış olarak kullanmak için ifadedeki karakterleri (örneğin, {{, }}, , [[]]) iki katına çıkarır. Aşağıdaki tabloda normal bir ifade ve kaçış sürümü gösterilmektedir:

Regular expression Kaçış normal ifadesi
^\d{3}-\d{2}-\d{4}$ ^\\d{{3}}-\\d{{2}}-\\d{{4}}$
^[a-z]{2}$ ^[[a-z]]{{2}}$

Yönlendirmede kullanılan normal ifadeler genellikle karakterle ^ başlar ve dizenin başlangıç konumuyla eşleşer. İfadeler genellikle karakterle biter ve dizenin sonuyla $ eşleşer. ^ ve $ karakterleri normal ifadenin yol parametresi değerinin tamamıyla eşleşmesini sağlar. ^ ve $ karakterleri olmadan, normal ifade dizedeki alt dizelerle eşleşir ve bu genellikle istenmeyen bir durumdur. Aşağıdaki tabloda örnekler ve bunların neden eşleştikleri veya eşleşmedikleri açıklanmaktadır:

Expression String Eşleştir Yorum
[a-z]{2} merhaba Yes Alt dize eşleşmeleri
[a-z]{2} 123abc456 Yes Alt dize eşleşmeleri
[a-z]{2} Mz Yes İfadeyle eşleşir
[a-z]{2} MZ Yes Büyük/küçük harfe duyarlı değil
^[a-z]{2}$ merhaba Hayır Bkz ^ . ve $ üzeri
^[a-z]{2}$ 123abc456 Hayır Bkz ^ . ve $ üzeri

Normal ifade söz dizimi hakkında daha fazla bilgi için bkz . .NET Framework Normal İfadeleri.

Bir parametreyi bilinen bir olası değer kümesiyle sınırlamak için normal bir ifade kullanın. Örneğin, {action:regex(^(list|get|create)$)} yalnızca yol değeri listile action , getveya createile eşleşir. Kısıtlamalar sözlüğüne geçirilirse dize ^(list|get|create)$ eşdeğerdir. Bilinen kısıtlamalardan biriyle eşleşmeyen kısıtlama sözlüğünde geçirilen kısıtlamalar da normal ifadeler olarak kabul edilir. Bilinen kısıtlamalardan biriyle eşleşmeyen bir şablon içinde geçirilen kısıtlamalar normal ifadeler olarak kabul edilmemektedir.

Özel yol kısıtlamaları

Özel yol kısıtlamaları, arabirimi uygulanarak IRouteConstraint oluşturulabilir. Arabirimi, IRouteConstraint kısıtlamanın karşılanması durumunda döndüren ve false aksi halde döndüren true öğesini içerirMatch.

Özel yol kısıtlamalarına nadiren ihtiyaç duyulduğu görülür. Özel yol kısıtlaması uygulamadan önce model bağlama gibi alternatifleri göz önünde bulundurun.

ASP.NET Core Constraints klasörü, kısıtlama oluşturmaya yönelik iyi örnekler sağlar. Örneğin, GuidRouteConstraint.

Özel IRouteConstraintbir kullanmak için, yol kısıtlama türünün hizmet kapsayıcısında uygulamanınkilere ConstraintMap kaydedilmesi gerekir. A ConstraintMap , yönlendirme kısıtlama anahtarlarını bu kısıtlamaları doğrulayan uygulamalarla IRouteConstraint eşleyen bir sözlüktür. Bir uygulamanın uygulamasıConstraintMap, bir çağrının AddRouting parçası olarak veya ile builder.Services.Configure<RouteOptions>doğrudan yapılandırılarak RouteOptions güncelleştirilebilirProgram.cs. Örneğin:

builder.Services.AddRouting(options =>
    options.ConstraintMap.Add("noZeroes", typeof(NoZeroesRouteConstraint)));

Yukarıdaki kısıtlama aşağıdaki kodda uygulanır:

[ApiController]
[Route("api/[controller]")]
public class NoZeroesController : ControllerBase
{
    [HttpGet("{id:noZeroes}")]
    public IActionResult Get(string id) =>
        Content(id);
}

uygulaması NoZeroesRouteConstraint , bir yol parametresinde kullanılmasını engeller 0 :

public class NoZeroesRouteConstraint : IRouteConstraint
{
    private static readonly Regex _regex = new(
        @"^[1-9]*$",
        RegexOptions.CultureInvariant | RegexOptions.IgnoreCase,
        TimeSpan.FromMilliseconds(100));

    public bool Match(
        HttpContext? httpContext, IRouter? route, string routeKey,
        RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (!values.TryGetValue(routeKey, out var routeValue))
        {
            return false;
        }

        var routeValueString = Convert.ToString(routeValue, CultureInfo.InvariantCulture);

        if (routeValueString is null)
        {
            return false;
        }

        return _regex.IsMatch(routeValueString);
    }
}

Uyarı

Güvenilmeyen girişi işlemek için kullanırken System.Text.RegularExpressions bir zaman aşımı geçirin. Kötü amaçlı bir kullanıcı Hizmet Reddi saldırısına neden olacak RegularExpressionsgirişler sağlayabilir. ASP.NET Zaman aşımı kullanan RegularExpressions Core framework API'leri.

Yukarıdaki kod:

  • Yolun segmentinde {id} engeller0.
  • Özel kısıtlama uygulamanın temel bir örneğini sağlamak için gösterilir. Üretim uygulamasında kullanılmamalıdır.

Aşağıdaki kod, içeren bir kodun işlenmesini önlemeye yönelik daha iyi bir id0 yaklaşımdır:

[HttpGet("{id}")]
public IActionResult Get(string id)
{
    if (id.Contains('0'))
    {
        return StatusCode(StatusCodes.Status406NotAcceptable);
    }

    return Content(id);
}

Yukarıdaki kod, yaklaşıma göre aşağıdaki avantajlara NoZeroesRouteConstraint sahiptir:

  • Özel bir kısıtlama gerektirmez.
  • Yol parametresi içerdiğinde 0daha açıklayıcı bir hata döndürür.

Parametre transformatörleri

Parametre transformatörleri:

Örneğin, ile Url.Action(new { article = "MyTestArticle" }) yol deseninde blog\{article:slugify} özel slugify bir parametre transformatörü oluştururblog\my-test-article.

Aşağıdaki IOutboundParameterTransformer uygulamayı göz önünde bulundurun:

public class SlugifyParameterTransformer : IOutboundParameterTransformer
{
    public string? TransformOutbound(object? value)
    {
        if (value is null)
        {
            return null;
        }

        return Regex.Replace(
            value.ToString()!,
                "([a-z])([A-Z])",
            "$1-$2",
            RegexOptions.CultureInvariant,
            TimeSpan.FromMilliseconds(100))
            .ToLowerInvariant();
    }
}

Rota deseninde bir parametre transformatörü kullanmak için içinde kullanarak ConstraintMapProgram.csyapılandırın:

builder.Services.AddRouting(options =>
    options.ConstraintMap["slugify"] = typeof(SlugifyParameterTransformer));

ASP.NET Core çerçevesi, bir uç noktanın çözümlendiği URI'yi dönüştürmek için parametre dönüştürücülerini kullanır. Örneğin, parametre transformatörleri , area, controlleractionve pageile eşleştirmek için kullanılan yol değerlerini dönüştürür:

app.MapControllerRoute(
    name: "default",
    pattern: "{controller:slugify=Home}/{action:slugify=Index}/{id?}");

Önceki yol şablonuyla, eylem SubscriptionManagementController.GetAll URI /subscription-management/get-allile eşleştirilir. Parametre transformatörü, bağlantı oluşturmak için kullanılan yol değerlerini değiştirmez. Örneğin, Url.Action("GetAll", "SubscriptionManagement") çıkışları /subscription-management/get-all.

ASP.NET Core, oluşturulan yollar ile parametre dönüştürücülerini kullanmaya yönelik API kuralları sağlar:

URL oluşturma başvurusu

Bu bölüm, URL oluşturma tarafından uygulanan algoritma için bir başvuru içerir. Uygulamada, URL oluşturmanın en karmaşık örneklerinde denetleyiciler veya Razor Sayfalar kullanılır. Ek bilgi için bkz . denetleyicilerde yönlendirme.

URL oluşturma işlemi bir LinkGenerator.GetPathByAddress çağrısı veya benzer bir yöntemle başlar. yöntemi bir adres, yol değerleri kümesi ve isteğe bağlı olarak geçerli HttpContextistek hakkında bilgi ile sağlanır.

İlk adım, adresi kullanarak adresin türüyle eşleşen bir aday uç nokta IEndpointAddressScheme<TAddress> kümesini çözümlemektir.

Adaylar kümesi adres düzeni tarafından bulunduktan sonra, URL oluşturma işlemi başarılı olana kadar uç noktalar yinelemeli olarak sıralanır ve işlenir. URL oluşturma belirsizlikleri denetlemez, döndürülen ilk sonuç nihai sonuç olur.

Günlüğe kaydetme ile URL oluşturma sorunlarını giderme

URL oluşturma sorunlarını gidermenin ilk adımı, günlük düzeyini Microsoft.AspNetCore.Routing olarak TRACEayarlamaktır. LinkGenerator sorunları gidermek için yararlı olabilecek işlemesiyle ilgili birçok ayrıntıyı günlüğe kaydeder.

URL oluşturmayla ilgili ayrıntılar için bkz . URL oluşturma başvurusu .

Adresler

Adresler, bir çağrıyı bağlantı oluşturucusuna bir dizi aday uç noktaya bağlamak için kullanılan URL oluşturma kavramıdır.

Adresler, varsayılan olarak iki uygulamayla birlikte gelen genişletilebilir bir kavramdır:

  • Adres olarak uç nokta adını (string) kullanma:
    • MVC'nin yol adına benzer işlevler sağlar.
    • IEndpointNameMetadata Meta veri türünü kullanır.
    • Sağlanan dizeyi tüm kayıtlı uç noktaların meta verilerine karşı çözümler.
    • Birden çok uç nokta aynı adı kullanıyorsa başlangıçta bir özel durum oluşturur.
    • Denetleyiciler ve Razor Sayfalar dışında genel amaçlı kullanım için önerilir.
  • Adres olarak yol değerlerini (RouteValuesAddress) kullanma:
    • Denetleyiciler ve Razor Sayfalar eski URL oluşturma için benzer işlevler sağlar.
    • Genişletmek ve hata ayıklamak çok karmaşık.
    • , Etiket Yardımcıları, HTML Yardımcıları, Eylem Sonuçları vb. tarafından IUrlHelperkullanılan uygulamayı sağlar.

Adres düzeninin rolü, adres ve eşleşen uç noktalar arasındaki ilişkilendirmeyi rastgele ölçütlerle yapmaktır:

  • Uç nokta adı düzeni temel bir sözlük araması gerçekleştirir.
  • Yol değerleri şeması, küme algoritmasının karmaşık en iyi alt kümesine sahiptir.

Ortam değerleri ve açık değerler

Geçerli istekten yönlendirme, geçerli isteğin HttpContext.Request.RouteValuesyol değerlerine erişir. Geçerli istekle ilişkili değerler ortam değerleri olarak adlandırılır. Netlik sağlamak amacıyla belgeler, yöntemlere açık değerler olarak geçirilen yol değerlerini ifade eder.

Aşağıdaki örnekte ortam değerleri ve açık değerler gösterilmektedir. Geçerli istekten ortam değerleri ve açık değerler sağlar:

public class WidgetController : ControllerBase
{
    private readonly LinkGenerator _linkGenerator;

    public WidgetController(LinkGenerator linkGenerator) =>
        _linkGenerator = linkGenerator;

    public IActionResult Index()
    {
        var indexPath = _linkGenerator.GetPathByAction(
            HttpContext, values: new { id = 17 })!;

        return Content(indexPath);
    }

    // ...

Yukarıdaki kod:

Aşağıdaki kod yalnızca açık değerler sağlar ve ortam değerleri sağlamaz:

var subscribePath = _linkGenerator.GetPathByAction(
    "Subscribe", "Home", new { id = 17 })!;

Yukarıdaki yöntem döndürür /Home/Subscribe/17

içindeki aşağıdaki kod WidgetController döndürür /Widget/Subscribe/17:

var subscribePath = _linkGenerator.GetPathByAction(
    HttpContext, "Subscribe", null, new { id = 17 });

Aşağıdaki kod, denetleyiciyi geçerli istekteki ortam değerlerinden ve açık değerlerden sağlar:

public class GadgetController : ControllerBase
{
    public IActionResult Index() =>
        Content(Url.Action("Edit", new { id = 17 })!);
}

Önceki kodda:

  • /Gadget/Edit/17 döndürülür.
  • Url alır IUrlHelper.
  • Action bir eylem yöntemi için mutlak yola sahip bir URL oluşturur. URL belirtilen action adı ve route değerleri içerir.

Aşağıdaki kod, geçerli istekten gelen ortam değerlerini ve açık değerleri sağlar:

public class IndexModel : PageModel
{
    public void OnGet()
    {
        var editUrl = Url.Page("./Edit", new { id = 17 });

        // ...
    }
}

Yukarıdaki kod, SayfaYı Düzenle Razor aşağıdaki sayfa yönergesini içerdiğinde olarak ayarlır:url/Edit/17

@page "{id:int}"

Düzenle sayfası yol şablonunu içermiyorsa "{id:int}" , url şeklindedir /Edit?id=17.

MVC'nin IUrlHelper davranışı, burada açıklanan kurallara ek olarak bir karmaşıklık katmanı ekler:

  • IUrlHelper her zaman geçerli istekten yol değerlerini ortam değerleri olarak sağlar.
  • IUrlHelper.Action , geliştirici tarafından geçersiz kılınmadığı sürece her zaman geçerli action ve controller yol değerlerini açık değerler olarak kopyalar.
  • IUrlHelper.Page geçersiz kılınmadığı sürece geçerli page yol değerini her zaman açık bir değer olarak kopyalar.
  • IUrlHelper.Page geçersiz kılınmadığı sürece geçerli handler yol değerini null her zaman ile açık değerler olarak geçersiz kılar.

MVC kendi kurallarına uymadığından kullanıcılar genellikle ortam değerlerinin davranışsal ayrıntılarına şaşırır. Geçmiş ve uyumluluk nedenleriyle, , controller, pageve handler gibi actionbelirli yol değerlerinin kendi özel durum davranışları vardır.

tarafından LinkGenerator.GetPathByAction sağlanan eşdeğer işlevsellik ve LinkGenerator.GetPathByPage uyumluluk için bu anomalilerini IUrlHelper yineler.

URL oluşturma işlemi

Aday uç nokta kümesi bulunduktan sonra URL oluşturma algoritması:

  • Uç noktaları yinelemeli olarak işler.
  • İlk başarılı sonucu döndürür.

Bu işlemin ilk adımı, yol değeri geçersizleştirmesi olarak adlandırılır. Yol değeri geçersiz kılınması, yönlendirmenin ortam değerlerinden hangi yol değerlerinin kullanılacağına ve hangilerinin yoksayılacağına karar verdiği işlemdir. Her ortam değeri kabul edilir ve açık değerlerle birleştirilir veya yoksayılır.

Ortam değerlerinin rolü hakkında düşünmenin en iyi yolu, bazı yaygın durumlarda uygulama geliştiricilerini yazmaya kaydetmeyi denemeleridir. Geleneksel olarak ortam değerlerinin yararlı olduğu senaryolar MVC ile ilgilidir:

  • Aynı denetleyicideki başka bir eyleme bağlanırken, denetleyici adının belirtilmesi gerekmez.
  • Aynı alandaki başka bir denetleyiciye bağlanırken alan adının belirtilmesi gerekmez.
  • Aynı eylem yöntemine bağlanırken yol değerlerinin belirtilmesi gerekmez.
  • Uygulamanın başka bir bölümüne bağlanırken, uygulamanın bu bölümünde hiçbir anlamı olmayan rota değerlerini taşımak istemezsiniz.

LinkGenerator veya IUrlHelper döndüren null çağrıların nedeni genellikle yol değeri geçersizleştirmesini anlamamaktır. Bunun sorunu çözüp çözmediğini görmek için yol değerlerinden daha fazlasını açıkça belirterek yol değeri geçersizliği sorunlarını giderin.

Yol değeri geçersiz kılınması, uygulamanın URL düzeninin hiyerarşik olduğu varsayımıyla çalışır ve soldan sağa bir hiyerarşi oluşturulur. Bunun pratikte nasıl çalıştığına ilişkin sezgisel bir fikir edinmek için temel denetleyici rota şablonunu {controller}/{action}/{id?} göz önünde bulundurun. Bir değerde yapılan değişiklik, sağda görünen tüm yol değerlerini geçersiz kıldığını gösterir. Bu, hiyerarşi hakkındaki varsayımı yansıtır. Uygulamanın için idbir ortam değeri varsa ve işlem için controllerfarklı bir değer belirtir:

  • idöğesinin solunda {id?}olduğundan {controller} yeniden kullanılamaz.

Bu ilkeyi gösteren bazı örnekler:

  • Açık değerler için idbir değer içeriyorsa, için id ortam değeri yoksayılır. ve action ortam controller değerleri kullanılabilir.
  • Açık değerler için actionbir değer içeriyorsa, için action ortam değerleri yoksayılır. için controller ortam değerleri kullanılabilir. için action açık değer için ortam değerinden actionid farklıysa, değeri kullanılmaz. için action açık değer için ortam değeri actionid ile aynıysa, değeri kullanılabilir.
  • Açık değerler için controllerbir değer içeriyorsa, için controller ortam değerleri yoksayılır. için controller açık değer için ortam değerinden controlleraction farklıysa ve id değerleri kullanılmaz. için controller açık değer, için ortam değeriyle controlleraction aynıysa ve id değerleri kullanılabilir.

Bu işlem, öznitelik yollarının ve ayrılmış geleneksel yolların varlığıyla daha karmaşıktır. Yol parametrelerini kullanarak hiyerarşi belirtme gibi {controller}/{action}/{id?} denetleyici geleneksel yolları. Denetleyicilere ve Sayfalara ayrılmış geleneksel yollar ve Razor öznitelik yolları için:

  • Yol değerleri hiyerarşisi vardır.
  • Bunlar şablonda görünmez.

Bu durumlarda, URL oluşturma gerekli değerler kavramını tanımlar. Denetleyiciler ve Razor Sayfalar tarafından oluşturulan uç noktaların, yol değeri geçersiz kılınmasına izin veren gerekli değerler belirtilmiştir.

Yol değeri geçersizleştirme algoritması ayrıntılı olarak:

  • Gerekli değer adları yol parametreleriyle birleştirilir ve ardından soldan sağa işlenir.
  • Her parametre için ortam değeri ve açık değer karşılaştırılır:
    • Ortam değeri ve açık değer aynıysa işlem devam eder.
    • Ortam değeri mevcutsa ve açık değer yoksa, URL oluşturulurken ortam değeri kullanılır.
    • Ortam değeri yoksa ve açık değer ise, ortam değerini ve sonraki tüm ortam değerlerini reddedin.
    • Ortam değeri ve açık değer varsa ve iki değer farklıysa, ortam değerini ve sonraki tüm ortam değerlerini reddedin.

Bu noktada, URL oluşturma işlemi yol kısıtlamalarını değerlendirmeye hazırdır. Kabul edilen değerler kümesi, kısıtlamalara sağlanan parametre varsayılan değerleriyle birleştirilir. Kısıtlamaların tümü geçerse işlem devam eder.

Ardından, kabul edilen değerler yol şablonunu genişletmek için kullanılabilir. Yol şablonu işlenir:

  • Soldan sağa.
  • Her parametrenin yerine kabul edilen değeri vardır.
  • Aşağıdaki özel durumlarla:
    • Kabul edilen değerlerde bir değer eksikse ve parametrenin varsayılan değeri varsa, varsayılan değer kullanılır.
    • Kabul edilen değerlerde bir değer eksikse ve parametre isteğe bağlıysa işleme devam eder.
    • Eksik isteğe bağlı parametrenin sağındaki herhangi bir yol parametresinin değeri varsa, işlem başarısız olur.
    • Bitişik varsayılan değerli parametreler ve isteğe bağlı parametreler mümkün olduğunca daraltılır.

Yolun bir kesimiyle eşleşmeyen açıkça sağlanan değerler sorgu dizesine eklenir. Aşağıdaki tabloda yol şablonu {controller}/{action}/{id?}kullanılırken elde edilen sonuç gösterilmektedir.

Ortam Değerleri Açık Değerler Sonuç
controller = "Home" action = "About" /Home/About
controller = "Home" controller = "Order", action = "About" /Order/About
denetleyici = "Home", renk = "Kırmızı" action = "About" /Home/About
controller = "Home" action = "About", color = "Red" /Home/About?color=Red

Yol değeri geçersiz kılınmasıyla ilgili sorunlar

Aşağıdaki kod, yönlendirme tarafından desteklenmeyen bir URL oluşturma şeması örneği gösterir:

app.MapControllerRoute(
    "default",
    "{culture}/{controller=Home}/{action=Index}/{id?}");

app.MapControllerRoute(
    "blog",
    "{culture}/{**slug}",
    new { controller = "Blog", action = "ReadPost" });

Yukarıdaki kodda culture , yerelleştirme için yol parametresi kullanılır. Parametrenin culture her zaman bir ortam değeri olarak kabul edilmiş olmasını istemeniz gerekir. Ancak, gerekli değerlerin culture çalışma şekli nedeniyle parametre ortam değeri olarak kabul edilmemektedir:

  • Yol şablonunda "default" , culture yol parametresi solundadır controller, bu nedenle olarak değişir controller ve geçersiz kılmaz culture.
  • Yol şablonunda "blog" , culture yol parametresinin, gerekli değerlerde görünen sağında controllerolduğu kabul edilir.

ILE URL yollarını ayrıştırma LinkParser

sınıfı, LinkParser URL yolunu bir yol değerleri kümesine ayrıştırma desteği ekler. ParsePathByEndpointName yöntemi bir uç nokta adı ve URL yolu alır ve URL yolundan ayıklanan bir yol değerleri kümesi döndürür.

Aşağıdaki örnek denetleyicide GetProduct , eylem bir yol şablonu api/Products/{id} kullanır ve öğesinin bir Name öğesine GetProductsahiptir:

[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
    [HttpGet("{id}", Name = nameof(GetProduct))]
    public IActionResult GetProduct(string id)
    {
        // ...

Aynı denetleyici sınıfında, AddRelatedProduct eylem sorgu dizesi parametresi olarak sağlanabilen bir URL yolu pathToRelatedProductbekler:

[HttpPost("{id}/Related")]
public IActionResult AddRelatedProduct(
    string id, string pathToRelatedProduct, [FromServices] LinkParser linkParser)
{
    var routeValues = linkParser.ParsePathByEndpointName(
        nameof(GetProduct), pathToRelatedProduct);
    var relatedProductId = routeValues?["id"];

    // ...

Yukarıdaki örnekte, AddRelatedProduct eylem URL yolundan id yol değerini ayıklar. Örneğin, url yolu /api/Products/1relatedProductId ile değeri olarak 1ayarlanır. Bu yaklaşım, API istemcilerinin kaynaklara başvururken URL yollarını kullanmasına olanak tanır ve bu tür bir URL'nin nasıl yapılandırıldığı hakkında bilgi sahibi olmak zorunda değildir.

Uç nokta meta verilerini yapılandırma

Aşağıdaki bağlantılar, uç nokta meta verilerini yapılandırma hakkında bilgi sağlar:

RequireHost ile yollarda konak eşleştirme

RequireHost belirtilen konağı gerektiren yola bir kısıtlama uygular. RequireHost veya [Host] parametresi şu olabilir:

  • Ana bilgisayar: www.domain.com, herhangi bir bağlantı noktasıyla eşleşir www.domain.com .
  • Joker karakterli konak: *.domain.com, , subdomain.domain.comveya www.subdomain.domain.com herhangi bir bağlantı noktasında eşleşirwww.domain.com.
  • Bağlantı noktası: *:5000, 5000 numaralı bağlantı noktasını herhangi bir konakla eşleştirir.
  • Konak ve bağlantı noktası: www.domain.com:5000 veya *.domain.com:5000, konak ve bağlantı noktasıyla eşleşir.

veya [Host]kullanılarak RequireHost birden çok parametre belirtilebilir. Kısıtlama, parametrelerden herhangi biri için geçerli olan konaklarla eşleşir. Örneğin, [Host("domain.com", "*.domain.com")] , www.domain.comve subdomain.domain.comile eşleşirdomain.com.

Aşağıdaki kod, belirtilen konağın yolda gerekli olmasını sağlamak için kullanır RequireHost :

app.MapGet("/", () => "Contoso").RequireHost("contoso.com");
app.MapGet("/", () => "AdventureWorks").RequireHost("adventure-works.com");

app.MapHealthChecks("/healthz").RequireHost("*:8080");

Aşağıdaki kod, belirtilen konaklardan herhangi birini gerektirmek için denetleyicideki özniteliğini kullanır [Host] :

[Host("contoso.com", "adventure-works.com")]
public class HostsController : Controller
{
    public IActionResult Index() =>
        View();

    [Host("example.com")]
    public IActionResult Example() =>
        View();
}

[Host] Özniteliği hem denetleyiciye hem de eylem yöntemine uygulandığında:

  • Eylemdeki özniteliği kullanılır.
  • Denetleyici özniteliği yoksayılır.

Yönlendirme için performans kılavuzu

Bir uygulamada performans sorunları olduğunda, yönlendirme genellikle sorun olarak şüphelenilir. Yönlendirmenin nedeni, denetleyiciler ve Razor Sayfalar gibi çerçevelerin günlüğe kaydetme iletilerinde çerçeve içinde harcanan süreyi raporlamasıdır. Denetleyiciler tarafından bildirilen süre ile isteğin toplam süresi arasında önemli bir fark olduğunda:

  • Geliştiriciler, sorunun kaynağı olarak uygulama kodlarını ortadan kaldırır.
  • Bunun nedeninin yönlendirme olduğunu varsaymak yaygın bir durumdur.

Yönlendirme, binlerce uç nokta kullanılarak performans testi yapılır. Tipik bir uygulamanın yalnızca çok büyük olmasıyla bir performans sorunuyla karşılaşma olasılığı düşüktür. Yavaş yönlendirme performansının en yaygın kök nedeni genellikle kötü davranan bir özel ara yazılımdır.

Aşağıdaki kod örneği, gecikme kaynağını daraltmayla ilgili temel bir tekniği gösterir:

var logger = app.Services.GetRequiredService<ILogger<Program>>();

app.Use(async (context, next) =>
{
    var stopwatch = Stopwatch.StartNew();
    await next(context);
    stopwatch.Stop();

    logger.LogInformation("Time 1: {ElapsedMilliseconds}ms", stopwatch.ElapsedMilliseconds);
});

app.UseRouting();

app.Use(async (context, next) =>
{
    var stopwatch = Stopwatch.StartNew();
    await next(context);
    stopwatch.Stop();

    logger.LogInformation("Time 2: {ElapsedMilliseconds}ms", stopwatch.ElapsedMilliseconds);
});

app.UseAuthorization();

app.Use(async (context, next) =>
{
    var stopwatch = Stopwatch.StartNew();
    await next(context);
    stopwatch.Stop();

    logger.LogInformation("Time 3: {ElapsedMilliseconds}ms", stopwatch.ElapsedMilliseconds);
});

app.MapGet("/", () => "Timing Test.");

Zaman yönlendirme:

  • Önceki kodda gösterilen zamanlama ara yazılımının bir kopyasıyla her ara yazılımı birbirine ekleyin.
  • Zamanlama verilerini kodla ilişkilendirmek için benzersiz bir tanımlayıcı ekleyin.

Bu, örneğin değerinden daha 10msönemli olduğunda gecikmeyi daraltmak için temel bir yoldur. Raporlardan Time 1 ara yazılım içinde harcanan UseRouting süreyi çıkarmaTime 2.

Aşağıdaki kod, önceki zamanlama koduna daha kompakt bir yaklaşım kullanır:

public sealed class AutoStopwatch : IDisposable
{
    private readonly ILogger _logger;
    private readonly string _message;
    private readonly Stopwatch _stopwatch;
    private bool _disposed;

    public AutoStopwatch(ILogger logger, string message) =>
        (_logger, _message, _stopwatch) = (logger, message, Stopwatch.StartNew());

    public void Dispose()
    {
        if (_disposed)
        {
            return;
        }

        _logger.LogInformation("{Message}: {ElapsedMilliseconds}ms",
            _message, _stopwatch.ElapsedMilliseconds);

        _disposed = true;
    }
}
var logger = app.Services.GetRequiredService<ILogger<Program>>();
var timerCount = 0;

app.Use(async (context, next) =>
{
    using (new AutoStopwatch(logger, $"Time {++timerCount}"))
    {
        await next(context);
    }
});

app.UseRouting();

app.Use(async (context, next) =>
{
    using (new AutoStopwatch(logger, $"Time {++timerCount}"))
    {
        await next(context);
    }
});

app.UseAuthorization();

app.Use(async (context, next) =>
{
    using (new AutoStopwatch(logger, $"Time {++timerCount}"))
    {
        await next(context);
    }
});

app.MapGet("/", () => "Timing Test.");

Potansiyel olarak pahalı yönlendirme özellikleri

Aşağıdaki liste, temel yol şablonlarıyla karşılaştırıldığında nispeten pahalı yönlendirme özellikleri hakkında bazı içgörüler sağlar:

  • Normal ifadeler: Karmaşık olan veya az miktarda girişle uzun süre çalışan normal ifadeler yazmak mümkündür.
  • Karmaşık segmentler ({x}-{y}-{z}):
    • Normal URL yolu kesimini ayrıştırmaktan çok daha pahalıdır.
    • Daha fazla alt dizenin ayrılmasına neden olur.
  • Zaman uyumlu veri erişimi: Birçok karmaşık uygulamanın yönlendirmesinin bir parçası olarak veritabanı erişimi vardır. zaman uyumsuz olan ve EndpointSelectorContextgibi MatcherPolicy genişletilebilirlik noktalarını kullanın.

Büyük rota tabloları için rehberlik

Varsayılan olarak ASP.NET Core, belleği CPU süresiyle takas eden bir yönlendirme algoritması kullanır. Bu, yol eşleştirme zamanının yol sayısına değil, yalnızca eşleşecek yolun uzunluğuna bağlı olması iyi bir etkiye sahiptir. Ancak, uygulamanın çok fazla sayıda yolu (binler) olduğunda ve yollarda yüksek miktarda değişken ön eki bulunduğunda, bu yaklaşım bazı durumlarda sorunlu olabilir. Örneğin, yolların yolunun erken segmentlerinde parametreleri varsa, örneğin {parameter}/some/literal.

Bir uygulamanın aşağıdakiler dışında bunun bir sorun olduğu bir durumla karşılaşmış olma olasılığı düşüktür:

  • Uygulamada bu deseni kullanan çok sayıda yol vardır.
  • Uygulamada çok sayıda yol vardır.

Bir uygulamanın büyük yol tablosu sorunuyla karşılaşıp karşılaşmadığını belirleme

  • Aranacak iki belirti vardır:
    • Uygulama ilk istekte yavaş başlatılıyor.
      • Bunun gerekli olduğunu ancak yeterli olmadığını unutmayın. Yavaş uygulama başlatmaya neden olabilecekden çok daha fazla yol dışı sorun vardır. Uygulamanın bu durumla karşılaştığını doğru bir şekilde belirlemek için aşağıdaki koşulu denetleyin.
    • Uygulama, başlatma sırasında çok fazla bellek tüketir ve bellek dökümü çok sayıda Microsoft.AspNetCore.Routing.Matching.DfaNode örnek gösterir.

Bu sorunu giderme

Bu senaryoya büyük ölçüde iyileştirecek yollara çeşitli teknikler ve iyileştirmeler uygulanabilir:

  • Mümkün olduğunda parametrelerinize {parameter:int}{parameter:guid}, , {parameter:regex(\\d+)}vb. yol kısıtlamaları uygulayın.
    • Bu, yönlendirme algoritmasının eşleştirme için kullanılan yapıları dahili olarak iyileştirmesini ve kullanılan belleği önemli ölçüde azaltmasını sağlar.
    • Çoğu durumda bu, kabul edilebilir bir davranışa geri dönmek için yeterli olacaktır.
  • Parametreleri şablondaki sonraki segmentlere taşımak için yolları değiştirin.
    • Bu, olası "yol" sayısını bir yol verilen uç noktayla eşleşecek şekilde azaltır.
  • Dinamik bir yol kullanın ve bir denetleyici/sayfaya eşlemeyi dinamik olarak gerçekleştirin.
    • Bu, ve MapDynamicPageRoutekullanılarak MapDynamicControllerRoute gerçekleştirilebilir.

Kitaplık yazarları için rehberlik

Bu bölüm, yönlendirmenin üzerine inşa eden kitaplık yazarları için rehberlik içerir. Bu ayrıntılar, uygulama geliştiricilerinin yönlendirmeyi genişleten kitaplıkları ve çerçeveleri kullanarak iyi bir deneyim elde etmelerini sağlamaya yöneliktir.

Uç noktaları tanımlama

URL eşleştirmesi için yönlendirme kullanan bir çerçeve oluşturmak için, üzerinde UseEndpointsderleyen bir kullanıcı deneyimi tanımlayarak başlayın.

DO , üzerinde derleyin IEndpointRouteBuilder. Bu, kullanıcıların kafa karışıklığı olmadan diğer ASP.NET Core özellikleriyle çerçevenizi oluşturmasına olanak tanır. Her ASP.NET Core şablonu yönlendirme içerir. Yönlendirmenin kullanıcılar için mevcut ve tanıdık olduğunu varsayın.

// Your framework
app.MapMyFramework(...);

app.MapHealthChecks("/healthz");

DO, uygulayan IEndpointConventionBuilderçağrısından korumalı bir MapMyFramework(...) beton türü döndürür. Çoğu çerçeve Map... yöntemi bu deseni izler. Arabirim IEndpointConventionBuilder :

  • Meta verilerin oluşmasına izin verir.
  • Çeşitli uzantı yöntemleri tarafından hedeflenmiştir.

Kendi türünüzü bildirmeniz, oluşturucuya kendi çerçeveye özgü işlevselliğinizi eklemenize olanak tanır. Çerçeve tarafından bildirilen bir oluşturucuyu sarmalayıp çağrıları ona iletmenin bir sakıncası yok.

// Your framework
app.MapMyFramework(...)
    .RequireAuthorization()
    .WithMyFrameworkFeature(awesome: true);

app.MapHealthChecks("/healthz");

Kendi EndpointDataSourceyazınızı yazmayı göz önünde bulundurun. EndpointDataSource , bir uç nokta koleksiyonunu bildirmeye ve güncelleştirmeye yönelik alt düzey temel öğedir. EndpointDataSource , denetleyiciler ve Razor Sayfalar tarafından kullanılan güçlü bir API'dir.

Yönlendirme testlerinin temel bir güncelleştirilmemiş veri kaynağı örneği vardır.

Varsayılan olarak bir EndpointDataSource kaydetmeyi DENEMEYİN. Kullanıcıların çerçevenizi ' UseEndpointsye kaydetmesini gerektirin. Yönlendirmenin felsefesi, varsayılan olarak hiçbir şeyin dahil olmadığını ve uç noktaların kaydedildiği yerdir UseEndpoints .

Yönlendirmeyle tümleşik ara yazılım oluşturma

Meta veri türlerini arabirim olarak tanımlamayı GÖZ ÖNÜNDE BULUNDURUN .

DO , meta veri türlerini sınıflarda ve yöntemlerde öznitelik olarak kullanmayı mümkün hale getirir.

public interface ICoolMetadata
{
    bool IsCool { get; }
}

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CoolMetadataAttribute : Attribute, ICoolMetadata
{
    public bool IsCool => true;
}

Denetleyiciler ve Razor Sayfalar gibi çerçeveler, meta veri özniteliklerinin türlere ve yöntemlere uygulanmasını destekler. Meta veri türlerini bildirirseniz:

  • Bunları öznitelik olarak erişilebilir hale getirin.
  • Kullanıcıların çoğu öznitelikleri uygulama konusunda bilgi sahibidir.

Bir meta veri türünün arabirim olarak bildirilmesi başka bir esneklik katmanı ekler:

  • Arabirimler birleştirilebilir.
  • Geliştiriciler, birden çok ilkeyi birleştiren kendi türlerini bildirebilir.

AŞAĞıDAKI örnekte gösterildiği gibi meta verileri geçersiz kılmayı mümkün kılamaz:

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class SuppressCoolMetadataAttribute : Attribute, ICoolMetadata
{
    public bool IsCool => false;
}

[CoolMetadata]
public class MyController : Controller
{
    public void MyCool() { }

    [SuppressCoolMetadata]
    public void Uncool() { }
}

Bu yönergeleri izlemenin en iyi yolu, işaretçi meta verilerini tanımlamaktan kaçınmaktır:

  • Yalnızca meta veri türünün varlığına bakmayın.
  • Meta verilerde bir özellik tanımlayın ve özelliğini denetleyin.

Meta veri koleksiyonu sıralanır ve önceliğe göre geçersiz kılmayı destekler. Denetleyiciler söz konusu olduğunda, eylem yöntemindeki meta veriler en belirgindir.

DO , ara yazılımları yönlendirme ile ve yönlendirme olmadan kullanışlı hale getirir:

app.UseAuthorization(new AuthorizationPolicy() { ... });

// Your framework
app.MapMyFramework(...).RequireAuthorization();

Bu kılavuza örnek olarak ara yazılımı göz önünde bulundurun UseAuthorization . Yetkilendirme ara yazılımı bir geri dönüş ilkesi geçirmenizi sağlar. Geri dönüş ilkesi belirtilirse her ikisi için de geçerlidir:

  • Belirtilen ilke olmayan uç noktalar.
  • Uç noktayla eşleşmeyen istekler.

Bu, yetkilendirme ara yazılımını yönlendirme bağlamı dışında kullanışlı hale getirir. Yetkilendirme ara yazılımı geleneksel ara yazılım programlama için kullanılabilir.

Tanılama hatalarını ayıklama

Ayrıntılı yönlendirme tanılama çıktısı için olarak DebugayarlayınLogging:LogLevel:Microsoft. Geliştirme ortamında, içinde günlük düzeyini appsettings.Development.jsonayarlayın:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Debug",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}

Ek kaynaklar

Yönlendirme, gelen HTTP isteklerini eşleştirmek ve bu istekleri uygulamanın yürütülebilir uç noktalarına göndermekle sorumludur. Uç noktalar , uygulamanın yürütülebilir istek işleme kodu birimleridir. Uç noktalar uygulamada tanımlanır ve uygulama başlatıldığında yapılandırılır. Uç nokta eşleştirme işlemi, isteğin URL'sinden değerleri ayıklayabilir ve istek işleme için bu değerleri sağlayabilir. Yönlendirme, uygulamadaki uç nokta bilgilerini kullanarak uç noktalara eşleyen URL'ler de oluşturabilir.

Uygulamalar yönlendirmeyi şu şekilde yapılandırabilir:

  • Denetleyiciler
  • Razor Pages
  • SignalR
  • gRPC Hizmetleri
  • Sistem Durumu Denetimleri gibi uç nokta özellikli ara yazılım.
  • Yönlendirme ile kaydedilen temsilciler ve lambdalar.

Bu belge, ASP.NET Core yönlendirmesinin alt düzey ayrıntılarını kapsar. Yönlendirmeyi yapılandırma hakkında bilgi için:

Bu belgede açıklanan uç nokta yönlendirme sistemi ASP.NET Core 3.0 ve üzeri için geçerlidir. tabanlı IRouterönceki yönlendirme sistemi hakkında bilgi için aşağıdaki yaklaşımlardan birini kullanarak ASP.NET Core 2.1 sürümünü seçin:

  • Önceki bir sürüm için sürüm seçici.
  • ASP.NET Core 2.1 yönlendirme'yi seçin.

Örnek kodu görüntüleme veya indirme (indirme)

Bu belgenin indirme örnekleri belirli Startup bir sınıf tarafından etkinleştirilir. Belirli bir örneği çalıştırmak için istediğiniz sınıfı çağıracak şekilde Startup değiştirinProgram.cs.

Yönlendirmeyle ilgili temel bilgiler

Tüm ASP.NET Core şablonları, oluşturulan koda yönlendirmeyi içerir. Yönlendirme, içindeki ara yazılım işlem hattına Startup.Configurekaydedilir.

Aşağıdaki kod, yönlendirmenin temel bir örneğini gösterir:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    });
}

Yönlendirme, ve UseEndpointstarafından UseRouting kaydedilen bir ara yazılım çifti kullanır:

  • UseRouting ara yazılım işlem hattına yol eşleştirmesi ekler. Bu ara yazılım, uygulamada tanımlanan uç nokta kümesine bakar ve isteğe göre en iyi eşleşmeyi seçer.
  • UseEndpoints ara yazılım işlem hattına uç nokta yürütme ekler. Seçili uç noktayla ilişkili temsilciyi çalıştırır.

Yukarıdaki örnek, MapGet yöntemini kullanarak kod uç noktasına tek bir yol içerir:

  • Kök URL'ye /bir HTTP GET isteği gönderildiğinde:
    • Gösterilen istek temsilcisi yürütülür.
    • Hello World! HTTP yanıtına yazılır. Varsayılan olarak, kök URL'si / şeklindedir https://localhost:5001/.
  • İstek yöntemi değilse GET veya kök URL değilse /, hiçbir yol eşleşmez ve bir HTTP 404 döndürülür.

Uç nokta

MapGet yöntemi bir uç nokta tanımlamak için kullanılır. Uç nokta şu şekilde olabilir:

  • URL ve HTTP yöntemiyle eşleştirilerek seçilir.
  • Temsilci çalıştırılarak yürütülür.

Uygulama tarafından eşleştirilebilen ve yürütülebilen uç noktalar içinde UseEndpointsyapılandırılır. Örneğin, MapGet, MapPostve benzer yöntemler istek temsilcilerini yönlendirme sistemine bağlar. ASP.NET Core çerçeve özelliklerini yönlendirme sistemine bağlamak için ek yöntemler kullanılabilir:

Aşağıdaki örnekte daha gelişmiş bir yol şablonuyla yönlendirme gösterilmektedir:

app.UseEndpoints(endpoints =>
{
    endpoints.MapGet("/hello/{name:alpha}", async context =>
    {
        var name = context.Request.RouteValues["name"];
        await context.Response.WriteAsync($"Hello {name}!");
    });
});

Dize /hello/{name:alpha} bir yol şablonudur. Uç noktanın nasıl eşleşeceklerini yapılandırmak için kullanılır. Bu durumda şablon aşağıdakiyle eşleşir:

  • Gibi bir URL /hello/Ryan
  • ile /hello/ başlayan ve ardından alfabetik karakter dizisi gelen herhangi bir URL yolu. :alpha yalnızca alfabetik karakterlerle eşleşen bir yol kısıtlaması uygular. Yol kısıtlamaları bu belgenin ilerleyen bölümlerinde açıklanmıştır.

URL yolunun ikinci kesimi: {name:alpha}

  • parametresine name bağlıdır.
  • Yakalanır ve HttpRequest.RouteValues içinde depolanır.

Bu belgede açıklanan uç nokta yönlendirme sistemi, ASP.NET Core 3.0 sürümünden itibaren yenidir. Ancak, ASP.NET Core'un tüm sürümleri aynı yol şablonu özellikleri kümesini ve yol kısıtlamalarını destekler.

Aşağıdaki örnekte sistem durumu denetimleri ve yetkilendirme ile yönlendirme gösterilmektedir:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    // Matches request to an endpoint.
    app.UseRouting();

    // Endpoint aware middleware. 
    // Middleware can use metadata from the matched endpoint.
    app.UseAuthentication();
    app.UseAuthorization();

    // Execute the matched endpoint.
    app.UseEndpoints(endpoints =>
    {
        // Configure the Health Check endpoint and require an authorized user.
        endpoints.MapHealthChecks("/healthz").RequireAuthorization();

        // Configure another endpoint, no authorization requirements.
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    });
}

Kod açıklamalarının İngilizce dışındaki dillere çevirisini görmek isterseniz, bunu bu GitHub tartışma konusunda bize bildirin.

Yukarıdaki örnekte aşağıdakiler gösterilmiştir:

  • Yetkilendirme ara yazılımı yönlendirme ile kullanılabilir.
  • Yetkilendirme davranışını yapılandırmak için uç noktalar kullanılabilir.

Çağrısı bir MapHealthChecks sistem durumu denetimi uç noktası ekler. Bu çağrıya zincirleme RequireAuthorization , uç noktaya bir yetkilendirme ilkesi ekler.

Arama UseAuthentication ve UseAuthorization kimlik doğrulama ve yetkilendirme ara yazılımını ekler. Bu ara yazılım, şunları yapabilecekleri şekilde ve UseEndpoints arasına UseRouting yerleştirilir:

  • tarafından UseRoutinghangi uç noktanın seçildiğini görün.
  • Uç noktaya göndermeden önce UseEndpoints bir yetkilendirme ilkesi uygulayın.

Uç nokta meta verileri

Yukarıdaki örnekte iki uç nokta vardır, ancak yalnızca sistem durumu denetimi uç noktasının bir yetkilendirme ilkesi eklenmiştir. İstek sistem durumu denetimi uç noktasıyla /healthzeşleşiyorsa yetkilendirme denetimi gerçekleştirilir. Bu, uç noktaların bunlara ek veri ekleyebileceğini gösterir. Bu ek veriler uç nokta meta verileri olarak adlandırılır:

  • Meta veriler yönlendirme kullanan ara yazılım tarafından işlenebilir.
  • Meta veriler herhangi bir .NET türünde olabilir.

Yönlendirme kavramları

Yönlendirme sistemi, güçlü uç nokta kavramını ekleyerek ara yazılım işlem hattının üzerine inşa eder. Uç noktalar yönlendirme, yetkilendirme ve herhangi bir sayıda ASP.NET Core sistemi açısından birbirinden ayrı olan uygulama işlevlerinin birimlerini temsil eder.

ASP.NET Temel uç nokta tanımı

ASP.NET Core uç noktası:

Aşağıdaki kod, geçerli istekle eşleşen uç noktanın nasıl alınıp denetlendiğini gösterir:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseRouting();

    app.Use(next => context =>
    {
        var endpoint = context.GetEndpoint();
        if (endpoint is null)
        {
            return Task.CompletedTask;
        }
        
        Console.WriteLine($"Endpoint: {endpoint.DisplayName}");

        if (endpoint is RouteEndpoint routeEndpoint)
        {
            Console.WriteLine("Endpoint has route pattern: " +
                routeEndpoint.RoutePattern.RawText);
        }

        foreach (var metadata in endpoint.Metadata)
        {
            Console.WriteLine($"Endpoint has metadata: {metadata}");
        }

        return Task.CompletedTask;
    });

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    });
}

Uç nokta seçilirse öğesinden HttpContextalınabilir. Özellikleri incelenebilir. Uç nokta nesneleri sabittir ve oluşturulduktan sonra değiştirilemez. En yaygın uç nokta türü bir RouteEndpoint'dir. RouteEndpoint , yönlendirme sistemi tarafından seçilmesini sağlayan bilgileri içerir.

Önceki kodda, uygulama. kullan , satır içi ara yazılımı yapılandırıyor.

Aşağıdaki kod, işlem hattında çağrılan yere app.Use bağlı olarak bir uç nokta bulunmayabileceğini gösterir:

// Location 1: before routing runs, endpoint is always null here
app.Use(next => context =>
{
    Console.WriteLine($"1. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    return next(context);
});

app.UseRouting();

// Location 2: after routing runs, endpoint will be non-null if routing found a match
app.Use(next => context =>
{
    Console.WriteLine($"2. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    return next(context);
});

app.UseEndpoints(endpoints =>
{
    // Location 3: runs when this endpoint matches
    endpoints.MapGet("/", context =>
    {
        Console.WriteLine(
            $"3. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
        return Task.CompletedTask;
    }).WithDisplayName("Hello");
});

// Location 4: runs after UseEndpoints - will only run if there was no match
app.Use(next => context =>
{
    Console.WriteLine($"4. Endpoint: {context.GetEndpoint()?.DisplayName ?? "(null)"}");
    return next(context);
});

Bu önceki örnek, bir uç noktanın seçili olup olmadığını görüntüleyen deyimler ekler Console.WriteLine . Netlik sağlamak için örnek, sağlanan / uç noktaya bir görünen ad atar.

Bu kodu ekranların URL'si / ile çalıştırma:

1. Endpoint: (null)
2. Endpoint: Hello
3. Endpoint: Hello

Bu kodu başka herhangi bir URL ile çalıştırmak şunu görüntüler:

1. Endpoint: (null)
2. Endpoint: (null)
4. Endpoint: (null)

Bu çıkış şunları gösterir:

  • Çağrılmadan önce UseRouting uç nokta her zaman null'tır.
  • Eşleşme bulunursa, ile UseEndpointsarasında UseRouting uç nokta null değildir.
  • Bir UseEndpoints eşleşme bulunduğunda ara yazılım terminaldir . Terminal ara yazılımı bu belgenin ilerleyen bölümlerinde tanımlanmıştır.
  • Yürüttkten sonra UseEndpoints ara yazılım yalnızca eşleşme bulunamadığında yürütülür.

Ara yazılım, UseRouting uç noktayı geçerli bağlama eklemek için SetEndpoint yöntemini kullanır. Ara yazılımı özel mantıkla değiştirmek UseRouting ve yine de uç noktaları kullanmanın avantajlarından yararlanmak mümkündür. Uç noktalar ara yazılım gibi alt düzey bir temel öğedir ve yönlendirme uygulamasıyla birleştirilmiş değildir. Çoğu uygulamanın özel mantıkla değiştirilmesi UseRouting gerekmez.

Ara UseEndpoints yazılım, ara yazılımla UseRouting birlikte kullanılacak şekilde tasarlanmıştır. Bir uç noktayı yürütmek için temel mantık karmaşık değildir. Uç noktayı almak ve ardından özelliğini RequestDelegate çağırmak için kullanınGetEndpoint.

Aşağıdaki kodda ara yazılımların yönlendirmeyi nasıl etkilediği veya buna nasıl tepki gösterebileceği gösterilmektedir:

public class IntegratedMiddlewareStartup
{ 
    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }

        // Location 1: Before routing runs. Can influence request before routing runs.
        app.UseHttpMethodOverride();

        app.UseRouting();

        // Location 2: After routing runs. Middleware can match based on metadata.
        app.Use(next => context =>
        {
            var endpoint = context.GetEndpoint();
            if (endpoint?.Metadata.GetMetadata<AuditPolicyAttribute>()?.NeedsAudit
                                                                            == true)
            {
                Console.WriteLine($"ACCESS TO SENSITIVE DATA AT: {DateTime.UtcNow}");
            }

            return next(context);
        });

        app.UseEndpoints(endpoints =>
        {         
            endpoints.MapGet("/", async context =>
            {
                await context.Response.WriteAsync("Hello world!");
            });

            // Using metadata to configure the audit policy.
            endpoints.MapGet("/sensitive", async context =>
            {
                await context.Response.WriteAsync("sensitive data");
            })
            .WithMetadata(new AuditPolicyAttribute(needsAudit: true));
        });

    } 
}

public class AuditPolicyAttribute : Attribute
{
    public AuditPolicyAttribute(bool needsAudit)
    {
        NeedsAudit = needsAudit;
    }

    public bool NeedsAudit { get; }
}

Yukarıdaki örnekte iki önemli kavram gösterilmektedir:

  • Ara yazılım, yönlendirmenin üzerinde çalıştığı verileri değiştirmek için daha önce UseRouting çalışabilir.
  • Ara yazılım, uç nokta yürütülmeden önce yönlendirme sonuçlarını işlemek için ve UseEndpoints arasında UseRouting çalışabilir.
    • ile UseEndpointsarasında UseRouting çalışan ara yazılım:
      • Genellikle uç noktaları anlamak için meta verileri inceler.
      • ve tarafından UseAuthorizationUseCorsyapıldığı gibi genellikle güvenlik kararları alır.
    • Ara yazılım ve meta verilerin birleşimi, uç nokta başına ilkelerin yapılandırılmasına olanak tanır.

Yukarıdaki kod, uç nokta başına ilkeleri destekleyen özel bir ara yazılım örneğini gösterir. Ara yazılım, konsola hassas verilere erişimin denetim günlüğünü yazar. Ara yazılım, meta verilerle AuditPolicyAttribute bir uç noktayı denetleyecek şekilde yapılandırılabilir. Bu örnek, yalnızca hassas olarak işaretlenmiş uç noktaların denetlendiği bir kabul etme deseni gösterir. Bu mantığı tersten tanımlamak, örneğin güvenli olarak işaretlenmemiş her şeyi denetlemek mümkündür. Uç nokta meta veri sistemi esnektir. Bu mantık, kullanım örneğine uygun şekilde tasarlanabilir.

Yukarıdaki örnek kod, uç noktaların temel kavramlarını göstermeye yöneliktir. Örnek, üretim kullanımı için tasarlanmamıştır. Denetim günlüğü ara yazılımının daha eksiksiz bir sürümü şunları yapar:

  • Bir dosyada veya veritabanında oturum açın.
  • Kullanıcı, IP adresi, hassas uç noktanın adı ve daha fazlası gibi ayrıntıları ekleyin.

Denetim ilkesi meta verileriAuditPolicyAttribute, denetleyiciler ve SignalRgibi sınıf tabanlı çerçevelerle daha kolay kullanım için olarak Attribute tanımlanır. Koda giden yol kullanılırken:

  • Meta veriler bir oluşturucu API'siyle eklenir.
  • Sınıf tabanlı çerçeveler, uç noktaları oluştururken ilgili yöntem ve sınıftaki tüm öznitelikleri içerir.

Meta veri türleri için en iyi yöntemler bunları arabirim veya öznitelik olarak tanımlamaktır. Arabirimler ve öznitelikler kodun yeniden kullanılmasına izin verir. Meta veri sistemi esnektir ve herhangi bir sınırlama getirmez.

Terminal ara yazılımını ve yönlendirmeyi karşılaştırma

Aşağıdaki kod örneği, ara yazılımı kullanarak yönlendirmeyi kullanmayla karşıttır:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    // Approach 1: Writing a terminal middleware.
    app.Use(next => async context =>
    {
        if (context.Request.Path == "/")
        {
            await context.Response.WriteAsync("Hello terminal middleware!");
            return;
        }

        await next(context);
    });

    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        // Approach 2: Using routing.
        endpoints.MapGet("/Movie", async context =>
        {
            await context.Response.WriteAsync("Hello routing!");
        });
    });
}

ile Approach 1: gösterilen ara yazılım stili, terminal ara yazılımıdır. Eşleşen bir işlem yaptığı için buna terminal ara yazılımı denir:

  • Yukarıdaki örnekteki eşleştirme işlemi ara yazılıma ve Path == "/Movie" yönlendirmeye yöneliktirPath == "/".
  • Eşleşme başarılı olduğunda ara yazılımı çağırmak next yerine bazı işlevleri yürütür ve döndürür.

Aramayı sonlandırdığından, bazı işlevler yürüttüğünden ve ardından döndürdüğünden terminal ara yazılımı olarak adlandırılır.

Terminal ara yazılımını ve yönlendirmeyi karşılaştırma:

  • Her iki yaklaşım da işlem hattını sonlandırmaya olanak sağlar:
    • Ara yazılım, çağırmak yerine döndürerek işlem hattını sonlandırır next.
    • Uç noktalar her zaman terminaldir.
  • Terminal ara yazılımı, ara yazılımı işlem hattında rastgele bir yere konumlandırmaya olanak tanır:
  • Terminal ara yazılımı, ara yazılımın ne zaman eşleşeceğini belirlemek için rastgele koda izin verir:
    • Özel yol eşleştirme kodu ayrıntılı olabilir ve doğru yazılması zor olabilir.
    • Yönlendirme, tipik uygulamalar için basit çözümler sağlar. Çoğu uygulama özel yol eşleştirme kodu gerektirmez.
  • ve UseCorsgibi UseAuthorization ara yazılımlarla uç noktalar arabirimi.
    • veya ile UseAuthorizationUseCors terminal ara yazılımı kullanmak için yetkilendirme sistemiyle el ile birlikte çalışma gerekir.

nokta her ikisini de tanımlar:

  • İstekleri işlemek için bir temsilci.
  • Rastgele meta veriler koleksiyonu. Meta veriler, her uç noktaya eklenen ilkelere ve yapılandırmaya göre çapraz kesme endişeleri uygulamak için kullanılır.

Terminal ara yazılımı etkili bir araç olabilir, ancak şunları gerektirebilir:

  • Önemli miktarda kodlama ve test.
  • İstenen esneklik düzeyine ulaşmak için diğer sistemlerle el ile tümleştirme.

Terminal ara yazılımı yazmadan önce yönlendirmeyle tümleştirmeyi göz önünde bulundurun.

Map ile tümleşen veya MapWhen genellikle yönlendirme kullanan bir uç noktaya dönüştürülebilen mevcut terminal ara yazılımı. MapHealthChecks , yönlendirici yazılımı desenini gösterir:

  • üzerinde IEndpointRouteBuilderbir uzantı yöntemi yazın.
  • kullanarak CreateApplicationBuilderiç içe bir ara yazılım işlem hattı oluşturun.
  • Ara yazılımı yeni işlem hattına ekleyin. Bu durumda, UseHealthChecks.
  • Buildara yazılım işlem hattı içine .RequestDelegate
  • Yeni ara yazılım işlem hattını çağırın Map ve sağlayın.
  • uzantı yönteminden tarafından Map sağlanan oluşturucu nesnesini döndürür.

Aşağıdaki kod MapHealthChecks kullanımını gösterir:

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    // Matches request to an endpoint.
    app.UseRouting();

    // Endpoint aware middleware. 
    // Middleware can use metadata from the matched endpoint.
    app.UseAuthentication();
    app.UseAuthorization();

    // Execute the matched endpoint.
    app.UseEndpoints(endpoints =>
    {
        // Configure the Health Check endpoint and require an authorized user.
        endpoints.MapHealthChecks("/healthz").RequireAuthorization();

        // Configure another endpoint, no authorization requirements.
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Hello World!");
        });
    });
}

Yukarıdaki örnek, oluşturucu nesnesini döndürmenin neden önemli olduğunu gösterir. Oluşturucu nesnesini döndürmek, uygulama geliştiricisinin uç nokta için yetkilendirme gibi ilkeleri yapılandırmasına olanak tanır. Bu örnekte sistem durumu denetimleri ara yazılımının yetkilendirme sistemiyle doğrudan tümleştirmesi yoktur.

Meta veri sistemi, terminal ara yazılımı kullanılarak genişletilebilirlik yazarlarının karşılaştığı sorunlara yanıt olarak oluşturulmuştur. Her ara yazılım için yetkilendirme sistemiyle kendi tümleştirmesini uygulamak sorunludur.

URL eşleştirme

  • Yönlendirmenin bir uç noktaya gelen istekle eşleşmesi işlemidir.
  • URL yolundaki verileri ve üst bilgileri temel alır.
  • İstekteki tüm verileri dikkate almak için genişletilebilir.

Yönlendirme ara yazılımı yürütürken, geçerli istekten bir istek özelliğine HttpContext ve yönlendirme değerleri ayarlar:Endpoint

  • HttpContext.GetEndpoint çağrısı uç noktayı alır.
  • HttpRequest.RouteValues yol değerlerinin koleksiyonunu alır.

Ara yazılım , yönlendirme ara yazılımı uç noktayı inceleyip işlem gerçekleştirdikten sonra çalışır. Örneğin, yetkilendirme ara yazılımı bir yetkilendirme ilkesi için uç noktanın meta veri koleksiyonunu sorgulayabilir. İstek işleme işlem hattındaki ara yazılımların tümü yürütüldükten sonra seçili uç noktanın temsilcisi çağrılır.

Uç nokta yönlendirmesindeki yönlendirme sistemi, tüm gönderme kararlarının sorumluluğundadır. Ara yazılım, seçili uç noktayı temel alan ilkeler uyguladığından aşağıdakiler önemlidir:

  • Göndermeyi veya güvenlik ilkelerinin uygulanmasını etkileyebilecek tüm karar yönlendirme sistemi içinde alınır.

Uyarı

Geriye dönük uyumluluk için, bir Denetleyici veya Razor Sayfalar uç nokta temsilcisi yürütülürken RouteContext.RouteData'nın özellikleri, şu ana kadar gerçekleştirilen istek işlemeye göre uygun değerlere ayarlanır.

Tür RouteContext , gelecekteki bir sürümde kullanım dışı olarak işaretlenecektir:

  • öğesine geçiş.RouteData.ValuesHttpRequest.RouteValues
  • Uç nokta meta verilerinden IDataTokensMetadata almak için geçişRouteData.DataTokens.

URL eşleştirme, yapılandırılabilir bir aşama kümesinde çalışır. Her aşamada çıkış, bir eşleşme kümesidir. Eşleşme kümesi bir sonraki aşamaya kadar daraltılabilir. Yönlendirme uygulaması, eşleşen uç noktalar için işleme sırasını garanti etmez. Tüm olası eşleşmeler aynı anda işlenir. URL eşleştirme aşamaları aşağıdaki sırada gerçekleşir. ASP.NET Core:

  1. URL yolunu, tüm eşleşmeleri toplayarak uç noktalar kümesine ve bunların yol şablonlarına göre işler.
  2. Önceki listeyi alır ve yol kısıtlamaları uygulanarak başarısız olan eşleşmeleri kaldırır.
  3. Önceki listeyi alır ve MatcherPolicy örnekleri kümesinde başarısız olan eşleşmeleri kaldırır.
  4. Yukarıdaki listeden son kararı vermek için EndpointSelector'ı kullanır.

Uç nokta listesi aşağıdakilere göre önceliklendirilir:

Eşleşen tüm uç noktalar, öğesine ulaşılana EndpointSelector kadar her aşamada işlenir. EndpointSelector son aşamadır. Eşleşmeler arasından en yüksek öncelikli uç noktayı en iyi eşleşme olarak seçer. En iyi eşleşmeyle aynı önceliğe sahip başka eşleşmeler varsa, belirsiz bir eşleşme özel durumu oluşturulur.

Yol önceliği, daha yüksek önceliğe sahip daha belirli bir yol şablonuna göre hesaplanır. Örneğin, ve şablonlarını /hello/{message}göz önünde bulundurun:

  • Her ikisi de URL yolu ile eşleşer /hello.
  • /hello daha belirgindir ve bu nedenle daha yüksek önceliklidir.

Genel olarak, rota önceliği, uygulamada kullanılan URL düzenleri türleri için en iyi eşleşmeyi seçmek için iyi bir iştir. Yalnızca belirsizlikten kaçınmak için gerektiğinde kullanın Order .

Yönlendirme tarafından sağlanan genişletilebilirlik türleri nedeniyle, yönlendirme sisteminin belirsiz yolları önceden hesaplaması mümkün değildir. Yol şablonları /{message:alpha} ve /{message:int}gibi bir örneği göz önünde bulundurun:

  • Kısıtlama alpha yalnızca alfabetik karakterlerle eşleşir.
  • Kısıtlama int yalnızca sayılarla eşleşir.
  • Bu şablonlar aynı yol önceliğine sahiptir, ancak her ikisi de eşleşen tek bir URL yoktur.
  • Yönlendirme sistemi başlangıçta bir belirsizlik hatası bildirdiyse, bu geçerli kullanım örneğini engeller.

Uyarı

içindeki UseEndpoints işlemlerin sırası, bir özel durum dışında yönlendirme davranışını etkilemez. MapControllerRoute ve MapAreaRoute çağrıldıkları sırayla uç noktalarına otomatik olarak bir sipariş değeri atayın. Bu, eski yönlendirme uygulamalarıyla aynı garantileri sağlayan yönlendirme sistemi olmadan denetleyicilerin uzun süreli davranışının benzetimini oluşturur.

Yönlendirmenin eski uygulamasında, yolların işlenme sırasına bağımlılığı olan yönlendirme genişletilebilirliğini uygulamak mümkündür. ASP.NET Core 3.0 ve sonraki sürümlerde uç nokta yönlendirme:

  • Rota kavramı yoktur.
  • Sipariş garantisi sağlamaz. Tüm uç noktalar aynı anda işlenir.

Rota şablonu önceliği ve uç nokta seçim sırası

Yol şablonu önceliği , her yol şablonuna ne kadar özel olduğuna göre bir değer atayan bir sistemdir. Yol şablonu önceliği:

  • Sık karşılaşılan durumlarda uç noktaların sırasını ayarlama gereğini önler.
  • Yönlendirme davranışıyla ilgili sağduyunun beklentilerini eşleştirmeye çalışır.

Örneğin, ve /Products/{id}şablonlarını /Products/List göz önünde bulundurun. URL yolundan /Products/Listdaha iyi bir eşleşme /Products/{id} olduğunu /Products/List varsaymak mantıklı olacaktır. Sabit segmentin parametre kesiminden /List/{id}daha iyi önceliğe sahip olduğu kabul edildiğinden bu işe yarar.

Önceliğin nasıl çalıştığına ilişkin ayrıntılar, yol şablonlarının nasıl tanımlandığına göre belirlenir:

  • Daha fazla segmente sahip şablonlar daha belirgin olarak kabul edilir.
  • Değişmez metin içeren bir kesim, parametre kesiminden daha özel olarak kabul edilir.
  • Kısıtlaması olan bir parametre kesimi, olmadan birden fazla özel olarak kabul edilir.
  • Karmaşık bir kesim, kısıtlaması olan bir parametre kesimi olarak özel olarak kabul edilir.
  • Tümünü yakala parametreleri en az belirlidir. Tümünü yakala yolları hakkında önemli bilgiler için bkz. Yol şablonu başvurusunda tümünü yakala.

Tam değerlerin başvurusu için GitHub'da kaynak koduna bakın.

URL oluşturma kavramları

URL oluşturma:

  • Yönlendirmenin bir yol değerleri kümesine dayalı bir URL yolu oluşturabildiği işlemdir.
  • Uç noktalar ile bunlara erişen URL'ler arasında mantıksal ayrım yapılmasını sağlar.

Uç nokta yönlendirme api'sini LinkGenerator içerir. LinkGenerator , DI'den kullanılabilen tek bir hizmettir. API, LinkGenerator yürütme isteği bağlamının dışında kullanılabilir. Mvc.IUrlHelper ve kullanan Etiket Yardımcıları, HTML Yardımcıları ve Eylem Sonuçları gibi senaryolarIUrlHelper, bağlantı oluşturma özellikleri sağlamak için API'yi dahili olarak kullanırLinkGenerator.

Bağlantı oluşturucu, adres ve adres düzenleri kavramı tarafından yedeklenmiştir. Adres düzeni, bağlantı oluşturma için dikkate alınması gereken uç noktaları belirlemenin bir yoludur. Örneğin, birçok kullanıcının denetleyicilerden aşina olduğu yol adı ve yol değerleri senaryoları ve Razor Sayfalar bir adres düzeni olarak uygulanır.

Bağlantı oluşturucu, aşağıdaki uzantı yöntemleri aracılığıyla denetleyicilere ve Razor Sayfalara bağlanabilir:

Bu yöntemlerin aşırı yüklemeleri, öğesini içeren HttpContextbağımsız değişkenleri kabul eder. Bu yöntemler işlevsel olarak Url.Action ve Url.Page eşdeğerdir, ancak ek esneklik ve seçenekler sunar.

GetPath* Yöntemler, mutlak yol içeren bir URI oluşturmaları için Url.Action ve Url.Pageile en benzerleridir. GetUri* Yöntemler her zaman bir düzen ve konak içeren mutlak bir URI oluşturur. Kabul HttpContext eden yöntemler, yürütme isteği bağlamında bir URI oluşturur. Geçersiz kılınmadıkça, yürütülen istekten ortam yolu değerleri, URL temel yolu, şema ve konak kullanılır.

LinkGenerator bir adresle çağrılır. URI oluşturma işlemi iki adımda gerçekleşir:

  1. Adres, adresle eşleşen uç noktaların listesine bağlıdır.
  2. Sağlanan değerlerle eşleşen bir yol deseni bulunana kadar her uç noktanın RoutePattern değerleri değerlendirilir. Sonuçta elde edilen çıkış, bağlantı oluşturucuya sağlanan diğer URI parçalarıyla birleştirilir ve döndürülür.

tarafından LinkGenerator sağlanan yöntemler, her tür adres için standart bağlantı oluşturma özelliklerini destekler. Bağlantı oluşturucuyu kullanmanın en kolay yolu, belirli bir adres türü için işlemler gerçekleştiren uzantı yöntemleridir:

Uzantı Yöntemi Açıklama
GetPathByAddress Sağlanan değerleri temel alan mutlak bir yola sahip bir URI oluşturur.
GetUriByAddress Sağlanan değerlere göre mutlak bir URI oluşturur.

Uyarı

Çağırma LinkGenerator yöntemlerinin aşağıdaki etkilerine dikkat edin:

  • Gelen isteklerin üst bilgisini doğrulamayan Host bir uygulama yapılandırmasında uzantı yöntemlerini dikkatli kullanınGetUri*. Gelen isteklerin Host üst bilgisi doğrulanmazsa, güvenilmeyen istek girişi bir görünüm veya sayfadaki URI'lerde istemciye geri gönderilebilir. Tüm üretim uygulamalarının, üst bilgiyi bilinen geçerli değerlerle doğrulayacak Host şekilde yapılandırmalarını öneririz.

  • veya ile MapMapWhenbirlikte ara yazılımda dikkatli kullanınLinkGenerator. Map* , bağlantı oluşturmanın çıkışını etkileyen yürütme isteğinin temel yolunu değiştirir. Tüm API'ler LinkGenerator bir temel yol belirtmeye izin verir. Bağlantı oluşturma üzerindeki etkiyi Map* geri almak için boş bir temel yol belirtin.

Ara yazılım örneği

Aşağıdaki örnekte ara yazılım, depo ürünlerini listeleyen bir eylem yöntemine bağlantı oluşturmak için API'yi kullanır LinkGenerator . Bağlantı oluşturucuyu bir sınıfa ekleyerek kullanma ve bir uygulamadaki herhangi bir sınıf için çağrısı GenerateLink yapmak mümkündür:

public class ProductsLinkMiddleware
{
    private readonly LinkGenerator _linkGenerator;

    public ProductsLinkMiddleware(RequestDelegate next, LinkGenerator linkGenerator)
    {
        _linkGenerator = linkGenerator;
    }

    public async Task InvokeAsync(HttpContext httpContext)
    {
        var url = _linkGenerator.GetPathByAction("ListProducts", "Store");

        httpContext.Response.ContentType = "text/plain";

        await httpContext.Response.WriteAsync($"Go to {url} to see our products.");
    }
}

Yol şablonu başvurusu

içindeki {} belirteçler, yol eşleşirse bağlı olan yol parametrelerini tanımlar. Yol kesiminde birden fazla yol parametresi tanımlanabilir, ancak yol parametreleri değişmez değerle ayrılmalıdır. Örneğin, {controller=Home}{action=Index} ile {action}arasında {controller} değişmez değer olmadığından geçerli bir yol değildir. Yol parametreleri bir ada sahip olmalı ve ek öznitelikler belirtilmiş olabilir.

Yol parametreleri dışındaki değişmez metin (örneğin, {id}) ve yol ayırıcı / url'deki metinle eşleşmelidir. Metin eşleştirme büyük/küçük harfe duyarlı değildir ve URL'nin yolunun kod çözülen gösterimine dayanır. Sabit yol parametresi sınırlayıcısı { veya }ile eşleştirmek için, karakteri yineleyerek sınırlayıcıdan kaçın. Örneğin {{ veya }}.

Yıldız işareti * veya çift yıldız **işareti:

  • URI'nin geri kalanına bağlanmak için bir yol parametresine ön ek olarak kullanılabilir.
  • Tümünü yakala parametreleri olarak adlandırılır. Örneğin, blog/{**slug}:
    • ile başlayan ve onu izleyen herhangi bir değere sahip URI'lerle /blog eşleşir.
    • Aşağıdaki /blog değer, bilgi yolu değerine atanır.

Uyarı

Tümünü yakala parametresi, yönlendirmedeki bir hata nedeniyle yolları yanlış eşleştirebilir. Bu hatadan etkilenen uygulamalar aşağıdaki özelliklere sahiptir:

  • Tümünü yakala yolu, örneğin, {**slug}"
  • Tümünü yakala yolu eşleşmesi gereken isteklerle eşleşemiyor.
  • Diğer yolların kaldırılması, tümünü yakala yolunun çalışmaya başlamasını sağlar.

Bu hataya isabet eden durumlar için bkz. GitHub hataları 18677 ve 16579 .

Bu hata için bir kabul düzeltmesi .NET Core 3.1.301 SDK ve sonraki sürümlerde yer alır. Aşağıdaki kod, bu hatayı düzelten bir iç anahtar ayarlar:

public static void Main(string[] args)
{
   AppContext.SetSwitch("Microsoft.AspNetCore.Routing.UseCorrectCatchAllBehavior", 
                         true);
   CreateHostBuilder(args).Build().Run();
}
// Remaining code removed for brevity.

Tümünü yakala parametreleri de boş dizeyle eşleşebilir.

Yol ayırıcı / karakterleri de dahil olmak üzere bir URL oluşturmak için yol kullanıldığında tümünü yakala parametresi uygun karakterlerin kaçışını verir. Örneğin, yol değerlerine { path = "my/path" } sahip yol foo/{*path} oluştururfoo/my%2Fpath. Kaçış eğik çizgisine dikkat edin. Gidiş dönüş yol ayırıcı karakterleri için yol parametresi ön ekini ** kullanın. ile { path = "my/path" } yolu foo/{**path} oluştururfoo/my/path.

İsteğe bağlı dosya uzantısına sahip bir dosya adını yakalamaya çalışan URL desenlerinin dikkate alınması gereken ek noktalar vardır. Örneğin, şablonunu files/{filename}.{ext?}göz önünde bulundurun. Hem hem de filenameext değerleri mevcut olduğunda, her iki değer de doldurulur. URL'de yalnızca için filename bir değer varsa, yol eşleşir çünkü sondaki . isteğe bağlıdır. Aşağıdaki URL'ler bu yolla eşleşti:

  • /files/myFile.txt
  • /files/myFile

Yol parametrelerinde, parametre adından sonra eşittir işaretiyle (= ) ayrılmış varsayılan değer belirtilerek varsayılan değerler belirlenebilir. Örneğin, {controller=Home} için controllervarsayılan değer olarak tanımlarHome. Parametresinin URL'sinde değer yoksa varsayılan değer kullanılır. Yol parametreleri, parametre adının sonuna bir soru işareti (?) eklenerek isteğe bağlıdır. Örneğin, id?. İsteğe bağlı değerler ile varsayılan yol parametreleri arasındaki fark:

  • Varsayılan değere sahip bir yol parametresi her zaman bir değer üretir.
  • İsteğe bağlı bir parametre yalnızca istek URL'si tarafından bir değer sağlandığında bir değere sahiptir.

Yol parametreleri, URL'den bağlanan yol değeriyle eşleşmesi gereken kısıtlamalara sahip olabilir. Yol parametresi adından sonra ekleme : ve kısıtlama adı, bir yol parametresinde satır içi kısıtlama belirtir. Kısıtlama bağımsız değişkenler gerektiriyorsa, bunlar kısıtlama adından sonra parantez (...) içine alınır. Başka bir : ve kısıtlama adı eklenerek birden çok satır içi kısıtlama belirtilebilir.

Kısıtlama adı ve bağımsız değişkenleri, URL işlemede IInlineConstraintResolver kullanılacak örneğini IRouteConstraint oluşturmak için hizmete geçirilir. Örneğin, yol şablonu blog/{article:minlength(10)} bağımsız değişkeniyle 10bir minlength kısıtlama belirtir. Yol kısıtlamaları hakkında daha fazla bilgi ve çerçeve tarafından sağlanan kısıtlamaların listesi için Yol kısıtlaması başvurusu bölümüne bakın.

Rota parametrelerinde de parametre transformatörleri olabilir. Parametre transformatörleri, url'lere bağlantılar ve eşleşen eylemler ve sayfalar oluştururken parametrenin değerini dönüştürür. Kısıtlamalar gibi parametre transformatörleri de rota parametresi adından sonra bir : ve transformatör adı eklenerek bir yol parametresine satır içi olarak eklenebilir. Örneğin, yol şablonu blog/{article:slugify} bir slugify transformatör belirtir. Parametre transformatörleri hakkında daha fazla bilgi için Parametre transformatörü başvurusu bölümüne bakın.

Aşağıdaki tabloda örnek yol şablonları ve davranışları gösterilmektedir:

Rota Şablonu Örnek Eşleşen URI İstek URI'si...
hello /hello Yalnızca tek yol ile eşleşir /hello.
{Page=Home} / ile eşleşir ve ile eşleşir PageHome.
{Page=Home} /Contact ile eşleşir ve ile eşleşir PageContact.
{controller}/{action}/{id?} /Products/List Denetleyiciye ve List eyleme Products Haritalar.
{controller}/{action}/{id?} /Products/Details/123 Denetleyiciye Products Haritalar ve Details 123 olarak ayarlanmış eylemid.
{controller=Home}/{action=Index}/{id?} / Denetleyiciye ve Index yönteme Home Haritalar. id yoksayılır.
{controller=Home}/{action=Index}/{id?} /Products Denetleyiciye ve Index yönteme Products Haritalar. id yoksayılır.

Şablon kullanmak genellikle yönlendirmeye en basit yaklaşımdır. Kısıtlamalar ve varsayılanlar, yol şablonunun dışında da belirtilebilir.

Karmaşık segmentler

Karmaşık segmentler, doyumsuz olmayan bir şekilde sağdan sola sabit sınırlayıcıları eşleştirerek işlenir. Örneğin, [Route("/a{b}c{d}")] karmaşık bir kesimdir. Karmaşık segmentler, bunları başarıyla kullanmak için anlaşılması gereken belirli bir şekilde çalışır. Bu bölümdeki örnekte, karmaşık segmentlerin neden yalnızca sınırlayıcı metin parametre değerlerinin içinde görünmediğinde gerçekten iyi çalıştığı gösterilmektedir. Daha karmaşık durumlar için bir regex kullanmak ve sonra değerleri el ile ayıklamak gerekir.

Uyarı

Güvenilmeyen girişi işlemek için kullanırken System.Text.RegularExpressions bir zaman aşımı geçirin. Kötü amaçlı bir kullanıcı Hizmet Reddi saldırısına neden olacak RegularExpressionsgirişler sağlayabilir. ASP.NET Zaman aşımı kullanan RegularExpressions Core framework API'leri.

Bu, yönlendirmenin şablon /a{b}c{d} ve URL yolu /abcdile gerçekleştirdiği adımların özetidir. |, algoritmanın nasıl çalıştığını görselleştirmeye yardımcı olmak için kullanılır:

  • İlk değişmez değer, sağdan sola, şeklindedir c. Bu nedenle /abcd sağdan aranıp öğesini bulur /ab|c|d.
  • Sağdaki (d) her şey artık yol parametresiyle {d}eşleştirilir.
  • Sağdan sola doğru sonraki değişmez değer olur a. Kaldığımız /ab|c|d yerden başlayarak arandı, sonra a bulunur /|a|b|c|d.
  • Sağındaki (b) değeri artık route parametresiyle {b}eşleştirilir.
  • Kalan metin ve kalan yol şablonu olmadığından bu bir eşleşmedir.

Aşağıda, aynı şablonu /a{b}c{d} ve URL yolunu kullanan negatif bir durum örneği verilmişti /aabcd. |, algoritmanın nasıl çalıştığını görselleştirmeye yardımcı olmak için kullanılır. Bu durum aynı algoritmayla açıklanan bir eşleşme değildir:

  • İlk değişmez değer, sağdan sola, şeklindedir c. Bu nedenle /aabcd sağdan aranıp öğesini bulur /aab|c|d.
  • Sağdaki (d) her şey artık yol parametresiyle {d}eşleştirilir.
  • Sağdan sola doğru sonraki değişmez değer olur a. Kaldığımız /aab|c|d yerden başlayarak arandı, sonra a bulunur /a|a|b|c|d.
  • Sağındaki (b) değeri artık route parametresiyle {b}eşleştirilir.
  • Bu noktada kalan metin avardır, ancak algoritmada ayrıştırılacak yol şablonu tükendi, bu nedenle bu eşleşme değildir.

Eşleşen algoritma doyumsuz olmadığından:

  • Her adımda mümkün olan en küçük metin miktarıyla eşleşir.
  • Sınırlayıcı değerinin parametre değerlerinin içinde göründüğü her durumda eşleşmez.

Normal ifadeler, eşleşen davranışları üzerinde çok daha fazla denetim sağlar.

Yavaş eşleştirme olarak da bilinen doyumsuz eşleştirme, mümkün olan en büyük dizeyle eşleşir. Doyumsuz olmayan, mümkün olan en küçük dizeyle eşleşir.

Yol kısıtlaması başvurusu

Yönlendirme kısıtlamaları, gelen URL'de bir eşleşme oluştuğunda ve URL yolu yol değerlerine belirteç olarak ayarlandığında yürütülür. Yol kısıtlamaları genellikle yol şablonu aracılığıyla ilişkili yol değerini inceler ve değerin kabul edilebilir olup olmadığı konusunda doğru veya yanlış bir karar verir. Bazı yol kısıtlamaları, isteğin yönlendirilip yönlendirilemeyeceğini göz önünde bulundurmak için yol değerinin dışındaki verileri kullanır. Örneğin, HttpMethodRouteConstraint http fiiline göre bir isteği kabul edebilir veya reddedebilir. Kısıtlamalar yönlendirme isteklerinde ve bağlantı oluşturmada kullanılır.

Uyarı

Giriş doğrulaması için kısıtlamaları kullanmayın. Giriş doğrulaması için kısıtlamalar kullanılıyorsa geçersiz giriş Bulunamadı yanıtında 404 sonuçlanıyor. Geçersiz giriş, uygun bir 400 hata iletisiyle Hatalı İstek oluşturmalıdır. Yol kısıtlamaları, belirli bir yolun girişlerini doğrulamak için değil, benzer yolların belirsizliğini belirlemek için kullanılır.

Aşağıdaki tabloda örnek yol kısıtlamaları ve beklenen davranışları gösterilmektedir:

kısıtlama Örnek Örnek Eşleşmeler Notlar
int {id:int} 123456789, -123456789 Herhangi bir tamsayıyla eşleşir
bool {active:bool} true, FALSE veya falseile eşleşirtrue. Duyarlı
datetime {dob:datetime} 2016-12-31, 2016-12-31 7:32pm Sabit kültürdeki geçerli DateTime bir değerle eşleşir. Önceki uyarıya bakın.
decimal {price:decimal} 49.99, -1,000.01 Sabit kültürdeki geçerli decimal bir değerle eşleşir. Önceki uyarıya bakın.
double {weight:double} 1.234, -1,001.01e8 Sabit kültürdeki geçerli double bir değerle eşleşir. Önceki uyarıya bakın.
float {weight:float} 1.234, -1,001.01e8 Sabit kültürdeki geçerli float bir değerle eşleşir. Önceki uyarıya bakın.
guid {id:guid} CD2C1638-1638-72D5-1638-DEADBEEF1638 Geçerli Guid bir değerle eşleşir
long {ticks:long} 123456789, -123456789 Geçerli long bir değerle eşleşir
minlength(value) {username:minlength(4)} Rick Dize en az 4 karakter olmalıdır
maxlength(value) {filename:maxlength(8)} MyFile Dize 8 karakterden fazla olmamalıdır
length(length) {filename:length(12)} somefile.txt Dize tam olarak 12 karakter uzunluğunda olmalıdır
length(min,max) {filename:length(8,16)} somefile.txt Dize en az 8 ve en fazla 16 karakter uzunluğunda olmalıdır
min(value) {age:min(18)} 19 Tamsayı değeri en az 18 olmalıdır
max(value) {age:max(120)} 91 Tamsayı değeri en fazla 120 olmalıdır
range(min,max) {age:range(18,120)} 91 Tamsayı değeri en az 18, en fazla 120 olmalıdır
alpha {name:alpha} Rick Dize bir a-z veya daha fazla alfabetik karakterden ve büyük/küçük harfe duyarsız karakterden oluşmalıdır.
regex(expression) {ssn:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)} 123-45-6789 Dize normal ifadeyle eşleşmelidir. Normal ifade tanımlama hakkındaki ipuçlarına bakın.
required {name:required} Rick URL oluşturma sırasında parametre olmayan bir değerin mevcut olmasını zorunlu kılmak için kullanılır

Uyarı

Güvenilmeyen girişi işlemek için kullanırken System.Text.RegularExpressions bir zaman aşımı geçirin. Kötü amaçlı bir kullanıcı Hizmet Reddi saldırısına neden olacak RegularExpressionsgirişler sağlayabilir. ASP.NET Zaman aşımı kullanan RegularExpressions Core framework API'leri.

Tek bir parametreye birden çok iki nokta üst üste sınırlandırılmış kısıtlama uygulanabilir. Örneğin, aşağıdaki kısıtlama bir parametreyi 1 veya daha büyük bir tamsayı değeriyle kısıtlar:

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

Uyarı

URL'yi doğrulayan ve CLR türüne dönüştürülen yol kısıtlamaları her zaman sabit kültürü kullanır. Örneğin, CLR türüne int veya DateTimedönüştürme. Bu kısıtlamalar URL'nin yerelleştirilebilir olmadığını varsayar. Çerçeve tarafından sağlanan yol kısıtlamaları, yol değerlerinde depolanan değerleri değiştirmez. URL'den ayrıştırılan tüm yol değerleri dize olarak depolanır. Örneğin kısıtlama, float yol değerini kayan değere dönüştürmeye çalışır, ancak dönüştürülen değer yalnızca float'a dönüştürülebileceğini doğrulamak için kullanılır.

Kısıtlamalardaki normal ifadeler

Uyarı

Güvenilmeyen girişi işlemek için kullanırken System.Text.RegularExpressions bir zaman aşımı geçirin. Kötü amaçlı bir kullanıcı Hizmet Reddi saldırısına neden olacak RegularExpressionsgirişler sağlayabilir. ASP.NET Zaman aşımı kullanan RegularExpressions Core framework API'leri.

Normal ifadeler, yol kısıtlaması kullanılarak regex(...) satır içi kısıtlamalar olarak belirtilebilir. Ailedeki yöntemler, kısıtlamaların MapControllerRoute nesne değişmez değerlerini de kabul eder. Bu form kullanılırsa, dize değerleri normal ifadeler olarak yorumlanır.

Aşağıdaki kod satır içi bir regex kısıtlaması kullanır:

app.UseEndpoints(endpoints =>
{
    endpoints.MapGet("{message:regex(^\\d{{3}}-\\d{{2}}-\\d{{4}}$)}",
        context => 
        {
            return context.Response.WriteAsync("inline-constraint match");
        });
 });

Aşağıdaki kod, bir regex kısıtlaması belirtmek için bir nesne değişmez değeri kullanır:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(
        name: "people",
        pattern: "People/{ssn}",
        constraints: new { ssn = "^\\d{3}-\\d{2}-\\d{4}$", },
        defaults: new { controller = "People", action = "List", });
});

ASP.NET Core çerçevesi normal ifade oluşturucuya ekler RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant . Bu üyelerin açıklaması için bkz RegexOptions .

Normal ifadeler, yönlendirme ve C# dili tarafından kullanılanlara benzer sınırlayıcılar ve belirteçler kullanır. Normal ifade belirteçlerinin kaçılması gerekir. Normal ifadeyi ^\d{3}-\d{2}-\d{4}$ satır içi kısıtlamada kullanmak için aşağıdakilerden birini kullanın:

Yönlendirme parametresi sınırlayıcı karakterlerini {, , [}, , ]kaçış olarak kullanmak için ifadedeki karakterleri (örneğin, {{, }}, , [[]]) iki katına çıkarır. Aşağıdaki tabloda normal bir ifade ve kaçış sürümü gösterilmektedir:

Regular expression Kaçış normal ifadesi
^\d{3}-\d{2}-\d{4}$ ^\\d{{3}}-\\d{{2}}-\\d{{4}}$
^[a-z]{2}$ ^[[a-z]]{{2}}$

Yönlendirmede kullanılan normal ifadeler genellikle karakterle ^ başlar ve dizenin başlangıç konumuyla eşleşer. İfadeler genellikle karakterle biter ve dizenin sonuyla $ eşleşer. ^ ve $ karakterleri normal ifadenin yol parametresi değerinin tamamıyla eşleşmesini sağlar. ^ ve $ karakterleri olmadan, normal ifade dizedeki alt dizelerle eşleşir ve bu genellikle istenmeyen bir durumdur. Aşağıdaki tabloda örnekler ve bunların neden eşleştikleri veya eşleşmedikleri açıklanmaktadır:

Expression String Eşleştir Yorum
[a-z]{2} merhaba Yes Alt dize eşleşmeleri
[a-z]{2} 123abc456 Yes Alt dize eşleşmeleri
[a-z]{2} Mz Yes İfadeyle eşleşir
[a-z]{2} MZ Yes Büyük/küçük harfe duyarlı değil
^[a-z]{2}$ merhaba Hayır Bkz ^ . ve $ üzeri
^[a-z]{2}$ 123abc456 Hayır Bkz ^ . ve $ üzeri

Normal ifade söz dizimi hakkında daha fazla bilgi için bkz . .NET Framework Normal İfadeleri.

Bir parametreyi bilinen bir olası değer kümesiyle sınırlamak için normal bir ifade kullanın. Örneğin, {action:regex(^(list|get|create)$)} yalnızca yol değeri listile action , getveya createile eşleşir. Kısıtlamalar sözlüğüne geçirilirse dize ^(list|get|create)$ eşdeğerdir. Bilinen kısıtlamalardan biriyle eşleşmeyen kısıtlama sözlüğünde geçirilen kısıtlamalar da normal ifadeler olarak kabul edilir. Bilinen kısıtlamalardan biriyle eşleşmeyen bir şablon içinde geçirilen kısıtlamalar normal ifadeler olarak kabul edilmemektedir.

Özel yol kısıtlamaları

Özel yol kısıtlamaları, arabirimi uygulanarak IRouteConstraint oluşturulabilir. Arabirimi, IRouteConstraint kısıtlamanın karşılanması durumunda döndüren ve false aksi halde döndüren true öğesini içerirMatch.

Özel yol kısıtlamalarına nadiren ihtiyaç duyulduğu görülür. Özel yol kısıtlaması uygulamadan önce model bağlama gibi alternatifleri göz önünde bulundurun.

ASP.NET Core Constraints klasörü, kısıtlama oluşturmaya yönelik iyi örnekler sağlar. Örneğin, GuidRouteConstraint.

Özel IRouteConstraintbir kullanmak için, yol kısıtlama türünün hizmet kapsayıcısında uygulamanınkilere ConstraintMap kaydedilmesi gerekir. A ConstraintMap , yönlendirme kısıtlama anahtarlarını bu kısıtlamaları doğrulayan uygulamalarla IRouteConstraint eşleyen bir sözlüktür. Bir uygulamanınkilerConstraintMap, hizmetlerin bir parçası olarak güncelleştirilebilirStartup.ConfigureServices. AddRouting çağrısı veya ile services.Configure<RouteOptions>doğrudan yapılandırarakRouteOptions. Örneğin:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    services.AddRouting(options =>
    {
        options.ConstraintMap.Add("customName", typeof(MyCustomConstraint));
    });
}

Yukarıdaki kısıtlama aşağıdaki kodda uygulanır:

[Route("api/[controller]")]
[ApiController]
public class TestController : ControllerBase
{
    // GET /api/test/3
    [HttpGet("{id:customName}")]
    public IActionResult Get(string id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }

    // GET /api/test/my/3
    [HttpGet("my/{id:customName}")]
    public IActionResult Get(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

MyDisplayRouteInfo, Rick.Docs.Samples.RouteInfo NuGet paketi tarafından sağlanır ve yol bilgilerini görüntüler.

uygulaması MyCustomConstraint bir yol parametresine uygulanmasını engeller 0 :

class MyCustomConstraint : IRouteConstraint
{
    private Regex _regex;

    public MyCustomConstraint()
    {
        _regex = new Regex(@"^[1-9]*$",
                            RegexOptions.CultureInvariant | RegexOptions.IgnoreCase,
                            TimeSpan.FromMilliseconds(100));
    }
    public bool Match(HttpContext httpContext, IRouter route, string routeKey,
                      RouteValueDictionary values, RouteDirection routeDirection)
    {
        if (values.TryGetValue(routeKey, out object value))
        {
            var parameterValueString = Convert.ToString(value,
                                                        CultureInfo.InvariantCulture);
            if (parameterValueString == null)
            {
                return false;
            }

            return _regex.IsMatch(parameterValueString);
        }

        return false;
    }
}

Uyarı

Güvenilmeyen girişi işlemek için kullanırken System.Text.RegularExpressions bir zaman aşımı geçirin. Kötü amaçlı bir kullanıcı Hizmet Reddi saldırısına neden olacak RegularExpressionsgirişler sağlayabilir. ASP.NET Zaman aşımı kullanan RegularExpressions Core framework API'leri.

Yukarıdaki kod:

  • Yolun segmentinde {id} engeller0.
  • Özel kısıtlama uygulamanın temel bir örneğini sağlamak için gösterilir. Üretim uygulamasında kullanılmamalıdır.

Aşağıdaki kod, içeren bir kodun işlenmesini önlemeye yönelik daha iyi bir id0 yaklaşımdır:

[HttpGet("{id}")]
public IActionResult Get(string id)
{
    if (id.Contains('0'))
    {
        return StatusCode(StatusCodes.Status406NotAcceptable);
    }

    return ControllerContext.MyDisplayRouteInfo(id);
}

Yukarıdaki kod, yaklaşıma göre aşağıdaki avantajlara MyCustomConstraint sahiptir:

  • Özel bir kısıtlama gerektirmez.
  • Yol parametresi içerdiğinde 0daha açıklayıcı bir hata döndürür.

Parametre transformatörü başvurusu

Parametre transformatörleri:

Örneğin, ile Url.Action(new { article = "MyTestArticle" }) yol deseninde blog\{article:slugify} özel slugify bir parametre transformatörü oluştururblog\my-test-article.

Aşağıdaki IOutboundParameterTransformer uygulamayı göz önünde bulundurun:

public class SlugifyParameterTransformer : IOutboundParameterTransformer
{
    public string TransformOutbound(object value)
    {
        if (value == null) { return null; }

        return Regex.Replace(value.ToString(), 
                             "([a-z])([A-Z])",
                             "$1-$2",
                             RegexOptions.CultureInvariant,
                             TimeSpan.FromMilliseconds(100)).ToLowerInvariant();
    }
}

Rota deseninde bir parametre transformatörü kullanmak için içinde kullanarak ConstraintMapStartup.ConfigureServicesyapılandırın:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();

    services.AddRouting(options =>
    {
        options.ConstraintMap["slugify"] = typeof(SlugifyParameterTransformer);
    });
}

ASP.NET Core çerçevesi, bir uç noktanın çözümlendiği URI'yi dönüştürmek için parametre dönüştürücülerini kullanır. Örneğin, parametre transformatörleri , area, controlleractionve pageile eşleştirmek için kullanılan yol değerlerini dönüştürür.

routes.MapControllerRoute(
    name: "default",
    template: "{controller:slugify=Home}/{action:slugify=Index}/{id?}");

Önceki yol şablonuyla, eylem SubscriptionManagementController.GetAll URI /subscription-management/get-allile eşleştirilir. Parametre transformatörü, bağlantı oluşturmak için kullanılan yol değerlerini değiştirmez. Örneğin, Url.Action("GetAll", "SubscriptionManagement") çıkışları /subscription-management/get-all.

ASP.NET Core, oluşturulan yollar ile parametre dönüştürücülerini kullanmaya yönelik API kuralları sağlar:

URL oluşturma başvurusu

Bu bölüm, URL oluşturma tarafından uygulanan algoritma için bir başvuru içerir. Uygulamada, URL oluşturmanın en karmaşık örneklerinde denetleyiciler veya Razor Sayfalar kullanılır. Ek bilgi için bkz . denetleyicilerde yönlendirme.

URL oluşturma işlemi LinkGenerator.GetPathByAddress çağrısı veya benzer bir yöntemle başlar. yöntemi bir adres, yol değerleri kümesi ve isteğe bağlı olarak geçerli HttpContextistek hakkında bilgi ile sağlanır.

İlk adım, adresi kullanarak adresin türüyle eşleşen bir aday uç nokta IEndpointAddressScheme<TAddress> kümesini çözümlemektir.

Adaylar kümesi adres düzeni tarafından bulunduktan sonra, URL oluşturma işlemi başarılı olana kadar uç noktalar yinelemeli olarak sıralanır ve işlenir. URL oluşturma belirsizlikleri denetlemez, döndürülen ilk sonuç nihai sonuç olur.

Günlüğe kaydetme ile URL oluşturma sorunlarını giderme

URL oluşturma sorunlarını gidermenin ilk adımı, günlük düzeyini Microsoft.AspNetCore.Routing olarak TRACEayarlamaktır. LinkGenerator sorunları gidermek için yararlı olabilecek işlemesiyle ilgili birçok ayrıntıyı günlüğe kaydeder.

URL oluşturmayla ilgili ayrıntılar için bkz . URL oluşturma başvurusu .

Adresler

Adresler, bir çağrıyı bağlantı oluşturucusuna bir dizi aday uç noktaya bağlamak için kullanılan URL oluşturma kavramıdır.

Adresler, varsayılan olarak iki uygulamayla birlikte gelen genişletilebilir bir kavramdır:

  • Adres olarak uç nokta adını (string) kullanma:
    • MVC'nin yol adına benzer işlevler sağlar.
    • IEndpointNameMetadata Meta veri türünü kullanır.
    • Sağlanan dizeyi tüm kayıtlı uç noktaların meta verilerine karşı çözümler.
    • Birden çok uç nokta aynı adı kullanıyorsa başlangıçta bir özel durum oluşturur.
    • Denetleyiciler ve Razor Sayfalar dışında genel amaçlı kullanım için önerilir.
  • Adres olarak yol değerlerini (RouteValuesAddress) kullanma:
    • Denetleyiciler ve Razor Sayfalar eski URL oluşturma için benzer işlevler sağlar.
    • Genişletmek ve hata ayıklamak çok karmaşık.
    • , Etiket Yardımcıları, HTML Yardımcıları, Eylem Sonuçları vb. tarafından IUrlHelperkullanılan uygulamayı sağlar.

Adres düzeninin rolü, adres ve eşleşen uç noktalar arasındaki ilişkilendirmeyi rastgele ölçütlerle yapmaktır:

  • Uç nokta adı düzeni temel bir sözlük araması gerçekleştirir.
  • Yol değerleri şeması, küme algoritmasının karmaşık en iyi alt kümesine sahiptir.

Ortam değerleri ve açık değerler

Geçerli istekten yönlendirme, geçerli isteğin HttpContext.Request.RouteValuesyol değerlerine erişir. Geçerli istekle ilişkili değerler ortam değerleri olarak adlandırılır. Netlik sağlamak amacıyla belgeler, yöntemlere açık değerler olarak geçirilen yol değerlerini ifade eder.

Aşağıdaki örnekte ortam değerleri ve açık değerler gösterilmektedir. Geçerli istekten ortam değerleri ve açık değerler sağlar: : { id = 17, }

public class WidgetController : Controller
{
    private readonly LinkGenerator _linkGenerator;

    public WidgetController(LinkGenerator linkGenerator)
    {
        _linkGenerator = linkGenerator;
    }

    public IActionResult Index()
    {
        var url = _linkGenerator.GetPathByAction(HttpContext,
                                                 null, null,
                                                 new { id = 17, });
        return Content(url);
    }

Yukarıdaki kod:

Aşağıdaki kod ortam değerleri ve açık değerler sağlamaz: : { controller = "Home", action = "Subscribe", id = 17, }

public IActionResult Index2()
{
    var url = _linkGenerator.GetPathByAction("Subscribe", "Home",
                                             new { id = 17, });
    return Content(url);
}

Yukarıdaki yöntem döndürür /Home/Subscribe/17

içindeki aşağıdaki kod WidgetController döndürür /Widget/Subscribe/17:

var url = _linkGenerator.GetPathByAction("Subscribe", null,
                                         new { id = 17, });

Aşağıdaki kod, denetleyiciyi geçerli istekteki ortam değerlerinden ve açık değerlerden sağlar: : { action = "Edit", id = 17, }

public class GadgetController : Controller
{
    public IActionResult Index()
    {
        var url = Url.Action("Edit", new { id = 17, });
        return Content(url);
    }

Önceki kodda:

  • /Gadget/Edit/17 döndürülür.
  • Url alır IUrlHelper.
  • Action bir eylem yöntemi için mutlak yola sahip bir URL oluşturur. URL belirtilen action adı ve route değerleri içerir.

Aşağıdaki kod, geçerli istekten gelen ortam değerlerini ve açık değerleri sağlar: : { page = "./Edit, id = 17, }

public class IndexModel : PageModel
{
    public void OnGet()
    {
        var url = Url.Page("./Edit", new { id = 17, });
        ViewData["URL"] = url;
    }
}

Yukarıdaki kod, SayfaYı Düzenle Razor aşağıdaki sayfa yönergesini içerdiğinde olarak ayarlır:url/Edit/17

@page "{id:int}"

Düzenle sayfası yol şablonunu içermiyorsa "{id:int}" , url şeklindedir /Edit?id=17.

MVC'nin IUrlHelper davranışı, burada açıklanan kurallara ek olarak bir karmaşıklık katmanı ekler:

  • IUrlHelper her zaman geçerli istekten yol değerlerini ortam değerleri olarak sağlar.
  • IUrlHelper.Action , geliştirici tarafından geçersiz kılınmadığı sürece her zaman geçerli action ve controller yol değerlerini açık değerler olarak kopyalar.
  • IUrlHelper.Page geçersiz kılınmadığı sürece geçerli page yol değerini her zaman açık bir değer olarak kopyalar.
  • IUrlHelper.Page geçersiz kılınmadığı sürece geçerli handler yol değerini null her zaman ile açık değerler olarak geçersiz kılar.

MVC kendi kurallarına uymadığından kullanıcılar genellikle ortam değerlerinin davranışsal ayrıntılarına şaşırır. Geçmiş ve uyumluluk nedenleriyle, , controller, pageve handler gibi actionbelirli yol değerlerinin kendi özel durum davranışları vardır.

tarafından LinkGenerator.GetPathByAction sağlanan eşdeğer işlevsellik ve LinkGenerator.GetPathByPage uyumluluk için bu anomalilerini IUrlHelper yineler.

URL oluşturma işlemi

Aday uç nokta kümesi bulunduktan sonra URL oluşturma algoritması:

  • Uç noktaları yinelemeli olarak işler.
  • İlk başarılı sonucu döndürür.

Bu işlemin ilk adımı, yol değeri geçersizleştirmesi olarak adlandırılır. Yol değeri geçersiz kılınması, yönlendirmenin ortam değerlerinden hangi yol değerlerinin kullanılacağına ve hangilerinin yoksayılacağına karar verdiği işlemdir. Her ortam değeri kabul edilir ve açık değerlerle birleştirilir veya yoksayılır.

Ortam değerlerinin rolü hakkında düşünmenin en iyi yolu, bazı yaygın durumlarda uygulama geliştiricilerini yazmaya kaydetmeyi denemeleridir. Geleneksel olarak ortam değerlerinin yararlı olduğu senaryolar MVC ile ilgilidir:

  • Aynı denetleyicideki başka bir eyleme bağlanırken, denetleyici adının belirtilmesi gerekmez.
  • Aynı alandaki başka bir denetleyiciye bağlanırken alan adının belirtilmesi gerekmez.
  • Aynı eylem yöntemine bağlanırken yol değerlerinin belirtilmesi gerekmez.
  • Uygulamanın başka bir bölümüne bağlanırken, uygulamanın bu bölümünde hiçbir anlamı olmayan rota değerlerini taşımak istemezsiniz.

LinkGenerator veya IUrlHelper döndüren null çağrıların nedeni genellikle yol değeri geçersizleştirmesini anlamamaktır. Bunun sorunu çözüp çözmediğini görmek için yol değerlerinden daha fazlasını açıkça belirterek yol değeri geçersizliği sorunlarını giderin.

Yol değeri geçersiz kılınması, uygulamanın URL düzeninin hiyerarşik olduğu varsayımıyla çalışır ve soldan sağa bir hiyerarşi oluşturulur. Bunun pratikte nasıl çalıştığına ilişkin sezgisel bir fikir edinmek için temel denetleyici rota şablonunu {controller}/{action}/{id?} göz önünde bulundurun. Bir değerde yapılan değişiklik, sağda görünen tüm yol değerlerini geçersiz kıldığını gösterir. Bu, hiyerarşi hakkındaki varsayımı yansıtır. Uygulamanın için idbir ortam değeri varsa ve işlem için controllerfarklı bir değer belirtir:

  • idöğesinin solunda {id?}olduğundan {controller} yeniden kullanılamaz.

Bu ilkeyi gösteren bazı örnekler:

  • Açık değerler için idbir değer içeriyorsa, için id ortam değeri yoksayılır. ve action ortam controller değerleri kullanılabilir.
  • Açık değerler için actionbir değer içeriyorsa, için action ortam değerleri yoksayılır. için controller ortam değerleri kullanılabilir. için action açık değer için ortam değerinden actionid farklıysa, değeri kullanılmaz. için action açık değer için ortam değeri actionid ile aynıysa, değeri kullanılabilir.
  • Açık değerler için controllerbir değer içeriyorsa, için controller ortam değerleri yoksayılır. için controller açık değer için ortam değerinden controlleraction farklıysa ve id değerleri kullanılmaz. için controller açık değer, için ortam değeriyle controlleraction aynıysa ve id değerleri kullanılabilir.

Bu işlem, öznitelik yollarının ve ayrılmış geleneksel yolların varlığıyla daha karmaşıktır. Yol parametrelerini kullanarak hiyerarşi belirtme gibi {controller}/{action}/{id?} denetleyici geleneksel yolları. Denetleyicilere ve Sayfalara ayrılmış geleneksel yollar ve Razor öznitelik yolları için:

  • Yol değerleri hiyerarşisi vardır.
  • Bunlar şablonda görünmez.

Bu durumlarda, URL oluşturma gerekli değerler kavramını tanımlar. Denetleyiciler ve Razor Sayfalar tarafından oluşturulan uç noktaların, yol değeri geçersiz kılınmasına izin veren gerekli değerler belirtilmiştir.

Yol değeri geçersizleştirme algoritması ayrıntılı olarak:

  • Gerekli değer adları yol parametreleriyle birleştirilir ve ardından soldan sağa işlenir.
  • Her parametre için ortam değeri ve açık değer karşılaştırılır:
    • Ortam değeri ve açık değer aynıysa işlem devam eder.
    • Ortam değeri mevcutsa ve açık değer yoksa, URL oluşturulurken ortam değeri kullanılır.
    • Ortam değeri yoksa ve açık değer ise, ortam değerini ve sonraki tüm ortam değerlerini reddedin.
    • Ortam değeri ve açık değer varsa ve iki değer farklıysa, ortam değerini ve sonraki tüm ortam değerlerini reddedin.

Bu noktada, URL oluşturma işlemi yol kısıtlamalarını değerlendirmeye hazırdır. Kabul edilen değerler kümesi, kısıtlamalara sağlanan parametre varsayılan değerleriyle birleştirilir. Kısıtlamaların tümü geçerse işlem devam eder.

Ardından, kabul edilen değerler yol şablonunu genişletmek için kullanılabilir. Yol şablonu işlenir:

  • Soldan sağa.
  • Her parametrenin yerine kabul edilen değeri vardır.
  • Aşağıdaki özel durumlarla:
    • Kabul edilen değerlerde bir değer eksikse ve parametrenin varsayılan değeri varsa, varsayılan değer kullanılır.
    • Kabul edilen değerlerde bir değer eksikse ve parametre isteğe bağlıysa işleme devam eder.
    • Eksik isteğe bağlı parametrenin sağındaki herhangi bir yol parametresinin değeri varsa, işlem başarısız olur.
    • Bitişik varsayılan değerli parametreler ve isteğe bağlı parametreler mümkün olduğunca daraltılır.

Yolun bir kesimiyle eşleşmeyen açıkça sağlanan değerler sorgu dizesine eklenir. Aşağıdaki tabloda yol şablonu {controller}/{action}/{id?}kullanılırken elde edilen sonuç gösterilmektedir.

Ortam Değerleri Açık Değerler Sonuç
controller = "Home" action = "About" /Home/About
controller = "Home" controller = "Order", action = "About" /Order/About
denetleyici = "Home", renk = "Kırmızı" action = "About" /Home/About
controller = "Home" action = "About", color = "Red" /Home/About?color=Red

Yol değeri geçersiz kılınmasıyla ilgili sorunlar

ASP.NET Core 3.0 sürümünden itibaren, önceki ASP.NET Core sürümlerinde kullanılan bazı URL oluşturma düzenleri URL oluşturma ile iyi çalışmaz. ASP.NET Core ekibi, gelecek bir sürümde bu gereksinimleri karşılayacak özellikler eklemeyi planlıyor. Şimdilik en iyi çözüm eski yönlendirmeyi kullanmaktır.

Aşağıdaki kod, yönlendirme tarafından desteklenmeyen bir URL oluşturma şeması örneği gösterir.

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute("default", 
                                     "{culture}/{controller=Home}/{action=Index}/{id?}");
    endpoints.MapControllerRoute("blog", "{culture}/{**slug}", 
                                      new { controller = "Blog", action = "ReadPost", });
});

Yukarıdaki kodda culture , yerelleştirme için yol parametresi kullanılır. Parametrenin culture her zaman bir ortam değeri olarak kabul edilmiş olmasını istemeniz gerekir. Ancak, gerekli değerlerin culture çalışma şekli nedeniyle parametre ortam değeri olarak kabul edilmemektedir:

  • Yol şablonunda "default" , culture yol parametresi solundadır controller, bu nedenle olarak değişir controller ve geçersiz kılmaz culture.
  • Yol şablonunda "blog" , culture yol parametresinin, gerekli değerlerde görünen sağında controllerolduğu kabul edilir.

Uç nokta meta verilerini yapılandırma

Aşağıdaki bağlantılar uç nokta meta verilerini yapılandırma hakkında bilgi sağlar:

RequireHost ile yollarda konak eşleştirme

RequireHost belirtilen konağı gerektiren yola bir kısıtlama uygular. RequireHost veya [Host] parametresi şunlar olabilir:

  • Ana bilgisayar: www.domain.com, herhangi bir bağlantı noktasıyla eşleşir www.domain.com .
  • Joker karakterli konak: *.domain.com, , subdomain.domain.comveya www.subdomain.domain.com herhangi bir bağlantı noktasında eşleşirwww.domain.com.
  • Bağlantı noktası: *:5000, 5000 numaralı bağlantı noktasını herhangi bir konakla eşleştirir.
  • Konak ve bağlantı noktası: www.domain.com:5000 veya *.domain.com:5000, konak ve bağlantı noktasıyla eşleşir.

veya [Host]kullanılarak RequireHost birden çok parametre belirtilebilir. Kısıtlama, parametrelerden herhangi biri için geçerli olan konaklarla eşleşir. Örneğin, [Host("domain.com", "*.domain.com")] , www.domain.comve subdomain.domain.comile eşleşirdomain.com.

Aşağıdaki kod, belirtilen konağın yolda gerekli olmasını sağlamak için kullanır RequireHost :

public void Configure(IApplicationBuilder app)
{
    app.UseRouting();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", context => context.Response.WriteAsync("Hi Contoso!"))
            .RequireHost("contoso.com");
        endpoints.MapGet("/", context => context.Response.WriteAsync("AdventureWorks!"))
            .RequireHost("adventure-works.com");
        endpoints.MapHealthChecks("/healthz").RequireHost("*:8080");
    });
}

Aşağıdaki kod, belirtilen konaklardan herhangi birini gerektirmek için denetleyicideki özniteliğini kullanır [Host] :

[Host("contoso.com", "adventure-works.com")]
public class ProductController : Controller
{
    public IActionResult Index()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    [Host("example.com:8080")]
    public IActionResult Privacy()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

[Host] Özniteliği hem denetleyiciye hem de eylem yöntemine uygulandığında:

  • Eylemdeki özniteliği kullanılır.
  • Denetleyici özniteliği yoksayılır.

Yönlendirme için performans kılavuzu

Performansı artırmak için yönlendirmenin çoğu ASP.NET Core 3.0'da güncelleştirildi.

Bir uygulamada performans sorunları olduğunda, yönlendirme genellikle sorun olarak şüphelenilir. Yönlendirmenin nedeni, denetleyiciler ve Razor Sayfalar gibi çerçevelerin günlüğe kaydetme iletilerinde çerçeve içinde harcanan süreyi raporlamasıdır. Denetleyiciler tarafından bildirilen süre ile isteğin toplam süresi arasında önemli bir fark olduğunda:

  • Geliştiriciler, sorunun kaynağı olarak uygulama kodlarını ortadan kaldırır.
  • Bunun nedeninin yönlendirme olduğunu varsaymak yaygın bir durumdur.

Yönlendirme, binlerce uç nokta kullanılarak performans testi yapılır. Tipik bir uygulamanın yalnızca çok büyük olmasıyla bir performans sorunuyla karşılaşma olasılığı düşüktür. Yavaş yönlendirme performansının en yaygın kök nedeni genellikle kötü davranan bir özel ara yazılımdır.

Aşağıdaki kod örneği, gecikme kaynağını daraltmayla ilgili temel bir tekniği gösterir:

public void Configure(IApplicationBuilder app, ILogger<Startup> logger)
{
    app.Use(next => async context =>
    {
        var sw = Stopwatch.StartNew();
        await next(context);
        sw.Stop();

        logger.LogInformation("Time 1: {ElapsedMilliseconds}ms", sw.ElapsedMilliseconds);
    });

    app.UseRouting();

    app.Use(next => async context =>
    {
        var sw = Stopwatch.StartNew();
        await next(context);
        sw.Stop();

        logger.LogInformation("Time 2: {ElapsedMilliseconds}ms", sw.ElapsedMilliseconds);
    });

    app.UseAuthorization();

    app.Use(next => async context =>
    {
        var sw = Stopwatch.StartNew();
        await next(context);
        sw.Stop();

        logger.LogInformation("Time 3: {ElapsedMilliseconds}ms", sw.ElapsedMilliseconds);
    });

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Timing test.");
        });
    });
}

Zaman yönlendirme:

  • Önceki kodda gösterilen zamanlama ara yazılımının bir kopyasıyla her ara yazılımı birbirine ekleyin.
  • Zamanlama verilerini kodla ilişkilendirmek için benzersiz bir tanımlayıcı ekleyin.

Bu, örneğin değerinden daha 10msönemli olduğunda gecikmeyi daraltmak için temel bir yoldur. Raporlardan Time 1 ara yazılım içinde harcanan UseRouting süreyi çıkarmaTime 2.

Aşağıdaki kod, önceki zamanlama koduna daha kompakt bir yaklaşım kullanır:

public sealed class MyStopwatch : IDisposable
{
    ILogger<Startup> _logger;
    string _message;
    Stopwatch _sw;

    public MyStopwatch(ILogger<Startup> logger, string message)
    {
        _logger = logger;
        _message = message;
        _sw = Stopwatch.StartNew();
    }

    private bool disposed = false;


    public void Dispose()
    {
        if (!disposed)
        {
            _logger.LogInformation("{Message }: {ElapsedMilliseconds}ms",
                                    _message, _sw.ElapsedMilliseconds);

            disposed = true;
        }
    }
}
public void Configure(IApplicationBuilder app, ILogger<Startup> logger)
{
    int count = 0;
    app.Use(next => async context =>
    {
        using (new MyStopwatch(logger, $"Time {++count}"))
        {
            await next(context);
        }

    });

    app.UseRouting();

    app.Use(next => async context =>
    {
        using (new MyStopwatch(logger, $"Time {++count}"))
        {
            await next(context);
        }
    });

    app.UseAuthorization();

    app.Use(next => async context =>
    {
        using (new MyStopwatch(logger, $"Time {++count}"))
        {
            await next(context);
        }
    });

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapGet("/", async context =>
        {
            await context.Response.WriteAsync("Timing test.");
        });
    });
}

Potansiyel olarak pahalı yönlendirme özellikleri

Aşağıdaki liste, temel yol şablonlarıyla karşılaştırıldığında nispeten pahalı yönlendirme özellikleri hakkında bazı içgörüler sağlar:

  • Normal ifadeler: Karmaşık olan veya az miktarda girişle uzun süre çalışan normal ifadeler yazmak mümkündür.
  • Karmaşık segmentler ({x}-{y}-{z}):
    • Normal URL yolu kesimini ayrıştırmaktan çok daha pahalıdır.
    • Daha fazla alt dizenin ayrılmasına neden olur.
    • Karmaşık segment mantığı ASP.NET Core 3.0 yönlendirme performansı güncelleştirmesinde güncelleştirilmedi.
  • Zaman uyumlu veri erişimi: Birçok karmaşık uygulamanın yönlendirmesinin bir parçası olarak veritabanı erişimi vardır. ASP.NET Core 2.2 ve önceki yönlendirme, veritabanı erişim yönlendirmesini desteklemek için doğru genişletilebilirlik noktalarını sağlamayabilir. Örneğin, IRouteConstraintve IActionConstraint zaman uyumlu. ve EndpointSelectorContext gibi MatcherPolicy genişletilebilirlik noktaları zaman uyumsuz.

Kitaplık yazarları için rehberlik

Bu bölüm, yönlendirmenin üzerine inşa eden kitaplık yazarları için rehberlik içerir. Bu ayrıntılar, uygulama geliştiricilerinin yönlendirmeyi genişleten kitaplıkları ve çerçeveleri kullanarak iyi bir deneyim elde etmelerini sağlamaya yöneliktir.

Uç noktaları tanımlama

URL eşleştirmesi için yönlendirme kullanan bir çerçeve oluşturmak için, üzerinde UseEndpointsderleyen bir kullanıcı deneyimi tanımlayarak başlayın.

DO , üzerinde derleyin IEndpointRouteBuilder. Bu, kullanıcıların kafa karışıklığı olmadan diğer ASP.NET Core özellikleriyle çerçevenizi oluşturmasına olanak tanır. Her ASP.NET Core şablonu yönlendirme içerir. Yönlendirmenin kullanıcılar için mevcut ve tanıdık olduğunu varsayın.

app.UseEndpoints(endpoints =>
{
    // Your framework
    endpoints.MapMyFramework(...);

    endpoints.MapHealthChecks("/healthz");
});

DO, uygulayan IEndpointConventionBuilderçağrısından korumalı bir MapMyFramework(...) beton türü döndürür. Çoğu çerçeve Map... yöntemi bu deseni izler. Arabirim IEndpointConventionBuilder :

  • Meta verilerin birliğine izin verir.
  • Çeşitli uzantı yöntemleri tarafından hedeflenmiştir.

Kendi türünüzü bildirmeniz, oluşturucuya kendi çerçeveye özgü işlevselliğinizi eklemenize olanak tanır. Çerçeve tarafından bildirilen bir oluşturucuyu sarmalayıp çağrıları ona iletmenin bir sakıncası yok.

app.UseEndpoints(endpoints =>
{
    // Your framework
    endpoints.MapMyFramework(...).RequireAuthorization()
                                 .WithMyFrameworkFeature(awesome: true);

    endpoints.MapHealthChecks("/healthz");
});

Kendi EndpointDataSourceyazınızı yazmayı göz önünde bulundurun. EndpointDataSource , bir uç nokta koleksiyonunu bildirmeye ve güncelleştirmeye yönelik alt düzey temel öğedir. EndpointDataSource , denetleyiciler ve Razor Sayfalar tarafından kullanılan güçlü bir API'dir.

Yönlendirme testlerinin temel bir güncelleştirilmemiş veri kaynağı örneği vardır.

Varsayılan olarak bir EndpointDataSource kaydetmeyi DENEMEYİN. Kullanıcıların çerçevenizi ' UseEndpointsye kaydetmesini gerektirin. Yönlendirmenin felsefesi, varsayılan olarak hiçbir şeyin dahil olmadığını ve uç noktaların kaydedildiği yerdir UseEndpoints .

Yönlendirmeyle tümleşik ara yazılım oluşturma

Meta veri türlerini arabirim olarak tanımlamayı GÖZ ÖNÜNDE BULUNDURUN .

DO , meta veri türlerini sınıflarda ve yöntemlerde öznitelik olarak kullanmayı mümkün hale getirir.

public interface ICoolMetadata
{
    bool IsCool { get; }
}

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CoolMetadataAttribute : Attribute, ICoolMetadata
{
    public bool IsCool => true;
}

Denetleyiciler ve Razor Sayfalar gibi çerçeveler, meta veri özniteliklerinin türlere ve yöntemlere uygulanmasını destekler. Meta veri türlerini bildirirseniz:

  • Bunları öznitelik olarak erişilebilir hale getirin.
  • Kullanıcıların çoğu öznitelikleri uygulama konusunda bilgi sahibidir.

Bir meta veri türünün arabirim olarak bildirilmesi başka bir esneklik katmanı ekler:

  • Arabirimler birleştirilebilir.
  • Geliştiriciler, birden çok ilkeyi birleştiren kendi türlerini bildirebilir.

AŞAĞıDAKI örnekte gösterildiği gibi meta verileri geçersiz kılmayı mümkün kılamaz:

public interface ICoolMetadata
{
    bool IsCool { get; }
}

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class CoolMetadataAttribute : Attribute, ICoolMetadata
{
    public bool IsCool => true;
}

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class SuppressCoolMetadataAttribute : Attribute, ICoolMetadata
{
    public bool IsCool => false;
}

[CoolMetadata]
public class MyController : Controller
{
    public void MyCool() { }

    [SuppressCoolMetadata]
    public void Uncool() { }
}

Bu yönergeleri izlemenin en iyi yolu, işaretçi meta verilerini tanımlamaktan kaçınmaktır:

  • Yalnızca meta veri türünün varlığına bakmayın.
  • Meta verilerde bir özellik tanımlayın ve özelliğini denetleyin.

Meta veri koleksiyonu sıralanır ve önceliğe göre geçersiz kılmayı destekler. Denetleyiciler söz konusu olduğunda, eylem yöntemindeki meta veriler en belirgindir.

DO , ara yazılımları yönlendirme ile ve yönlendirme olmadan kullanışlı hale getirir.

app.UseRouting();

app.UseAuthorization(new AuthorizationPolicy() { ... });

app.UseEndpoints(endpoints =>
{
    // Your framework
    endpoints.MapMyFramework(...).RequireAuthorization();
});

Bu kılavuza örnek olarak ara yazılımı göz önünde bulundurun UseAuthorization . Yetkilendirme ara yazılımı bir geri dönüş ilkesi geçirmenizi sağlar. Geri dönüş ilkesi belirtilirse her ikisi için de geçerlidir:

  • Belirtilen ilke olmayan uç noktalar.
  • Uç noktayla eşleşmeyen istekler.

Bu, yetkilendirme ara yazılımını yönlendirme bağlamı dışında kullanışlı hale getirir. Yetkilendirme ara yazılımı geleneksel ara yazılım programlama için kullanılabilir.

Tanılama hatalarını ayıklama

Ayrıntılı yönlendirme tanılama çıktısı için olarak DebugayarlayınLogging:LogLevel:Microsoft. Geliştirme ortamında, içinde günlük düzeyini appsettings.Development.jsonayarlayın:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Debug",
      "Microsoft.Hosting.Lifetime": "Information"
    }
  }
}