ASP.NET Core'de denetleyici eylemlerine 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.

ASP.NET Core denetleyicileri, gelen isteklerin URL'lerini eşleştirmek ve bunları eylemlerle eşlemek için Yönlendirme ara yazılımını kullanır. Yol şablonları:

  • başlangıçta veya özniteliklerde tanımlanır Program.cs .
  • URL yollarının eylemlerle nasıl eşlendiğini açıklayın.
  • Bağlantılar için URL'ler oluşturmak için kullanılır. Oluşturulan bağlantılar genellikle yanıt olarak döndürülür.

Eylemler geleneksel olarak yönlendirilir veya öznitelik tarafından yönlendirilir. Denetleyiciye veya eyleme bir yol yerleştirmek, denetleyicinin öznitelik yönlendirmeli olmasını sağlar. Daha fazla bilgi için bkz . Karma yönlendirme .

Bu belge:

  • MVC ile yönlendirme arasındaki etkileşimleri açıklar:
  • Uç nokta yönlendirme adlı varsayılan yönlendirme sistemine başvurur. Denetleyiciler uyumluluk amacıyla yönlendirmenin önceki sürümüyle birlikte kullanılabilir. Yönergeler için 2.2-3.0 geçiş kılavuzuna bakın.

Geleneksel rotayı ayarlama

ASP.NET Core MVC şablonu, aşağıdakine benzer geleneksel yönlendirme kodu oluşturur:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

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

app.Run();

MapControllerRoute tek bir yol oluşturmak için kullanılır. Tek yol route olarak adlandırılır default . Denetleyicileri ve görünümleri olan çoğu uygulama, yola benzer default bir yol şablonu kullanır. RESTAPI'ler öznitelik yönlendirme kullanmalıdır.

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

Yol şablonu "{controller=Home}/{action=Index}/{id?}":

  • Gibi bir URL yoluyla eşleşir /Products/Details/5

  • Yolu belirteçleştirerek yol değerlerini ayıklar { controller = Products, action = Details, id = 5 } . Uygulama adlı ProductsController bir denetleyiciye ve bir eyleme sahipse, yol değerlerinin ayıkılması eşleşmeye Details neden olur:

    public class ProductsController : Controller
    {
        public IActionResult Details(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.

  • /Products/Details/5model parametresini 5olarak ayarlamak id için değerini id = 5 bağlar. Diğer ayrıntılar için bkz . Model Bağlama .

  • {controller=Home}varsayılan controllerolarak tanımlarHome.

  • {action=Index}varsayılan actionolarak tanımlarIndex.

  • içindeki ?{id?} karakteri isteğe bağlı olarak tanımlar id .

    • Varsayılan ve isteğe bağlı yol parametrelerinin eşleşme için URL yolunda mevcut olması gerekmez. Yol şablonu söz diziminin ayrıntılı açıklaması için bkz . Yol Şablonu Başvurusu .
  • URL yolu ile eşleşir /.

  • Yol değerlerini üretir { controller = Home, action = Index }.

için değerler controller ve action varsayılan değerleri kullanır. id URL yolunda karşılık gelen bir kesim olmadığından bir değer üretmez. / yalnızca bir HomeController ve Index eylemi varsa eşleşir:

public class HomeController : Controller
{
    public IActionResult Index() { ... }
}

Yukarıdaki denetleyici tanımı ve yol şablonu kullanılarak, HomeController.Index eylem aşağıdaki URL yolları için çalıştırılır:

  • /Home/Index/17
  • /Home/Index
  • /Home
  • /

URL yolu / , rota şablonu varsayılan Home denetleyicilerini ve Index eylemini kullanır. URL yolu /Home , rota şablonu varsayılan Index eylemini kullanır.

Kolaylık yöntemi MapDefaultControllerRoute:

app.MapDefaultControllerRoute();

Değiştirir:

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

Önemli

Yönlendirme, ve UseEndpoints ara yazılımı kullanılarak UseRouting yapılandırılır. Denetleyicileri kullanmak için:

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. Daha fazla bilgi için, bkz. ASP.NET Core’da Yönlendirme.

Geleneksel yönlendirme

Geleneksel yönlendirme, denetleyiciler ve görünümlerle kullanılır. Yol default :

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

Yukarıdaki örnek, geleneksel bir rota örneğidir. URL yolları için bir kural oluşturduğundan buna geleneksel yönlendirme adı verilir:

  • İlk yol kesimi olan {controller=Home}, denetleyici adıyla eşler.
  • İkinci segment olan {action=Index}, eylem adıyla eşler.
  • Üçüncü segment, {id?} isteğe bağlı idbir için kullanılır. in ?{id?} bunu isteğe bağlı hale getirir. id bir model varlığıyla eşlemek için kullanılır.

Bu default yolu kullanarak URL yolu:

  • /Products/List eylemiyle eşler ProductsController.List .
  • /Blog/Article/17BlogController.Article eşler ve genellikle model parametresini id 17'ye bağlar.

Bu eşleme:

  • Yalnızca denetleyiciyi ve eylem adlarını temel alır.
  • Ad alanları, kaynak dosya konumları veya yöntem parametreleri temel alınamaz.

Geleneksel yönlendirmeyi varsayılan yol ile kullanmak, her eylem için yeni bir URL düzeni oluşturmak zorunda kalmadan uygulamanın oluşturulmasına olanak tanır. CRUD stili eylemleri olan bir uygulama için, denetleyiciler arasında URL'ler için tutarlılık sağlar:

  • Kodu basitleştirmeye yardımcı olur.
  • Kullanıcı arabirimini daha öngörülebilir hale getirir.

Uyarı

id Yukarıdaki koddaki, yol şablonu tarafından isteğe bağlı olarak tanımlanır. Eylemler, URL'nin parçası olarak sağlanan isteğe bağlı kimlik olmadan yürütülebilir. Genellikle URL'den atlandığında id :

  • id , model bağlamasına 0 göre olarak ayarlanır.
  • veritabanında eşleşen id == 0varlık bulunamadı.

Öznitelik yönlendirmesi , bazı eylemler için gerekli kimlikleri yapmak için ayrıntılı denetim sağlar ve diğerleri için gerekli değildir. Kural gereği, belgelerde doğru kullanımda görünme olasılıkları gibi id isteğe bağlı parametreler bulunur.

Çoğu uygulama, URL'lerin okunabilir ve anlamlı olması için temel ve açıklayıcı bir yönlendirme düzeni seçmelidir. Varsayılan geleneksel yol {controller=Home}/{action=Index}/{id?}:

  • Temel ve açıklayıcı bir yönlendirme düzenini destekler.
  • Kullanıcı arabirimi tabanlı uygulamalar için yararlı bir başlangıç noktasıdır.
  • Birçok web kullanıcı arabirimi uygulaması için gereken tek yol şablonudur. Daha büyük web kullanıcı arabirimi uygulamaları için, Alanlar'ı kullanan başka bir yol genellikle gereken tek yoldur.

MapControllerRoute ve MapAreaRoute :

  • Çağrıldıkları sırayla uç noktalarına otomatik olarak bir sipariş değeri atayın.

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

  • Rota kavramı yoktur.
  • Genişletilebilirlik yürütme için sipariş garantisi sağlamaz, tüm uç noktalar aynı anda işlenir.

gibi Routeyerleşik yönlendirme uygulamalarının istekleri nasıl eşleştirdiğini görmek için Günlüğü etkinleştirin.

Öznitelik yönlendirmesi bu belgenin ilerleyen bölümlerinde açıklanmıştır.

Birden çok geleneksel rota

ve MapAreaControllerRouteöğesine daha fazla çağrı MapControllerRoute eklenerek birden çok geleneksel yol yapılandırılabilir. Bunu yapmak birden çok kural tanımlamaya veya belirli bir eyleme ayrılmış geleneksel yollar eklemeye olanak tanır, örneğin:

app.MapControllerRoute(name: "blog",
                pattern: "blog/{*article}",
                defaults: new { controller = "Blog", action = "Article" });
app.MapControllerRoute(name: "default",
               pattern: "{controller=Home}/{action=Index}/{id?}");

blog Yukarıdaki koddaki yol, ayrılmış bir geleneksel yoldur. Buna ayrılmış geleneksel yol denir çünkü:

Çünkü controller ve action rota şablonunda "blog/{*article}" parametre olarak görünmez:

  • Yalnızca varsayılan değerlerine { controller = "Blog", action = "Article" }sahip olabilirler.
  • Bu yol her zaman eylemiyle BlogController.Articleeşler.

/Blog, /Blog/Articleve /Blog/{any-string} blog yoluyla eşleşen tek URL yollarıdır.

Yukarıdaki örnek:

Uyarı

ASP.NET Core'da yönlendirme şunları yapmaz:

  • Yol olarak adlandırılan bir kavram tanımlayın. UseRouting ara yazılım işlem hattına yol eşleştirmesi ekler. Ara UseRouting yazılım, uygulamada tanımlanan uç nokta kümesine bakar ve isteğe göre en iyi uç nokta eşleşmesini seçer.
  • veya IActionConstraintgibi IRouteConstraint genişletilebilirlik yürütme sırası hakkında garantiler sağlar.

Yönlendirme hakkında başvuru malzemesi için bkz. Yönlendirme.

Geleneksel yönlendirme sırası

Geleneksel yönlendirme yalnızca uygulama tarafından tanımlanan eylem ve denetleyici birleşimiyle eşleşir. Bu, geleneksel yolların çakıştığı durumları basitleştirmeye yöneliktir. kullanarak MapControllerRouteMapDefaultControllerRouteyollar ekleyin ve MapAreaControllerRoute çağrıldıkları sırayla uç noktalarına otomatik olarak bir sipariş değeri atayın. Daha önce görünen bir yoldan gelen eşleşmelerin önceliği daha yüksektir. Geleneksel yönlendirme, siparişe bağlıdır. Genel olarak, alanları olan yollar, alanı olmayan rotalara göre daha belirgin olduğundan daha erken yerleştirilmelidir. Gibi {*article} tümünü yakala rota parametrelerine sahip ayrılmış geleneksel yollar, bir yolu çok doyumsuz hale getirir; başka bir deyişle, diğer yollar tarafından eşleşmesini istediğiniz URL'lerle eşleşir. Doyumsuz eşleşmeleri önlemek için doyumsuz yolları daha sonra yol tablosuna yerleştirin.

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.

Belirsiz eylemleri çözme

yönlendirme aracılığıyla iki uç nokta eşleştiğinde, yönlendirme aşağıdakilerden birini yapmalıdır:

  • En iyi adayı seçin.
  • Özel durum oluşturma.

Örneğin:

public class Products33Controller : Controller
{
    public IActionResult Edit(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }

    [HttpPost]
    public IActionResult Edit(int id, Product product)
    {
        return ControllerContext.MyDisplayRouteInfo(id, product.name);
    }
}

Yukarıdaki denetleyici, eşleşen iki eylemi tanımlar:

  • URL yolu /Products33/Edit/17
  • Yönlendirme verileri { controller = Products33, action = Edit, id = 17 }.

Bu, MVC denetleyicileri için tipik bir desendir:

  • Edit(int) bir ürünü düzenlemek için bir form görüntüler.
  • Edit(int, Product) deftere nakledilmiş formu işler.

Doğru yolu çözümlemek için:

  • Edit(int, Product) , istek bir HTTP POSTolduğunda seçilir.
  • Edit(int), HTTP fiili başka bir şey olduğunda seçilir. Edit(int) genellikle aracılığıyla çağrılır GET.

HttpPostAttribute, , [HttpPost]isteğin HTTP yöntemine göre seçebilmesi için yönlendirmeye sağlanır. , HttpPostAttribute değerinden Edit(int)daha iyi bir eşleşme sağlarEdit(int, Product).

gibi HttpPostAttributeözniteliklerin rolünü anlamak önemlidir. Diğer HTTP fiilleri için benzer öznitelikler tanımlanır. Geleneksel yönlendirmede, eylemlerin bir gösteri formunun parçası olan form gönderme formu iş akışının parçası olduğunda aynı eylem adını kullanması yaygındır. Örneğin, bkz . İki Düzenleme eylemi yöntemini inceleme.

Yönlendirme en iyi adayı seçemiyorsa, birden çok eşleşen uç nokta listeleyerek bir AmbiguousMatchException oluşturulur.

Geleneksel yol adları

Dizeler "blog" ve "default" aşağıdaki örneklerde geleneksel yol adları verilmiştir:

app.MapControllerRoute(name: "blog",
                pattern: "blog/{*article}",
                defaults: new { controller = "Blog", action = "Article" });
app.MapControllerRoute(name: "default",
               pattern: "{controller=Home}/{action=Index}/{id?}");

Yol adları, yola mantıksal bir ad verir. Adlandırılmış yol, URL oluşturma için kullanılabilir. Adlandırılmış yol kullanmak, yolların sıralanması URL oluşturmayı karmaşık hale getirebileceğinden URL oluşturmayı kolaylaştırır. Yol adları, uygulama genelinde benzersiz olmalıdır.

Yol adları:

  • URL eşleştirme veya istekleri işleme üzerinde hiçbir etkisi yoktur.
  • Yalnızca URL oluşturma için kullanılır.

Yol adı kavramı, yönlendirmede IEndpointNameMetadata olarak temsil edilir. Yol adı ve uç nokta adı terimleri:

  • Bunlar birbirinin yerine kullanılabilir.
  • Belgelerde ve kodlarda hangisinin kullanıldığı, açıklanan API'ye bağlıdır.

API'ler için REST öznitelik yönlendirme

RESTAPI'ler, işlemlerin HTTP fiilleri ile temsil edildiği bir kaynak kümesi olarak uygulamanın işlevselliğini modellemek için öznitelik yönlendirmesini kullanmalıdır.

Öznitelik yönlendirme, eylemleri doğrudan yol şablonlarıyla eşlemek için bir dizi öznitelik kullanır. Aşağıdaki kod bir REST API için tipiktir ve sonraki örnekte kullanılır:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

var app = builder.Build();

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();

Yukarıdaki kodda, MapControllers öznitelik yönlendirilmiş denetleyicilerini eşlemek için çağrılır.

Aşağıdaki örnekte:

  • HomeController , varsayılan geleneksel yolun {controller=Home}/{action=Index}/{id?} eşlediği url'lere benzer bir URL kümesiyle eşleşir.
public class HomeController : Controller
{
    [Route("")]
    [Route("Home")]
    [Route("Home/Index")]
    [Route("Home/Index/{id?}")]
    public IActionResult Index(int? id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }

    [Route("Home/About")]
    [Route("Home/About/{id?}")]
    public IActionResult About(int? id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

EylemHomeController.Index, , /Home/Home/Indexveya /Home/Index/3URL yollarından /herhangi biri için çalıştırılır.

Bu örnek, öznitelik yönlendirmesi ile geleneksel yönlendirme arasındaki temel programlama farkını vurgular. Öznitelik yönlendirmesi, yol belirtmek için daha fazla giriş gerektirir. Geleneksel varsayılan yol, yolları daha kısa işler. Ancak, öznitelik yönlendirmesi her eylem için hangi yol şablonlarının geçerli olduğunu hassas bir şekilde denetlemenizi sağlar ve gerektirir.

Öznitelik yönlendirme ile, belirteç değiştirme kullanılmadığı sürece denetleyici ve eylem adları eylemin eşleştirildiği bir rol oynamaz. Aşağıdaki örnek, önceki örnekle aynı URL'ler ile eşleşir:

public class MyDemoController : Controller
{
    [Route("")]
    [Route("Home")]
    [Route("Home/Index")]
    [Route("Home/Index/{id?}")]
    public IActionResult MyIndex(int? id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }

    [Route("Home/About")]
    [Route("Home/About/{id?}")]
    public IActionResult MyAbout(int? id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Aşağıdaki kod ve controlleriçin action belirteç değişimini kullanır:

public class HomeController : Controller
{
    [Route("")]
    [Route("Home")]
    [Route("[controller]/[action]")]
    public IActionResult Index()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    [Route("[controller]/[action]")]
    public IActionResult About()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

Aşağıdaki kod denetleyici için geçerlidir [Route("[controller]/[action]")] :

[Route("[controller]/[action]")]
public class HomeController : Controller
{
    [Route("~/")]
    [Route("/Home")]
    [Route("~/Home/Index")]
    public IActionResult Index()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    public IActionResult About()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

Yukarıdaki kodda, yöntem şablonlarının Index yol şablonlarına önceden / eklenmesi veya ~/ bu şablonlara eklenmesi gerekir. Bir eyleme / uygulanan ve denetleyiciye uygulanan yönlendirme şablonlarıyla birleştirilen veya ~/ olmayan yol şablonları.

Rota şablonu seçimi hakkında bilgi için bkz . Yol şablonu önceliği .

Ayrılmış yönlendirme adları

Denetleyiciler veya Razor Sayfalar kullanılırken aşağıdaki anahtar sözcükler ayrılmış yol parametre adlarıdır:

  • action
  • area
  • controller
  • handler
  • page

Öznitelik yönlendirme ile yol parametresi olarak kullanmak page yaygın bir hatadır. Bunun yapılması, URL oluşturma ile tutarsız ve kafa karıştırıcı davranışlara neden olur.

public class MyDemo2Controller : Controller
{
    [Route("/articles/{page}")]
    public IActionResult ListArticles(int page)
    {
        return ControllerContext.MyDisplayRouteInfo(page);
    }
}

Özel parametre adları, URL oluşturma işleminin Sayfaya mı yoksa Denetleyiciye Razor mi başvurduğuna karar vermek için URL oluşturma tarafından kullanılır.

Aşağıdaki anahtar sözcükler bir Razor görünüm veya Razor Sayfa bağlamında ayrılmıştır:

  • page
  • using
  • namespace
  • inject
  • section
  • inherits
  • model
  • addTagHelper
  • removeTagHelper

Bu anahtar sözcükler bağlantı nesilleri, modele bağlı parametreler veya en üst düzey özellikler için kullanılmamalıdır.

HTTP fiil şablonları

ASP.NET Core aşağıdaki HTTP fiili şablonlarına sahiptir:

Yol şablonları

ASP.NET Core aşağıdaki yol şablonlarına sahiptir:

Http fiili öznitelikleriyle öznitelik yönlendirme

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

[Route("api/[controller]")]
[ApiController]
public class Test2Controller : ControllerBase
{
    [HttpGet]   // GET /api/test2
    public IActionResult ListProducts()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    [HttpGet("{id}")]   // GET /api/test2/xyz
    public IActionResult GetProduct(string id)
    {
       return ControllerContext.MyDisplayRouteInfo(id);
    }

    [HttpGet("int/{id:int}")] // GET /api/test2/int/3
    public IActionResult GetIntProduct(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }

    [HttpGet("int2/{id}")]  // GET /api/test2/int2/3
    public IActionResult GetInt2Product(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Önceki kodda:

  • Her eylem, yalnızca HTTP GET istekleriyle eşleşen özniteliğini içerir [HttpGet] .
  • Eylem GetProduct şablonu içerir "{id}" , bu nedenle id denetleyicideki "api/[controller]" şablona eklenir. Yöntem şablonu şeklindedir "api/[controller]/{id}". Bu nedenle bu eylem yalnızca ,/api/test2/123/api/test2/{any string} vb. formu /api/test2/xyziçin GET istekleriyle eşleşir.
    [HttpGet("{id}")]   // GET /api/test2/xyz
    public IActionResult GetProduct(string id)
    {
       return ControllerContext.MyDisplayRouteInfo(id);
    }
    
  • Eylem GetIntProduct şablonu içerir "int/{id:int}" . Şablonun :int bölümü, yol değerlerini tamsayıya dönüştürülebilecek dizelerle kısıtlar id . için bir /api/test2/int/abcGET isteği:
    • Bu eylemle eşleşmiyor.
    • 404 Bulunamadı hatası döndürür.
      [HttpGet("int/{id:int}")] // GET /api/test2/int/3
      public IActionResult GetIntProduct(int id)
      {
          return ControllerContext.MyDisplayRouteInfo(id);
      }
      
  • Eylem GetInt2Product şablonda yer alır {id} , ancak tamsayıya dönüştürülebilecek değerlerle kısıtlamaz id . için bir /api/test2/int2/abcGET isteği:
    • Bu rotayla eşleşir.
    • Model bağlaması tamsayıya dönüştürülemiyor abc . id yönteminin parametresi tamsayıdır.
    • Model bağlaması tamsayıya dönüştürülemediği abc için 400 Hatalı İstek döndürür.
      [HttpGet("int2/{id}")]  // GET /api/test2/int2/3
      public IActionResult GetInt2Product(int id)
      {
          return ControllerContext.MyDisplayRouteInfo(id);
      }
      

Öznitelik yönlendirme, , HttpPutAttributeve HttpDeleteAttributegibi HttpPostAttributeöznitelikleri kullanabilirHttpMethodAttribute. Tüm HTTP fiil öznitelikleri bir yol şablonu kabul eder. Aşağıdaki örnekte aynı yol şablonuyla eşleşen iki eylem gösterilmektedir:

[ApiController]
public class MyProductsController : ControllerBase
{
    [HttpGet("/products3")]
    public IActionResult ListProducts()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    [HttpPost("/products3")]
    public IActionResult CreateProduct(MyProduct myProduct)
    {
        return ControllerContext.MyDisplayRouteInfo(myProduct.Name);
    }
}

URL yolunu /products3kullanma:

  • EYLEM, MyProductsController.ListProducts HTTP fiili olduğunda GETçalışır.
  • EYLEM, MyProductsController.CreateProduct HTTP fiili olduğunda POSTçalışır.

API REST oluştururken, eylem tüm HTTP yöntemlerini kabul ettiğinden eylem yönteminde kullanmanız [Route(...)] çok nadirdir. API'nizin neleri desteklediği konusunda kesin olmak için daha belirli HTTP fiil özniteliğini kullanmak daha iyidir. API'lerin istemcilerinin hangi yolların REST ve HTTP fiillerinin belirli mantıksal işlemlerle eşlenip eşlenemli olduğunu bilmesi beklenir.

REST API'ler, işlemlerin HTTP fiilleri ile temsil edildiği bir kaynak kümesi olarak uygulamanın işlevselliğini modellemek için öznitelik yönlendirmesini kullanmalıdır. Bu, aynı mantıksal kaynakta GET ve POST gibi birçok işlemin aynı URL'yi kullandığı anlamına gelir. Öznitelik yönlendirme, BIR API'nin genel uç nokta düzenini dikkatle tasarlamak için gereken bir denetim düzeyi sağlar.

Öznitelik yolu belirli bir eyleme uygulandığından, yol şablonu tanımının bir parçası olarak gerekli parametreleri yapmak kolaydır. Aşağıdaki örnekte, id URL yolunun bir parçası olarak gereklidir:

[ApiController]
public class Products2ApiController : ControllerBase
{
    [HttpGet("/products2/{id}", Name = "Products_List")]
    public IActionResult GetProduct(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Eylem Products2ApiController.GetProduct(int) :

  • gibi URL yolu ile çalıştırılır /products2/3
  • URL yolu /products2ile çalıştırılmıyor.

[Consumes] özniteliği, desteklenen istek içerik türlerini sınırlamak için bir eyleme izin verir. Daha fazla bilgi için bkz . Consumes özniteliğiyle desteklenen istek içerik türlerini tanımlama.

Rota şablonlarının ve ilgili seçeneklerin tam açıklaması için bkz . Yönlendirme .

hakkında [ApiController]daha fazla bilgi için bkz . ApiController özniteliği.

Yönlendirme adı

Aşağıdaki kod, yolunun Products_Listadını tanımlar:

[ApiController]
public class Products2ApiController : ControllerBase
{
    [HttpGet("/products2/{id}", Name = "Products_List")]
    public IActionResult GetProduct(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Yol adları, belirli bir yolu temel alan bir URL oluşturmak için kullanılabilir. Yol adları:

  • Yönlendirmenin URL eşleştirme davranışı üzerinde hiçbir etkisi yoktur.
  • Yalnızca URL oluşturma için kullanılır.

Yol adları uygulama genelinde benzersiz olmalıdır.

Yukarıdaki kodu, parametresini isteğe bağlı ({id?}) olarak tanımlayan id geleneksel varsayılan yolla karşıtlık yapın. API'leri tam olarak belirtebilme özelliği, farklı eylemlere izin verme /products ve /products/5 gönderme gibi avantajlara sahiptir.

Öznitelik yollarını birleştirme

Öznitelik yönlendirmesini daha az yinelenen hale getirmek için, denetleyicideki yol öznitelikleri tek tek eylemlerdeki yol öznitelikleriyle birleştirilir. Denetleyicide tanımlanan tüm yol şablonları, eylemlerdeki yol şablonlarına eklenir. Denetleyiciye bir yol özniteliği yerleştirmek, denetleyicideki tüm eylemlerin öznitelik yönlendirmesini kullanmasını sağlar.

[ApiController]
[Route("products")]
public class ProductsApiController : ControllerBase
{
    [HttpGet]
    public IActionResult ListProducts()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    [HttpGet("{id}")]
    public IActionResult GetProduct(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Yukarıdaki örnekte:

  • URL yolu /products eşleşebilir ProductsApi.ListProducts
  • URL yolu /products/5 ile eşleşebilir ProductsApi.GetProduct(int).

Bu eylemlerin her ikisi de özniteliğiyle işaretlendiğinden [HttpGet] yalnızca HTTP GET ile eşleşer.

Bir eyleme / uygulanan ve denetleyiciye uygulanan yönlendirme şablonlarıyla birleştirilen veya ~/ olmayan yol şablonları. Aşağıdaki örnek, varsayılan yola benzer bir URL yolu kümesiyle eşleşir.

[Route("Home")]
public class HomeController : Controller
{
    [Route("")]
    [Route("Index")]
    [Route("/")]
    public IActionResult Index()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    [Route("About")]
    public IActionResult About()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

Aşağıdaki tabloda, önceki koddaki öznitelikler açıklanmaktadır [Route] :

Öznitelik ile birleştirilir [Route("Home")] Yol şablonunu tanımlar
[Route("")] Yes "Home"
[Route("Index")] Evet "Home/Index"
[Route("/")] Hayır ""
[Route("About")] Evet "Home/About"

Öznitelik rota sırası

Yönlendirme bir ağaç oluşturur ve tüm uç noktaları aynı anda eşleştirir:

  • Yol girişleri ideal bir sıralamada yerleştirilmiş gibi davranır.
  • En belirli yolların daha genel yollardan önce yürütme şansı vardır.

Örneğin, gibi bir öznitelik yolu gibi blog/search/{topic}blog/{*article}bir öznitelik yolundan daha belirgindir. Rota blog/search/{topic} daha belirgin olduğundan varsayılan olarak daha yüksek önceliğe sahiptir. Geleneksel yönlendirmeyi kullanarak, rotaları istenen sırada yerleştirmek geliştiricinin sorumluluğundadır.

Öznitelik yolları özelliğini kullanarak Order bir sıra yapılandırabilir. Sağlanan tüm çerçeve yol öznitelikleri içerir Order . Yollar, özelliğin artan bir türüne Order göre işlenir. Varsayılan sıra şeklindedir 0. Bir düzeni ayarlamamış rotalardan Order = -1 önce çalıştırarak rota ayarlama. Varsayılan yol sıralamadan sonra çalıştırarak Order = 1 bir yol ayarlama.

öğesine bağlı Orderolarak kullanmaktan kaçının. Bir uygulamanın URL alanı doğru yönlendirmek için açık sipariş değerleri gerektiriyorsa, istemciler için de kafa karıştırıcı olabilir. Genel olarak, öznitelik yönlendirme url eşleştirme ile doğru yolu seçer. URL oluşturma için kullanılan varsayılan sıra çalışmıyorsa, geçersiz kılma olarak yol adı kullanmak genellikle özelliğin Order uygulanmasından daha basittir.

Her ikisinin de yol eşleştirmesini /hometanımlayan aşağıdaki iki denetleyiciyi göz önünde bulundurun:

public class HomeController : Controller
{
    [Route("")]
    [Route("Home")]
    [Route("Home/Index")]
    [Route("Home/Index/{id?}")]
    public IActionResult Index(int? id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }

    [Route("Home/About")]
    [Route("Home/About/{id?}")]
    public IActionResult About(int? id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}
public class MyDemoController : Controller
{
    [Route("")]
    [Route("Home")]
    [Route("Home/Index")]
    [Route("Home/Index/{id?}")]
    public IActionResult MyIndex(int? id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }

    [Route("Home/About")]
    [Route("Home/About/{id?}")]
    public IActionResult MyAbout(int? id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

/home Yukarıdaki kodla istekte bulunmak aşağıdakine benzer bir özel durum oluşturur:

AmbiguousMatchException: The request matched multiple endpoints. Matches:

 WebMvcRouting.Controllers.HomeController.Index
 WebMvcRouting.Controllers.MyDemoController.MyIndex

Yol özniteliklerinden birine eklendiğinde Order belirsizlik çözülür:

[Route("")]
[Route("Home", Order = 2)]
[Route("Home/MyIndex")]
public IActionResult MyIndex()
{
    return ControllerContext.MyDisplayRouteInfo();
}

Yukarıdaki kodla uç /home noktayı çalıştırır HomeController.Index . adresine ulaşmak için MyDemoController.MyIndexisteğinde bulunın /home/MyIndex. Not:

  • Yukarıdaki kod bir örnek veya kötü yönlendirme tasarımıdır. Özelliği göstermek için kullanılmıştır Order .
  • Order özelliği yalnızca belirsizliği giderir, bu şablon eşleştirilemez. Şablonu kaldırmak [Route("Home")] daha iyi olur.

Sayfalar rotası ve uygulama kuralları: Sayfalar ile Razor yönlendirme sırası hakkında bilgi için bkzRazor. Yönlendirme sırası.

Bazı durumlarda, belirsiz yollar içeren bir HTTP 500 hatası döndürülür. hangi uç noktaların neden olduğunu görmek için günlüğe kaydetmeyiAmbiguousMatchExceptionkullanın.

Yol şablonlarında belirteç değiştirme [denetleyici], [eylem], [alan]

Kolaylık sağlamak için öznitelik yolları, bir belirteci köşeli ayraç içine alarak belirtecin değiştirilmesini destekler ([, ]). , [area]ve [controller] belirteçleri[action], yolun tanımlandığı eylemdeki eylem adı, alan adı ve denetleyici adı değerleriyle değiştirilir:

[Route("[controller]/[action]")]
public class Products0Controller : Controller
{
    [HttpGet]
    public IActionResult List()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }


    [HttpGet("{id}")]
    public IActionResult Edit(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Önceki kodda:

[HttpGet]
public IActionResult List()
{
    return ControllerContext.MyDisplayRouteInfo();
}
  • Eşleşen /Products0/List
[HttpGet("{id}")]
public IActionResult Edit(int id)
{
    return ControllerContext.MyDisplayRouteInfo(id);
}
  • Eşleşen /Products0/Edit/{id}

Belirteç değiştirme, öznitelik yollarını oluşturmanın son adımı olarak gerçekleşir. Yukarıdaki örnek aşağıdaki kodla aynı şekilde davranır:

public class Products20Controller : Controller
{
    [HttpGet("[controller]/[action]")]  // Matches '/Products20/List'
    public IActionResult List()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    [HttpGet("[controller]/[action]/{id}")]   // Matches '/Products20/Edit/{id}'
    public IActionResult Edit(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Bunu İngilizce dışında bir dilde okuyorsanız, kod açıklamalarını ana dilinizde görmek isterseniz bu GitHub tartışma sorununda bize bildirin.

Öznitelik yolları devralma ile de birleştirilebilir. Bu, belirteç değiştirme ile birlikte güçlüdür. Belirteç değiştirme, öznitelik yolları tarafından tanımlanan yol adları için de geçerlidir. [Route("[controller]/[action]", Name="[controller]_[action]")]her eylem için benzersiz bir yol adı oluşturur:

[ApiController]
[Route("api/[controller]/[action]", Name = "[controller]_[action]")]
public abstract class MyBase2Controller : ControllerBase
{
}

public class Products11Controller : MyBase2Controller
{
    [HttpGet]                      // /api/products11/list
    public IActionResult List()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    [HttpGet("{id}")]             //    /api/products11/edit/3
    public IActionResult Edit(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Değişmez değer belirteci değiştirme sınırlayıcısı [ veya ]ile eşleştirmek için karakteri ([[ veya ]]) yineleyerek bu sınırlayıcıdan kaçın.

Belirteç değişimini özelleştirmek için parametre transformatörü kullanma

Belirteç değiştirme, bir parametre transformatörü kullanılarak özelleştirilebilir. Parametre transformatörü parametrelerin IOutboundParameterTransformer değerini uygular ve dönüştürür. Örneğin, özel SlugifyParameterTransformer parametre transformatörü yol değerini olarak subscription-managementdeğiştirirSubscriptionManagement:

using System.Text.RegularExpressions;

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

RouteTokenTransformerConvention, aşağıdakilere sahip bir uygulama modeli kuralıdır:

  • Bir uygulamadaki tüm öznitelik yollarına bir parametre transformatörü uygular.
  • Öznitelik yol belirteci değerlerini değiştirildiğinde özelleştirir.
public class SubscriptionManagementController : Controller
{
    [HttpGet("[controller]/[action]")]
    public IActionResult ListAll()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

Yukarıdaki ListAll yöntem ile eşleşir /subscription-management/list-all.

RouteTokenTransformerConvention seçeneği olarak kaydedilir:

using Microsoft.AspNetCore.Mvc.ApplicationModels;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews(options =>
{
    options.Conventions.Add(new RouteTokenTransformerConvention(
                                 new SlugifyParameterTransformer()));
});

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

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

app.Run();

Slug'ın tanımı için bkz . Slug üzerinde MDN web belgeleri.

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.

Birden çok öznitelik yolu

Öznitelik yönlendirme, aynı eyleme ulaşan birden çok yol tanımlamayı destekler. Bunun en yaygın kullanımı, aşağıdaki örnekte gösterildiği gibi varsayılan geleneksel yolun davranışını taklit etmektir:

[Route("[controller]")]
public class Products13Controller : Controller
{
    [Route("")]     // Matches 'Products13'
    [Route("Index")] // Matches 'Products13/Index'
    public IActionResult Index()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

Denetleyiciye birden çok yol özniteliği koymak, her birinin eylem yöntemlerindeki yol özniteliklerinin her biriyle birleştirilmesi anlamına gelir:

[Route("Store")]
[Route("[controller]")]
public class Products6Controller : Controller
{
    [HttpPost("Buy")]       // Matches 'Products6/Buy' and 'Store/Buy'
    [HttpPost("Checkout")]  // Matches 'Products6/Checkout' and 'Store/Checkout'
    public IActionResult Buy()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

Tüm HTTP fiil yolu kısıtlamaları uygularIActionConstraint.

Uygulayan IActionConstraint birden çok yol özniteliği bir eyleme yerleştirildiğinde:

  • Her eylem kısıtlaması, denetleyiciye uygulanan yol şablonuyla birleştirilir.
[Route("api/[controller]")]
public class Products7Controller : ControllerBase
{
    [HttpPut("Buy")]        // Matches PUT 'api/Products7/Buy'
    [HttpPost("Checkout")]  // Matches POST 'api/Products7/Checkout'
    public IActionResult Buy()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

Eylemlerde birden çok yol kullanmak yararlı ve güçlü görünebilir; uygulamanızın URL alanını temel ve iyi tanımlanmış olarak tutmak daha iyidir. Eylemlerde yalnızca gerektiğinde, örneğin mevcut istemcileri desteklemek için birden çok yol kullanın.

Öznitelik yolu isteğe bağlı parametreleri, varsayılan değerleri ve kısıtlamaları belirtme

Öznitelik yolları isteğe bağlı parametreleri, varsayılan değerleri ve kısıtlamaları belirtmek için geleneksel yollar ile aynı satır içi söz dizimini destekler.

public class Products14Controller : Controller
{
    [HttpPost("product14/{id:int}")]
    public IActionResult ShowProduct(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Yukarıdaki kodda bir [HttpPost("product14/{id:int}")] yol kısıtlaması uygular. Eylem Products14Controller.ShowProduct yalnızca gibi /product14/3URL yollarıyla eşleştirilir. Yol şablonu bölümü {id:int} , bu segmenti yalnızca tamsayılarla kısıtlar.

Yol şablonu söz diziminin ayrıntılı açıklaması için bkz . Yol Şablonu Başvurusu .

IRouteTemplateProvider kullanan özel yol öznitelikleri

Tüm yol öznitelikleri uygularIRouteTemplateProvider. ASP.NET Core çalışma zamanı:

  • Uygulama başlatıldığında denetleyici sınıflarında ve eylem yöntemlerinde öznitelikleri arar.
  • İlk yol kümesini oluşturmak için uygulayan IRouteTemplateProvider öznitelikleri kullanır.

Özel yol özniteliklerini tanımlamak için uygulayın IRouteTemplateProvider . Her IRouteTemplateProvider bir özel yol şablonu, sırası ve adıyla tek bir yol tanımlamanızı sağlar:

public class MyApiControllerAttribute : Attribute, IRouteTemplateProvider
{
    public string Template => "api/[controller]";
    public int? Order => 2;
    public string Name { get; set; } = string.Empty;
}

[MyApiController]
[ApiController]
public class MyTestApiController : ControllerBase
{
    // GET /api/MyTestApi
    [HttpGet]
    public IActionResult Get()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

Yukarıdaki Get yöntem döndürür Order = 2, Template = api/MyTestApi.

Öznitelik yollarını özelleştirmek için uygulama modelini kullanma

Uygulama modeli:

  • içinde başlangıçta Program.csoluşturulan bir nesne modelidir.
  • bir uygulamada eylemleri yönlendirmek ve yürütmek için ASP.NET Core tarafından kullanılan tüm meta verileri içerir.

Uygulama modeli, yol özniteliklerinden toplanan tüm verileri içerir. Yol özniteliklerindeki veriler uygulama tarafından IRouteTemplateProvider sağlanır. Kural -ları:

  • Yönlendirmenin davranışını özelleştirmek için uygulama modelini değiştirmek için yazılabilir.
  • Uygulama başlangıcında okunur.

Bu bölümde, uygulama modelini kullanarak yönlendirmeyi özelleştirmeye yönelik temel bir örnek gösterilmektedir. Aşağıdaki kod, yolları kabaca projenin klasör yapısıyla hizalar.

public class NamespaceRoutingConvention : Attribute, IControllerModelConvention
{
    private readonly string _baseNamespace;

    public NamespaceRoutingConvention(string baseNamespace)
    {
        _baseNamespace = baseNamespace;
    }

    public void Apply(ControllerModel controller)
    {
        var hasRouteAttributes = controller.Selectors.Any(selector =>
                                                selector.AttributeRouteModel != null);
        if (hasRouteAttributes)
        {
            return;
        }

        var namespc = controller.ControllerType.Namespace;
        if (namespc == null)
            return;
        var template = new StringBuilder();
        template.Append(namespc, _baseNamespace.Length + 1,
                        namespc.Length - _baseNamespace.Length - 1);
        template.Replace('.', '/');
        template.Append("/[controller]/[action]/{id?}");

        foreach (var selector in controller.Selectors)
        {
            selector.AttributeRouteModel = new AttributeRouteModel()
            {
                Template = template.ToString()
            };
        }
    }
}

Aşağıdaki kod, kuralın namespace yönlendirilen öznitelik denetleyicilerine uygulanmasını engeller:

public void Apply(ControllerModel controller)
{
    var hasRouteAttributes = controller.Selectors.Any(selector =>
                                            selector.AttributeRouteModel != null);
    if (hasRouteAttributes)
    {
        return;
    }

Örneğin, aşağıdaki denetleyici şunu kullanmaz NamespaceRoutingConvention:

[Route("[controller]/[action]/{id?}")]
public class ManagersController : Controller
{
    // /managers/index
    public IActionResult Index()
    {
        var template = ControllerContext.ActionDescriptor.AttributeRouteInfo?.Template;
        return Content($"Index- template:{template}");
    }

    public IActionResult List(int? id)
    {
        var path = Request.Path.Value;
        return Content($"List- Path:{path}");
    }
}

NamespaceRoutingConvention.Apply yöntemi:

  • Denetleyici öznitelik yönlendirildiyse hiçbir şey yapmaz.
  • temeli kaldırılmış olarak namespace denetleyiciler şablonunu temel alarak namespaceayarlar.

NamespaceRoutingConvention içinde uygulanabilirProgram.cs:

using My.Application.Controllers;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews(options =>
{
    options.Conventions.Add(
     new NamespaceRoutingConvention(typeof(HomeController).Namespace!));
});

var app = builder.Build();

Örneğin, aşağıdaki denetleyiciyi göz önünde bulundurun:

using Microsoft.AspNetCore.Mvc;

namespace My.Application.Admin.Controllers
{
    public class UsersController : Controller
    {
        // GET /admin/controllers/users/index
        public IActionResult Index()
        {
            var fullname = typeof(UsersController).FullName;
            var template = 
                ControllerContext.ActionDescriptor.AttributeRouteInfo?.Template;
            var path = Request.Path.Value;

            return Content($"Path: {path} fullname: {fullname}  template:{template}");
        }

        public IActionResult List(int? id)
        {
            var path = Request.Path.Value;
            return Content($"Path: {path} ID:{id}");
        }
    }
}

Önceki kodda:

  • Taban namespace şeklindedir My.Application.
  • Önceki denetleyicinin tam adı şeklindedir My.Application.Admin.Controllers.UsersController.
  • denetleyiciler NamespaceRoutingConvention şablonunu olarak Admin/Controllers/Users/[action]/{id?ayarlar.

, NamespaceRoutingConvention bir denetleyiciye öznitelik olarak da uygulanabilir:

[NamespaceRoutingConvention("My.Application")]
public class TestController : Controller
{
    // /admin/controllers/test/index
    public IActionResult Index()
    {
        var template = ControllerContext.ActionDescriptor.AttributeRouteInfo?.Template;
        var actionname = ControllerContext.ActionDescriptor.ActionName;
        return Content($"Action- {actionname} template:{template}");
    }

    public IActionResult List(int? id)
    {
        var path = Request.Path.Value;
        return Content($"List- Path:{path}");
    }
}

Karma yönlendirme: Öznitelik yönlendirmesi ile geleneksel yönlendirme karşılaştırması

ASP.NET Core uygulamaları, geleneksel yönlendirme ve öznitelik yönlendirme kullanımını karıştırabilir. Tarayıcılar için HTML sayfaları sunan denetleyiciler için geleneksel yolların ve API'leri sunan REST denetleyiciler için öznitelik yönlendirmenin kullanılması normaldir.

Eylemler geleneksel olarak yönlendirilir veya öznitelik yönlendirilir. Denetleyiciye veya eyleme bir yol yerleştirmek, bunun yönlendirilmiş özniteliğini oluşturur. Öznitelik yollarını tanımlayan eylemlere geleneksel yollar üzerinden (veya tam tersi) erişilemez. Denetleyicideki herhangi bir yol özniteliği, denetleyici özniteliğindeki tüm eylemlerin yönlendirilmiş olmasını sağlar.

Öznitelik yönlendirme ve geleneksel yönlendirme aynı yönlendirme altyapısını kullanır.

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

URL Oluşturma ve ortam değerleri

Uygulamalar, eylemlere URL bağlantıları oluşturmak için yönlendirme URL'si oluşturma özelliklerini kullanabilir. URL'lerin oluşturulması sabit kodlama URL'lerini ortadan kaldırarak kodu daha sağlam ve sürdürülebilir hale getirir. Bu bölüm, MVC tarafından sağlanan URL oluşturma özelliklerine odaklanır ve yalnızca URL oluşturmanın nasıl çalıştığına ilişkin temel bilgileri kapsar. URL oluşturmanın ayrıntılı açıklaması için bkz . Yönlendirme .

IUrlHelper Arabirim, MVC ile URL oluşturma için yönlendirme arasındaki altyapının temel öğesidir. örneğini IUrlHelper denetleyiciler, görünümler ve görünüm bileşenlerindeki özelliği aracılığıyla Url kullanabilirsiniz.

Aşağıdaki örnekte, IUrlHelper arabirim özelliği aracılığıyla başka bir eylemin Controller.Url URL'sini oluşturmak için kullanılır.

public class UrlGenerationController : Controller
{
    public IActionResult Source()
    {
        // Generates /UrlGeneration/Destination
        var url = Url.Action("Destination");
        return ControllerContext.MyDisplayRouteInfo("", $" URL = {url}");
    }

    public IActionResult Destination()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

Uygulama varsayılan geleneksel yolu kullanıyorsa değişkeninin url değeri URL yol dizesidir /UrlGeneration/Destination. Bu URL yolu, aşağıdakiler birleştirilerek yönlendirmeyle oluşturulur:

  • Geçerli istekten gelen ve ortam değerleri olarak adlandırılan yol değerleri.
  • yol şablonuna Url.Action geçirilen ve bu değerlerin yerine geçen değerler:
ambient values: { controller = "UrlGeneration", action = "Source" }
values passed to Url.Action: { controller = "UrlGeneration", action = "Destination" }
route template: {controller}/{action}/{id?}

result: /UrlGeneration/Destination

Yol şablonundaki her yol parametresinin değeri, değerleri ve ortam değerleriyle eşleşen adlarla değiştirilir. Değeri olmayan bir yol parametresi şu şekilde olabilir:

  • Varsa varsayılan bir değer kullanın.
  • İsteğe bağlıysa atlanır. Örneğin, id rota şablonundan {controller}/{action}/{id?}.

Gerekli bir yol parametresine karşılık gelen bir değer yoksa URL oluşturma işlemi başarısız olur. URL oluşturma bir yol için başarısız olursa, tüm yollar denenene veya eşleşme bulunana kadar sonraki yol denener.

Yukarıdaki örnek, Url.Action geleneksel yönlendirmeyi varsayar. URL oluşturma, öznitelik yönlendirmede benzer şekilde çalışır ancak kavramlar farklıdır. Geleneksel yönlendirme ile:

  • Yol değerleri, şablonu genişletmek için kullanılır.
  • ve action için controller yol değerleri genellikle bu şablonda görünür. Yönlendirme tarafından eşleşen URL'ler bir kurala bağlı olduğundan bu işe yarar.

Aşağıdaki örnek öznitelik yönlendirmeyi kullanır:

public class UrlGenerationAttrController : Controller
{
    [HttpGet("custom")]
    public IActionResult Source()
    {
        var url = Url.Action("Destination");
        return ControllerContext.MyDisplayRouteInfo("", $" URL = {url}");
    }

    [HttpGet("custom/url/to/destination")]
    public IActionResult Destination()
    {
       return ControllerContext.MyDisplayRouteInfo();
    }
}

Yukarıdaki Source koddaki eylem oluşturur custom/url/to/destination.

LinkGenerator ASP.NET Core 3.0'a IUrlHelperalternatif olarak eklendi. LinkGenerator benzer ama daha esnek işlevler sunar. üzerindeki IUrlHelper her yöntemin de üzerinde karşılık gelen bir yöntem LinkGenerator ailesi vardır.

Eylem adına göre URL oluşturma

Url.Action, LinkGenerator.GetPathByAction ve tüm ilgili aşırı yüklemeler, bir denetleyici adı ve eylem adı belirterek hedef uç noktayı oluşturmak üzere tasarlanmıştır.

kullanırken Url.Actionve action için controller geçerli yol değerleri çalışma zamanı tarafından sağlanır:

  • ve action değeri controller hem ortam değerlerinin hem de değerlerin bir parçasıdır. yöntemi Url.Action her zaman geçerli ve controller değerlerini action kullanır ve geçerli eyleme yönlendiren bir URL yolu oluşturur.

Yönlendirme, bir URL oluşturulurken sağlanmayan bilgileri doldurmak için ortam değerlerindeki değerleri kullanmayı dener. Ortam değerleriyle { a = Alice, b = Bob, c = Carol, d = David }gibi {a}/{b}/{c}/{d} bir yol düşünün:

  • Yönlendirme, ek değer içermeyen bir URL oluşturmak için yeterli bilgiye sahiptir.
  • Tüm yol parametrelerinin bir değeri olduğundan yönlendirme yeterli bilgiye sahiptir.

Değer { d = Donovan } eklenirse:

  • Değer { d = David } yoksayılır.
  • Oluşturulan URL yolu şeklindedir Alice/Bob/Carol/Donovan.

Uyarı: URL yolları hiyerarşiktir. Yukarıdaki örnekte, değer { c = Cheryl } eklenirse:

  • Her iki değer { c = Carol, d = David } de yoksayılır.
  • artık için d bir değer yok ve URL oluşturma başarısız oluyor.
  • URL oluşturmak için istenen ve d değerleri c belirtilmelidir.

Bu soruna varsayılan yoluyla {controller}/{action}/{id?}ulaşmayı bekleyebilirsiniz. Her zaman bir controller ve action değerini açıkça belirttiği için Url.Action bu sorun pratikte nadir görülür.

Url.Action'ın çeşitli aşırı yüklemeleri, ve actiondışındaki controller yol parametreleri için değerler sağlamak üzere bir yol değerleri nesnesi alır. Yol değerleri nesnesi ile idsık sık kullanılır. Örneğin, Url.Action("Buy", "Products", new { id = 17 }). Yol değerleri nesnesi:

  • Kurala göre genellikle anonim türde bir nesnedir.
  • veya POCO olabilirIDictionary<>).

Yol parametreleriyle eşleşmeyen ek yol değerleri sorgu dizesine eklenir.

public IActionResult Index()
{
    var url = Url.Action("Buy", "Products", new { id = 17, color = "red" });
    return Content(url!);
}

Yukarıdaki kod oluşturur /Products/Buy/17?color=red.

Aşağıdaki kod mutlak bir URL oluşturur:

public IActionResult Index2()
{
    var url = Url.Action("Buy", "Products", new { id = 17 }, protocol: Request.Scheme);
    // Returns https://localhost:5001/Products/Buy/17
    return Content(url!);
}

Mutlak URL oluşturmak için aşağıdakilerden birini kullanın:

Rotaya göre URL'ler oluşturma

Yukarıdaki kod, denetleyiciyi ve eylem adını geçirerek URL oluşturmayı gösterdi. IUrlHelperayrıca Url.RouteUrl yöntem ailesini de sağlar. Bu yöntemler Url.Action'a benzer, ancak geçerli ve controller değerlerini action yol değerlerine kopyalamaz. en yaygın kullanımı Url.RouteUrl:

  • URL'yi oluşturmak için bir yol adı belirtir.
  • Genellikle bir denetleyici veya eylem adı belirtmez.
public class UrlGeneration2Controller : Controller
{
    [HttpGet("")]
    public IActionResult Source()
    {
        var url = Url.RouteUrl("Destination_Route");
        return ControllerContext.MyDisplayRouteInfo("", $" URL = {url}");
    }

    [HttpGet("custom/url/to/destination2", Name = "Destination_Route")]
    public IActionResult Destination()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

Aşağıdaki Razor dosya, dosyasına Destination_Routebir HTML bağlantısı oluşturur:

<h1>Test Links</h1>

<ul>
    <li><a href="@Url.RouteUrl("Destination_Route")">Test Destination_Route</a></li>
</ul>

HTML'de URL'ler oluşturma ve Razor

IHtmlHelperHtmlHelper, ve öğelerini oluşturmak <form> için sırasıyla Html.BeginForm ve <a> Html.ActionLink yöntemlerini sağlar. Bu yöntemler url oluşturmak için Url.Action yöntemini kullanır ve benzer bağımsız değişkenleri kabul eder. Url.RouteUrl için HtmlHelper eşlikçiler Html.BeginRouteFormHtml.RouteLink ve benzer işlevlere sahiptir.

TagHelpers, TagHelper ve <a> TagHelper aracılığıyla form URL'ler oluşturur. Bunların her ikisi de uygulamaları için kullanılır IUrlHelper . Daha fazla bilgi için bkz . Formlardaki Etiket Yardımcıları.

İç görünümler, IUrlHelper yukarıdakilerin kapsamına Url alınmayan geçici URL'ler için özelliği aracılığıyla kullanılabilir.

Eylem Sonuçlarında URL oluşturma

Yukarıdaki örnekler bir denetleyicide kullanılarak IUrlHelper gösterildi. Denetleyicideki en yaygın kullanım, eylem sonucunun bir parçası olarak BIR URL oluşturmaktır.

ControllerBase ve Controller temel sınıfları, başka bir eyleme başvuran eylem sonuçları için kolaylık yöntemleri sağlar. Tipik kullanımlardan biri, kullanıcı girişini kabul ettikten sonra yeniden yönlendirmektir:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Edit(int id, Customer customer)
{
    if (ModelState.IsValid)
    {
        // Update DB with new details.
        ViewData["Message"] = $"Successful edit of customer {id}";
        return RedirectToAction("Index");
    }
    return View(customer);
}

Eylem, ve gibi RedirectToActionCreatedAtAction fabrika yöntemlerini ve üzerindeki IUrlHelperyöntemlere benzer bir deseni izler.

Ayrılmış geleneksel yollar için özel durum

Geleneksel yönlendirme , ayrılmış geleneksel yol olarak adlandırılan özel bir yol tanımı türü kullanabilir. Aşağıdaki örnekte adlı blog yol ayrılmış bir geleneksel yoldur:

app.MapControllerRoute(name: "blog",
                pattern: "blog/{*article}",
                defaults: new { controller = "Blog", action = "Article" });
app.MapControllerRoute(name: "default",
               pattern: "{controller=Home}/{action=Index}/{id?}");

Önceki yol tanımlarını kullanarak, Url.Action("Index", "Home") yolu kullanarak default URL yolunu / oluşturur, ancak neden? yol değerlerinin { controller = Home, action = Index } kullanarak blogbir URL oluşturmak için yeterli olacağını ve sonucun olacağını /blog?action=Index&controller=Hometahmin edebilirsiniz.

Ayrılmış geleneksel yollar , url oluşturmada yolun çok doyumsuz olmasını engelleyen ilgili bir yol parametresi olmayan varsayılan değerlerin özel bir davranışına dayanır. Bu durumda varsayılan değerler şeklindedir { controller = Blog, action = Article }ve controlleraction yol parametresi olarak gösterilmez. Yönlendirme URL oluşturmayı gerçekleştirirken, sağlanan değerlerin varsayılan değerlerle eşleşmesi gerekir. değerleri { controller = Home, action = Index } eşleşmediğinden { controller = Blog, action = Article }kullanarak blog URL oluşturma işlemi başarısız oluyor. Ardından yönlendirme, başarılı olan öğesini denemek defaultiçin geri döner.

Alanlar

Alanlar , ilgili işlevleri ayrı bir grup halinde düzenlemek için kullanılan bir MVC özelliğidir:

  • Denetleyici eylemleri için yönlendirme ad alanı.
  • Görünümler için klasör yapısı.

Alanların kullanılması, bir uygulamanın farklı alanlara sahip olduğu sürece aynı ada sahip birden çok denetleyiciye sahip olmasını sağlar. Alanları kullanmak, ve action'ye controller başka bir yol parametresi area ekleyerek yönlendirme amacıyla bir hiyerarşi oluşturur. Bu bölümde yönlendirmenin alanlarla nasıl etkileşime geçtiği açıklanır. Alanların görünümlerle nasıl kullanıldığı hakkında ayrıntılı bilgi için bkz. Alanlar.

Aşağıdaki örnek MVC'yi varsayılan geleneksel yolu ve adlandırılmış Blogbir areaarea yolu kullanacak şekilde yapılandırılır:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllersWithViews();

var app = builder.Build();

if (!app.Environment.IsDevelopment())
{    
    app.UseExceptionHandler("/Home/Error");
    app.UseHsts();
}

app.UseHttpsRedirection();
app.UseStaticFiles();

app.UseRouting();

app.UseAuthorization();

app.MapAreaControllerRoute("blog_route", "Blog",
        "Manage/{controller}/{action}/{id?}");
app.MapControllerRoute("default_route", "{controller}/{action}/{id?}");

app.Run();

Yukarıdaki kodda, MapAreaControllerRoute oluşturmak için çağrılır "blog_route". İkinci parametre olan "Blog", alan adıdır.

gibi /Manage/Users/AddUser"blog_route" bir URL yolu eşleştirildiğinde yol, yol değerlerini { area = Blog, controller = Users, action = AddUser }oluşturur. Yol area değeri için areavarsayılan değer tarafından oluşturulur. tarafından MapAreaControllerRoute oluşturulan yol aşağıdakine eşdeğerdir:

app.MapControllerRoute("blog_route", "Manage/{controller}/{action}/{id?}",
        defaults: new { area = "Blog" }, constraints: new { area = "Blog" });
app.MapControllerRoute("default_route", "{controller}/{action}/{id?}");

MapAreaControllerRoute , sağlanan alan adını kullanmak için area hem varsayılan değeri hem de kısıtlamayı kullanarak bir yol oluşturur. Bu durumda Blog. Varsayılan değer, yolun her zaman üretmesini { area = Blog, ... }sağlar. Kısıtlama, URL oluşturma için değeri { area = Blog, ... } gerektirir.

Geleneksel yönlendirme, siparişe bağlıdır. Genel olarak, alanları olan yollar, alanı olmayan rotalara göre daha belirgin olduğundan daha erken yerleştirilmelidir.

Yukarıdaki örneği kullanarak yol değerleri aşağıdaki eylemle eşleşmektedir { area = Blog, controller = Users, action = AddUser } :

using Microsoft.AspNetCore.Mvc;

namespace MyApp.Namespace1
{
    [Area("Blog")]
    public class UsersController : Controller
    {
        // GET /manage/users/adduser
        public IActionResult AddUser()
        {
            var area = ControllerContext.ActionDescriptor.RouteValues["area"];
            var actionName = ControllerContext.ActionDescriptor.ActionName;
            var controllerName = ControllerContext.ActionDescriptor.ControllerName;

            return Content($"area name:{area}" +
                $" controller:{controllerName}  action name: {actionName}");
        }        
    }
}

[Alan] özniteliği, bir alanın parçası olarak denetleyiciyi gösteren özelliktir. Bu denetleyici Blog bölgede. Özniteliği olmayan [Area] denetleyiciler hiçbir alanın üyesi değildir ve yönlendirme tarafından yol değeri sağlandığında area eşleşmez. Aşağıdaki örnekte, yalnızca listelenen ilk denetleyici yol değerleriyle { area = Blog, controller = Users, action = AddUser }eşleşebilir.

using Microsoft.AspNetCore.Mvc;

namespace MyApp.Namespace1
{
    [Area("Blog")]
    public class UsersController : Controller
    {
        // GET /manage/users/adduser
        public IActionResult AddUser()
        {
            var area = ControllerContext.ActionDescriptor.RouteValues["area"];
            var actionName = ControllerContext.ActionDescriptor.ActionName;
            var controllerName = ControllerContext.ActionDescriptor.ControllerName;

            return Content($"area name:{area}" +
                $" controller:{controllerName}  action name: {actionName}");
        }        
    }
}
using Microsoft.AspNetCore.Mvc;

namespace MyApp.Namespace2
{
    // Matches { area = Zebra, controller = Users, action = AddUser }
    [Area("Zebra")]
    public class UsersController : Controller
    {
        // GET /zebra/users/adduser
        public IActionResult AddUser()
        {
            var area = ControllerContext.ActionDescriptor.RouteValues["area"];
            var actionName = ControllerContext.ActionDescriptor.ActionName;
            var controllerName = ControllerContext.ActionDescriptor.ControllerName;

            return Content($"area name:{area}" +
                $" controller:{controllerName}  action name: {actionName}");
        }        
    }
}
using Microsoft.AspNetCore.Mvc;

namespace MyApp.Namespace3
{
    // Matches { area = string.Empty, controller = Users, action = AddUser }
    // Matches { area = null, controller = Users, action = AddUser }
    // Matches { controller = Users, action = AddUser }
    public class UsersController : Controller
    {
        // GET /users/adduser
        public IActionResult AddUser()
        {
            var area = ControllerContext.ActionDescriptor.RouteValues["area"];
            var actionName = ControllerContext.ActionDescriptor.ActionName;
            var controllerName = ControllerContext.ActionDescriptor.ControllerName;

            return Content($"area name:{area}" +
                $" controller:{controllerName}  action name: {actionName}");
        }
    }
}

Her denetleyicinin ad alanı tamlık için burada gösterilir. Önceki denetleyiciler aynı ad alanını kullandıysa bir derleyici hatası oluşturulur. Sınıf ad alanlarının MVC'nin yönlendirmesi üzerinde hiçbir etkisi yoktur.

İlk iki denetleyici, alanların üyeleridir ve yalnızca ilgili alan adları yol değeri tarafından area sağlandığında eşleşilir. Üçüncü denetleyici herhangi bir alanın üyesi değildir ve yalnızca yönlendirme tarafından değeri area sağlanmayanlarla eşleşebilir.

Değer eşleştirme açısından değerinarea olmaması, değerin null veya boş dize olmasıyla area aynıdır.

Bir alanın içinde bir eylem yürütürken için yol değeri area , URL oluşturma için kullanılacak yönlendirme için bir ortam değeri olarak kullanılabilir. Bu, aşağıdaki örnekte gösterildiği gibi, varsayılan olarak ALANLARıN URL oluşturma için yapışkan davrandığı anlamına gelir.

app.MapAreaControllerRoute(name: "duck_route",
                                     areaName: "Duck",
                                     pattern: "Manage/{controller}/{action}/{id?}");
app.MapControllerRoute(name: "default",
                             pattern: "Manage/{controller=Home}/{action=Index}/{id?}");
using Microsoft.AspNetCore.Mvc;

namespace MyApp.Namespace4
{
    [Area("Duck")]
    public class UsersController : Controller
    {
        // GET /Manage/users/GenerateURLInArea
        public IActionResult GenerateURLInArea()
        {
            // Uses the 'ambient' value of area.
            var url = Url.Action("Index", "Home");
            // Returns /Manage/Home/Index
            return Content(url);
        }

        // GET /Manage/users/GenerateURLOutsideOfArea
        public IActionResult GenerateURLOutsideOfArea()
        {
            // Uses the empty value for area.
            var url = Url.Action("Index", "Home", new { area = "" });
            // Returns /Manage
            return Content(url);
        }
    }
}

Aşağıdaki kod için /Zebra/Users/AddUserbir URL oluşturur:

public class HomeController : Controller
{
    public IActionResult About()
    {
        var url = Url.Action("AddUser", "Users", new { Area = "Zebra" });
        return Content($"URL: {url}");
    }

Eylem tanımı

NonAction özniteliğine sahip olanlar dışında bir denetleyicideki genel yöntemler eylemlerdir.

Örnek kod

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"
    }
  }
}

ASP.NET Core denetleyicileri, gelen isteklerin URL'lerini eşleştirmek ve bunları eylemlerle eşlemek için Yönlendirme ara yazılımını kullanır. Yol şablonları:

  • Başlangıç kodunda veya özniteliklerinde tanımlanır.
  • URL yollarının eylemlerle nasıl eşlendiğini açıklayın.
  • Bağlantılar için URL'ler oluşturmak için kullanılır. Oluşturulan bağlantılar genellikle yanıt olarak döndürülür.

Eylemler geleneksel olarak yönlendirilir veya öznitelik tarafından yönlendirilir. Denetleyiciye veya eyleme bir yol yerleştirmek, denetleyicinin öznitelik yönlendirmeli olmasını sağlar. Daha fazla bilgi için bkz . Karma yönlendirme .

Bu belge:

Geleneksel rotayı ayarlama

Startup.Configuregenellikle geleneksel yönlendirme kullanılırken aşağıdakine benzer bir koda sahiptir:

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

çağrısının UseEndpointsMapControllerRoute içinde, tek bir yol oluşturmak için kullanılır. Tek yol route olarak adlandırılır default . Denetleyicileri ve görünümleri olan çoğu uygulama, yola benzer default bir yol şablonu kullanır. RESTAPI'ler öznitelik yönlendirme kullanmalıdır.

Yol şablonu "{controller=Home}/{action=Index}/{id?}":

  • Gibi bir URL yoluyla eşleşir /Products/Details/5

  • Yolu belirteçleştirerek yol değerlerini ayıklar { controller = Products, action = Details, id = 5 } . Uygulama adlı ProductsController bir denetleyiciye ve bir eyleme sahipse, yol değerlerinin ayıkılması eşleşmeye Details neden olur:

    public class ProductsController : Controller
    {
        public IActionResult Details(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.

  • /Products/Details/5model parametresini 5olarak ayarlamak id için değerini id = 5 bağlar. Diğer ayrıntılar için bkz . Model Bağlama .

  • {controller=Home}varsayılan controllerolarak tanımlarHome.

  • {action=Index}varsayılan actionolarak tanımlarIndex.

  • içindeki ?{id?} karakteri isteğe bağlı olarak tanımlar id .

  • Varsayılan ve isteğe bağlı yol parametrelerinin eşleşme için URL yolunda mevcut olması gerekmez. Yol şablonu söz diziminin ayrıntılı açıklaması için bkz . Yol Şablonu Başvurusu .

  • URL yolu ile eşleşir /.

  • Yol değerlerini üretir { controller = Home, action = Index }.

için değerler controller ve action varsayılan değerleri kullanır. id URL yolunda karşılık gelen bir kesim olmadığından bir değer üretmez. / yalnızca bir HomeController ve Index eylemi varsa eşleşir:

public class HomeController : Controller
{
  public IActionResult Index() { ... }
}

Yukarıdaki denetleyici tanımı ve yol şablonu kullanılarak, HomeController.Index eylem aşağıdaki URL yolları için çalıştırılır:

  • /Home/Index/17
  • /Home/Index
  • /Home
  • /

URL yolu / , rota şablonu varsayılan Home denetleyicilerini ve Index eylemini kullanır. URL yolu /Home , rota şablonu varsayılan Index eylemini kullanır.

Kolaylık yöntemi MapDefaultControllerRoute:

endpoints.MapDefaultControllerRoute();

Değiştirir:

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

Önemli

Yönlendirme, , MapControllerRouteve MapAreaControllerRoute ara yazılımı kullanılarak UseRoutingyapılandırılır. Denetleyicileri kullanmak için:

Geleneksel yönlendirme

Geleneksel yönlendirme, denetleyiciler ve görünümlerle kullanılır. Yol default :

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

Yukarıdaki örnek, geleneksel bir rota örneğidir. URL yolları için bir kural oluşturduğundan buna geleneksel yönlendirme adı verilir:

  • İlk yol kesimi olan {controller=Home}, denetleyici adıyla eşler.
  • İkinci segment olan {action=Index}, eylem adıyla eşler.
  • Üçüncü segment, {id?} isteğe bağlı idbir için kullanılır. in ?{id?} bunu isteğe bağlı hale getirir. id bir model varlığıyla eşlemek için kullanılır.

Bu default yolu kullanarak URL yolu:

  • /Products/List eylemiyle eşler ProductsController.List .
  • /Blog/Article/17BlogController.Article eşler ve genellikle model parametresini id 17'ye bağlar.

Bu eşleme:

  • Yalnızca denetleyiciyi ve eylem adlarını temel alır.
  • Ad alanları, kaynak dosya konumları veya yöntem parametreleri temel alınamaz.

Geleneksel yönlendirmeyi varsayılan yol ile kullanmak, her eylem için yeni bir URL düzeni oluşturmak zorunda kalmadan uygulamanın oluşturulmasına olanak tanır. CRUD stili eylemleri olan bir uygulama için, denetleyiciler arasında URL'ler için tutarlılık sağlar:

  • Kodu basitleştirmeye yardımcı olur.
  • Kullanıcı arabirimini daha öngörülebilir hale getirir.

Uyarı

id Yukarıdaki koddaki, yol şablonu tarafından isteğe bağlı olarak tanımlanır. Eylemler, URL'nin parçası olarak sağlanan isteğe bağlı kimlik olmadan yürütülebilir. Genellikle URL'den atlandığında id :

  • id , model bağlamasına 0 göre olarak ayarlanır.
  • veritabanında eşleşen id == 0varlık bulunamadı.

Öznitelik yönlendirmesi , bazı eylemler için gerekli kimlikleri yapmak için ayrıntılı denetim sağlar ve diğerleri için gerekli değildir. Kural gereği, belgelerde doğru kullanımda görünme olasılıkları gibi id isteğe bağlı parametreler bulunur.

Çoğu uygulama, URL'lerin okunabilir ve anlamlı olması için temel ve açıklayıcı bir yönlendirme düzeni seçmelidir. Varsayılan geleneksel yol {controller=Home}/{action=Index}/{id?}:

  • Temel ve açıklayıcı bir yönlendirme düzenini destekler.
  • Kullanıcı arabirimi tabanlı uygulamalar için yararlı bir başlangıç noktasıdır.
  • Birçok web kullanıcı arabirimi uygulaması için gereken tek yol şablonudur. Daha büyük web kullanıcı arabirimi uygulamaları için, Alanlar'ı kullanan başka bir yol genellikle gereken tek yoldur.

MapControllerRoute ve MapAreaRoute :

  • Çağrıldıkları sırayla uç noktalarına otomatik olarak bir sipariş değeri atayın.

ASP.NET Core 3.0 ve sonraki sürümlerde uç nokta yönlendirme:

  • Rota kavramı yoktur.
  • Genişletilebilirlik yürütme için sipariş garantisi sağlamaz, tüm uç noktalar aynı anda işlenir.

gibi Routeyerleşik yönlendirme uygulamalarının istekleri nasıl eşleştirdiğini görmek için Günlüğü etkinleştirin.

Öznitelik yönlendirmesi bu belgenin ilerleyen bölümlerinde açıklanmıştır.

Birden çok geleneksel rota

ve MapAreaControllerRouteöğesine daha fazla çağrı MapControllerRoute eklenerek içine UseEndpoints birden çok geleneksel yol eklenebilir. Bunu yapmak birden çok kural tanımlamaya veya belirli bir eyleme ayrılmış geleneksel yollar eklemeye olanak tanır, örneğin:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(name: "blog",
                pattern: "blog/{*article}",
                defaults: new { controller = "Blog", action = "Article" });
    endpoints.MapControllerRoute(name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
});

blog Yukarıdaki koddaki yol, ayrılmış bir geleneksel yoldur. Buna ayrılmış geleneksel yol denir çünkü:

Çünkü controller ve action rota şablonunda "blog/{*article}" parametre olarak görünmez:

  • Yalnızca varsayılan değerlerine { controller = "Blog", action = "Article" }sahip olabilirler.
  • Bu yol her zaman eylemiyle BlogController.Articleeşler.

/Blog, /Blog/Articleve /Blog/{any-string} blog yoluyla eşleşen tek URL yollarıdır.

Yukarıdaki örnek:

Uyarı

ASP.NET Core 3.0 ve sonraki sürümlerinde yönlendirme şunları yapmaz:

  • Yol olarak adlandırılan bir kavram tanımlayın. UseRouting ara yazılım işlem hattına yol eşleştirmesi ekler. Ara UseRouting yazılım, uygulamada tanımlanan uç nokta kümesine bakar ve isteğe göre en iyi uç nokta eşleşmesini seçer.
  • veya IActionConstraintgibi IRouteConstraint genişletilebilirlik yürütme sırası hakkında garantiler sağlar.

Yönlendirme hakkında başvuru malzemesi için bkz. Yönlendirme.

Geleneksel yönlendirme sırası

Geleneksel yönlendirme yalnızca uygulama tarafından tanımlanan eylem ve denetleyici birleşimiyle eşleşir. Bu, geleneksel yolların çakıştığı durumları basitleştirmeye yöneliktir. kullanarak MapControllerRouteMapDefaultControllerRouteyollar ekleyin ve MapAreaControllerRoute çağrıldıkları sırayla uç noktalarına otomatik olarak bir sipariş değeri atayın. Daha önce görünen bir yoldan gelen eşleşmelerin önceliği daha yüksektir. Geleneksel yönlendirme, siparişe bağlıdır. Genel olarak, alanları olan yollar, alanı olmayan rotalara göre daha belirgin olduğundan daha erken yerleştirilmelidir. Gibi {*article} tümünü yakala rota parametrelerine sahip ayrılmış geleneksel yollar, bir yolu çok doyumsuz hale getirir; başka bir deyişle, diğer yollar tarafından eşleşmesini istediğiniz URL'lerle eşleşir. Doyumsuz eşleşmeleri önlemek için doyumsuz yolları daha sonra yol tablosuna yerleştirin.

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.

Belirsiz eylemleri çözme

yönlendirme aracılığıyla iki uç nokta eşleştiğinde, yönlendirme aşağıdakilerden birini yapmalıdır:

  • En iyi adayı seçin.
  • Özel durum oluşturma.

Örneğin:

    public class Products33Controller : Controller
    {
        public IActionResult Edit(int id)
        {
            return ControllerContext.MyDisplayRouteInfo(id);
        }

        [HttpPost]
        public IActionResult Edit(int id, Product product)
        {
            return ControllerContext.MyDisplayRouteInfo(id, product.name);
        }
    }
}

Yukarıdaki denetleyici, eşleşen iki eylemi tanımlar:

  • URL yolu /Products33/Edit/17
  • Yönlendirme verileri { controller = Products33, action = Edit, id = 17 }.

Bu, MVC denetleyicileri için tipik bir desendir:

  • Edit(int) bir ürünü düzenlemek için bir form görüntüler.
  • Edit(int, Product) deftere nakledilmiş formu işler.

Doğru yolu çözümlemek için:

  • Edit(int, Product) , istek bir HTTP POSTolduğunda seçilir.
  • Edit(int), HTTP fiili başka bir şey olduğunda seçilir. Edit(int) genellikle aracılığıyla çağrılır GET.

HttpPostAttribute, , [HttpPost]isteğin HTTP yöntemine göre seçebilmesi için yönlendirmeye sağlanır. , HttpPostAttribute değerinden Edit(int)daha iyi bir eşleşme sağlarEdit(int, Product).

gibi HttpPostAttributeözniteliklerin rolünü anlamak önemlidir. Diğer HTTP fiilleri için benzer öznitelikler tanımlanır. Geleneksel yönlendirmede, eylemlerin bir gösteri formunun parçası olan form gönderme formu iş akışının parçası olduğunda aynı eylem adını kullanması yaygındır. Örneğin, bkz . İki Düzenleme eylemi yöntemini inceleme.

Yönlendirme en iyi adayı seçemiyorsa, birden çok eşleşen uç nokta listeleyerek bir AmbiguousMatchException oluşturulur.

Geleneksel yol adları

Dizeler "blog" ve "default" aşağıdaki örneklerde geleneksel yol adları verilmiştir:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(name: "blog",
                pattern: "blog/{*article}",
                defaults: new { controller = "Blog", action = "Article" });
    endpoints.MapControllerRoute(name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
});

Yol adları, yola mantıksal bir ad verir. Adlandırılmış yol, URL oluşturma için kullanılabilir. Adlandırılmış yol kullanmak, yolların sıralanması URL oluşturmayı karmaşık hale getirebileceğinden URL oluşturmayı kolaylaştırır. Yol adları, uygulama genelinde benzersiz olmalıdır.

Yol adları:

  • URL eşleştirme veya istekleri işleme üzerinde hiçbir etkisi yoktur.
  • Yalnızca URL oluşturma için kullanılır.

Yol adı kavramı, yönlendirmede IEndpointNameMetadata olarak temsil edilir. Yol adı ve uç nokta adı terimleri:

  • Bunlar birbirinin yerine kullanılabilir.
  • Belgelerde ve kodlarda hangisinin kullanıldığı, açıklanan API'ye bağlıdır.

API'ler için REST öznitelik yönlendirme

RESTAPI'ler, işlemlerin HTTP fiilleri ile temsil edildiği bir kaynak kümesi olarak uygulamanın işlevselliğini modellemek için öznitelik yönlendirmesini kullanmalıdır.

Öznitelik yönlendirme, eylemleri doğrudan yol şablonlarıyla eşlemek için bir dizi öznitelik kullanır. Aşağıdaki StartUp.Configure kod bir REST API için tipiktir ve sonraki örnekte kullanılır:

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
}

public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseHttpsRedirection();

    app.UseRouting();

    app.UseAuthorization();

    app.UseEndpoints(endpoints =>
    {
        endpoints.MapControllers();
    });
}

Yukarıdaki kodda, MapControllers öznitelik yönlendirilmiş denetleyicilerini eşlemek için içinde UseEndpoints çağrılır.

Aşağıdaki örnekte:

  • HomeController , varsayılan geleneksel yolun {controller=Home}/{action=Index}/{id?} eşlediği url'lere benzer bir URL kümesiyle eşleşir.
public class HomeController : Controller
{
    [Route("")]
    [Route("Home")]
    [Route("Home/Index")]
    [Route("Home/Index/{id?}")]
    public IActionResult Index(int? id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }

    [Route("Home/About")]
    [Route("Home/About/{id?}")]
    public IActionResult About(int? id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

EylemHomeController.Index, , /Home/Home/Indexveya /Home/Index/3URL yollarından /herhangi biri için çalıştırılır.

Bu örnek, öznitelik yönlendirmesi ile geleneksel yönlendirme arasındaki temel programlama farkını vurgular. Öznitelik yönlendirmesi, yol belirtmek için daha fazla giriş gerektirir. Geleneksel varsayılan yol, yolları daha kısa işler. Ancak, öznitelik yönlendirmesi her eylem için hangi yol şablonlarının geçerli olduğunu hassas bir şekilde denetlemenizi sağlar ve gerektirir.

Öznitelik yönlendirme ile, belirteç değiştirme kullanılmadığı sürece denetleyici ve eylem adları eylemin eşleştirildiği bir rol oynamaz. Aşağıdaki örnek, önceki örnekle aynı URL'ler ile eşleşir:

public class MyDemoController : Controller
{
    [Route("")]
    [Route("Home")]
    [Route("Home/Index")]
    [Route("Home/Index/{id?}")]
    public IActionResult MyIndex(int? id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }

    [Route("Home/About")]
    [Route("Home/About/{id?}")]
    public IActionResult MyAbout(int? id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Aşağıdaki kod ve controlleriçin action belirteç değişimini kullanır:

public class HomeController : Controller
{
    [Route("")]
    [Route("Home")]
    [Route("[controller]/[action]")]
    public IActionResult Index()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    [Route("[controller]/[action]")]
    public IActionResult About()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

Aşağıdaki kod denetleyici için geçerlidir [Route("[controller]/[action]")] :

[Route("[controller]/[action]")]
public class HomeController : Controller
{
    [Route("~/")]
    [Route("/Home")]
    [Route("~/Home/Index")]
    public IActionResult Index()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    public IActionResult About()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

Yukarıdaki kodda, yöntem şablonlarının Index yol şablonlarına önceden / eklenmesi veya ~/ bu şablonlara eklenmesi gerekir. Bir eyleme / uygulanan ve denetleyiciye uygulanan yönlendirme şablonlarıyla birleştirilen veya ~/ olmayan yol şablonları.

Rota şablonu seçimi hakkında bilgi için bkz . Yol şablonu önceliği .

Ayrılmış yönlendirme adları

Denetleyiciler veya Razor Sayfalar kullanılırken aşağıdaki anahtar sözcükler ayrılmış yol parametre adlarıdır:

  • action
  • area
  • controller
  • handler
  • page

Öznitelik yönlendirme ile yol parametresi olarak kullanmak page yaygın bir hatadır. Bunun yapılması, URL oluşturma ile tutarsız ve kafa karıştırıcı davranışlara neden olur.

public class MyDemo2Controller : Controller
{
    [Route("/articles/{page}")]
    public IActionResult ListArticles(int page)
    {
        return ControllerContext.MyDisplayRouteInfo(page);
    }
}

Özel parametre adları, URL oluşturma işleminin Sayfaya mı yoksa Denetleyiciye Razor mi başvurduğuna karar vermek için URL oluşturma tarafından kullanılır.

Aşağıdaki anahtar sözcükler bir Razor görünüm veya Razor Sayfa bağlamında ayrılmıştır:

  • page
  • using
  • namespace
  • inject
  • section
  • inherits
  • model
  • addTagHelper
  • removeTagHelper

Bu anahtar sözcükler bağlantı nesilleri, modele bağlı parametreler veya en üst düzey özellikler için kullanılmamalıdır.

HTTP fiil şablonları

ASP.NET Core aşağıdaki HTTP fiili şablonlarına sahiptir:

Yol şablonları

ASP.NET Core aşağıdaki yol şablonlarına sahiptir:

Http fiili öznitelikleriyle öznitelik yönlendirme

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

[Route("api/[controller]")]
[ApiController]
public class Test2Controller : ControllerBase
{
    [HttpGet]   // GET /api/test2
    public IActionResult ListProducts()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    [HttpGet("{id}")]   // GET /api/test2/xyz
    public IActionResult GetProduct(string id)
    {
       return ControllerContext.MyDisplayRouteInfo(id);
    }

    [HttpGet("int/{id:int}")] // GET /api/test2/int/3
    public IActionResult GetIntProduct(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }

    [HttpGet("int2/{id}")]  // GET /api/test2/int2/3
    public IActionResult GetInt2Product(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Önceki kodda:

  • Her eylem, yalnızca HTTP GET istekleriyle eşleşen özniteliğini içerir [HttpGet] .
  • Eylem GetProduct şablonu içerir "{id}" , bu nedenle id denetleyicideki "api/[controller]" şablona eklenir. Yöntem şablonu şeklindedir "api/[controller]/{id}". Bu nedenle bu eylem yalnızca ,/api/test2/123/api/test2/{any string} vb. formu /api/test2/xyziçin GET istekleriyle eşleşir.
    [HttpGet("{id}")]   // GET /api/test2/xyz
    public IActionResult GetProduct(string id)
    {
       return ControllerContext.MyDisplayRouteInfo(id);
    }
    
  • Eylem GetIntProduct şablonu içerir "int/{id:int}" . Şablonun :int bölümü, yol değerlerini tamsayıya dönüştürülebilecek dizelerle kısıtlar id . için bir /api/test2/int/abcGET isteği:
    • Bu eylemle eşleşmiyor.
    • 404 Bulunamadı hatası döndürür.
      [HttpGet("int/{id:int}")] // GET /api/test2/int/3
      public IActionResult GetIntProduct(int id)
      {
          return ControllerContext.MyDisplayRouteInfo(id);
      }
      
  • Eylem GetInt2Product şablonda yer alır {id} , ancak tamsayıya dönüştürülebilecek değerlerle kısıtlamaz id . için bir /api/test2/int2/abcGET isteği:
    • Bu rotayla eşleşir.
    • Model bağlaması tamsayıya dönüştürülemiyor abc . id yönteminin parametresi tamsayıdır.
    • Model bağlaması tamsayıya dönüştürülemediği abc için 400 Hatalı İstek döndürür.
      [HttpGet("int2/{id}")]  // GET /api/test2/int2/3
      public IActionResult GetInt2Product(int id)
      {
          return ControllerContext.MyDisplayRouteInfo(id);
      }
      

Öznitelik yönlendirme, , HttpPutAttributeve HttpDeleteAttributegibi HttpPostAttributeöznitelikleri kullanabilirHttpMethodAttribute. Tüm HTTP fiil öznitelikleri bir yol şablonu kabul eder. Aşağıdaki örnekte aynı yol şablonuyla eşleşen iki eylem gösterilmektedir:

[ApiController]
public class MyProductsController : ControllerBase
{
    [HttpGet("/products3")]
    public IActionResult ListProducts()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    [HttpPost("/products3")]
    public IActionResult CreateProduct(MyProduct myProduct)
    {
        return ControllerContext.MyDisplayRouteInfo(myProduct.Name);
    }
}

URL yolunu /products3kullanma:

  • EYLEM, MyProductsController.ListProducts HTTP fiili olduğunda GETçalışır.
  • EYLEM, MyProductsController.CreateProduct HTTP fiili olduğunda POSTçalışır.

API REST oluştururken, eylem tüm HTTP yöntemlerini kabul ettiğinden eylem yönteminde kullanmanız [Route(...)] çok nadirdir. API'nizin neleri desteklediği konusunda kesin olmak için daha belirli HTTP fiil özniteliğini kullanmak daha iyidir. API'lerin istemcilerinin hangi yolların REST ve HTTP fiillerinin belirli mantıksal işlemlerle eşlenip eşlenemli olduğunu bilmesi beklenir.

REST API'ler, işlemlerin HTTP fiilleri ile temsil edildiği bir kaynak kümesi olarak uygulamanın işlevselliğini modellemek için öznitelik yönlendirmesini kullanmalıdır. Bu, aynı mantıksal kaynakta GET ve POST gibi birçok işlemin aynı URL'yi kullandığı anlamına gelir. Öznitelik yönlendirme, BIR API'nin genel uç nokta düzenini dikkatle tasarlamak için gereken bir denetim düzeyi sağlar.

Öznitelik yolu belirli bir eyleme uygulandığından, yol şablonu tanımının bir parçası olarak gerekli parametreleri yapmak kolaydır. Aşağıdaki örnekte, id URL yolunun bir parçası olarak gereklidir:

[ApiController]
public class Products2ApiController : ControllerBase
{
    [HttpGet("/products2/{id}", Name = "Products_List")]
    public IActionResult GetProduct(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Eylem Products2ApiController.GetProduct(int) :

  • gibi URL yolu ile çalıştırılır /products2/3
  • URL yolu /products2ile çalıştırılmıyor.

[Consumes] özniteliği, desteklenen istek içerik türlerini sınırlamak için bir eyleme izin verir. Daha fazla bilgi için bkz . Consumes özniteliğiyle desteklenen istek içerik türlerini tanımlama.

Rota şablonlarının ve ilgili seçeneklerin tam açıklaması için bkz . Yönlendirme .

hakkında [ApiController]daha fazla bilgi için bkz . ApiController özniteliği.

Yönlendirme adı

Aşağıdaki kod, yolunun Products_Listadını tanımlar:

[ApiController]
public class Products2ApiController : ControllerBase
{
    [HttpGet("/products2/{id}", Name = "Products_List")]
    public IActionResult GetProduct(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Yol adları, belirli bir yolu temel alan bir URL oluşturmak için kullanılabilir. Yol adları:

  • Yönlendirmenin URL eşleştirme davranışı üzerinde hiçbir etkisi yoktur.
  • Yalnızca URL oluşturma için kullanılır.

Yol adları uygulama genelinde benzersiz olmalıdır.

Yukarıdaki kodu, parametresini isteğe bağlı ({id?}) olarak tanımlayan id geleneksel varsayılan yolla karşıtlık yapın. API'leri tam olarak belirtebilme özelliği, farklı eylemlere izin verme /products ve /products/5 gönderme gibi avantajlara sahiptir.

Öznitelik yollarını birleştirme

Öznitelik yönlendirmesini daha az yinelenen hale getirmek için, denetleyicideki yol öznitelikleri tek tek eylemlerdeki yol öznitelikleriyle birleştirilir. Denetleyicide tanımlanan tüm yol şablonları, eylemlerdeki yol şablonlarına eklenir. Denetleyiciye bir yol özniteliği yerleştirmek, denetleyicideki tüm eylemlerin öznitelik yönlendirmesini kullanmasını sağlar.

[ApiController]
[Route("products")]
public class ProductsApiController : ControllerBase
{
    [HttpGet]
    public IActionResult ListProducts()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    [HttpGet("{id}")]
    public IActionResult GetProduct(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Yukarıdaki örnekte:

  • URL yolu /products eşleşebilir ProductsApi.ListProducts
  • URL yolu /products/5 ile eşleşebilir ProductsApi.GetProduct(int).

Bu eylemlerin her ikisi de özniteliğiyle işaretlendiğinden [HttpGet] yalnızca HTTP GET ile eşleşer.

Bir eyleme / uygulanan ve denetleyiciye uygulanan yönlendirme şablonlarıyla birleştirilen veya ~/ olmayan yol şablonları. Aşağıdaki örnek, varsayılan yola benzer bir URL yolu kümesiyle eşleşir.

[Route("Home")]
public class HomeController : Controller
{
    [Route("")]
    [Route("Index")]
    [Route("/")]
    public IActionResult Index()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    [Route("About")]
    public IActionResult About()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

Aşağıdaki tabloda, önceki koddaki öznitelikler açıklanmaktadır [Route] :

Öznitelik ile birleştirilir [Route("Home")] Yol şablonunu tanımlar
[Route("")] Yes "Home"
[Route("Index")] Evet "Home/Index"
[Route("/")] Hayır ""
[Route("About")] Evet "Home/About"

Öznitelik rota sırası

Yönlendirme bir ağaç oluşturur ve tüm uç noktaları aynı anda eşleştirir:

  • Yol girişleri ideal bir sıralamada yerleştirilmiş gibi davranır.
  • En belirli yolların daha genel yollardan önce yürütme şansı vardır.

Örneğin, gibi bir öznitelik yolu gibi blog/search/{topic}blog/{*article}bir öznitelik yolundan daha belirgindir. Rota blog/search/{topic} daha belirgin olduğundan varsayılan olarak daha yüksek önceliğe sahiptir. Geleneksel yönlendirmeyi kullanarak, rotaları istenen sırada yerleştirmek geliştiricinin sorumluluğundadır.

Öznitelik yolları özelliğini kullanarak Order bir sıra yapılandırabilir. Sağlanan tüm çerçeve yol öznitelikleri içerir Order . Yollar, özelliğin artan bir türüne Order göre işlenir. Varsayılan sıra şeklindedir 0. Bir düzeni ayarlamamış rotalardan Order = -1 önce çalıştırarak rota ayarlama. Varsayılan yol sıralamadan sonra çalıştırarak Order = 1 bir yol ayarlama.

öğesine bağlı Orderolarak kullanmaktan kaçının. Bir uygulamanın URL alanı doğru yönlendirmek için açık sipariş değerleri gerektiriyorsa, istemciler için de kafa karıştırıcı olabilir. Genel olarak, öznitelik yönlendirme url eşleştirme ile doğru yolu seçer. URL oluşturma için kullanılan varsayılan sıra çalışmıyorsa, geçersiz kılma olarak yol adı kullanmak genellikle özelliğin Order uygulanmasından daha basittir.

Her ikisinin de yol eşleştirmesini /hometanımlayan aşağıdaki iki denetleyiciyi göz önünde bulundurun:

public class HomeController : Controller
{
    [Route("")]
    [Route("Home")]
    [Route("Home/Index")]
    [Route("Home/Index/{id?}")]
    public IActionResult Index(int? id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }

    [Route("Home/About")]
    [Route("Home/About/{id?}")]
    public IActionResult About(int? id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}
public class MyDemoController : Controller
{
    [Route("")]
    [Route("Home")]
    [Route("Home/Index")]
    [Route("Home/Index/{id?}")]
    public IActionResult MyIndex(int? id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }

    [Route("Home/About")]
    [Route("Home/About/{id?}")]
    public IActionResult MyAbout(int? id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

/home Yukarıdaki kodla istekte bulunmak aşağıdakine benzer bir özel durum oluşturur:

AmbiguousMatchException: The request matched multiple endpoints. Matches:

 WebMvcRouting.Controllers.HomeController.Index
 WebMvcRouting.Controllers.MyDemoController.MyIndex

Yol özniteliklerinden birine eklendiğinde Order belirsizlik çözülür:

[Route("")]
[Route("Home", Order = 2)]
[Route("Home/MyIndex")]
public IActionResult MyIndex()
{
    return ControllerContext.MyDisplayRouteInfo();
}

Yukarıdaki kodla uç /home noktayı çalıştırır HomeController.Index . adresine ulaşmak için MyDemoController.MyIndexisteğinde bulunın /home/MyIndex. Not:

  • Yukarıdaki kod bir örnek veya kötü yönlendirme tasarımıdır. Özelliği göstermek için kullanılmıştır Order .
  • Order özelliği yalnızca belirsizliği giderir, bu şablon eşleştirilemez. Şablonu kaldırmak [Route("Home")] daha iyi olur.

Sayfalar rotası ve uygulama kuralları: Sayfalar ile Razor yönlendirme sırası hakkında bilgi için bkzRazor. Yönlendirme sırası.

Bazı durumlarda, belirsiz yollar içeren bir HTTP 500 hatası döndürülür. hangi uç noktaların neden olduğunu görmek için günlüğe kaydetmeyiAmbiguousMatchExceptionkullanın.

Yol şablonlarında belirteç değiştirme [denetleyici], [eylem], [alan]

Kolaylık sağlamak için öznitelik yolları, bir belirteci köşeli ayraç içine alarak belirtecin değiştirilmesini destekler ([, ]). , [area]ve [controller] belirteçleri[action], yolun tanımlandığı eylemdeki eylem adı, alan adı ve denetleyici adı değerleriyle değiştirilir:

[Route("[controller]/[action]")]
public class Products0Controller : Controller
{
    [HttpGet]
    public IActionResult List()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }


    [HttpGet("{id}")]
    public IActionResult Edit(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Önceki kodda:

[HttpGet]
public IActionResult List()
{
    return ControllerContext.MyDisplayRouteInfo();
}
  • Eşleşen /Products0/List
[HttpGet("{id}")]
public IActionResult Edit(int id)
{
    return ControllerContext.MyDisplayRouteInfo(id);
}
  • Eşleşen /Products0/Edit/{id}

Belirteç değiştirme, öznitelik yollarını oluşturmanın son adımı olarak gerçekleşir. Yukarıdaki örnek aşağıdaki kodla aynı şekilde davranır:

public class Products20Controller : Controller
{
    [HttpGet("[controller]/[action]")]  // Matches '/Products20/List'
    public IActionResult List()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    [HttpGet("[controller]/[action]/{id}")]   // Matches '/Products20/Edit/{id}'
    public IActionResult Edit(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Bunu İngilizce dışında bir dilde okuyorsanız, kod açıklamalarını ana dilinizde görmek isterseniz bu GitHub tartışma sorununda bize bildirin.

Öznitelik yolları devralma ile de birleştirilebilir. Bu, belirteç değiştirme ile birlikte güçlüdür. Belirteç değiştirme, öznitelik yolları tarafından tanımlanan yol adları için de geçerlidir. [Route("[controller]/[action]", Name="[controller]_[action]")]her eylem için benzersiz bir yol adı oluşturur:

[ApiController]
[Route("api/[controller]/[action]", Name = "[controller]_[action]")]
public abstract class MyBase2Controller : ControllerBase
{
}

public class Products11Controller : MyBase2Controller
{
    [HttpGet]                      // /api/products11/list
    public IActionResult List()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

    [HttpGet("{id}")]             //    /api/products11/edit/3
    public IActionResult Edit(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Değişmez değer belirteci değiştirme sınırlayıcısı [ veya ]ile eşleştirmek için karakteri ([[ veya ]]) yineleyerek bu sınırlayıcıdan kaçın.

Belirteç değişimini özelleştirmek için parametre transformatörü kullanma

Belirteç değiştirme, bir parametre transformatörü kullanılarak özelleştirilebilir. Parametre transformatörü parametrelerin IOutboundParameterTransformer değerini uygular ve dönüştürür. Örneğin, özel SlugifyParameterTransformer parametre transformatörü yol değerini olarak subscription-managementdeğiştirirSubscriptionManagement:

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

RouteTokenTransformerConvention, aşağıdakilere sahip bir uygulama modeli kuralıdır:

  • Bir uygulamadaki tüm öznitelik yollarına bir parametre transformatörü uygular.
  • Öznitelik yol belirteci değerlerini değiştirildiğinde özelleştirir.
public class SubscriptionManagementController : Controller
{
    [HttpGet("[controller]/[action]")]
    public IActionResult ListAll()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

Yukarıdaki ListAll yöntem ile eşleşir /subscription-management/list-all.

RouteTokenTransformerConvention, içinde ConfigureServicesbir seçenek olarak kaydedilir.

public void ConfigureServices(IServiceCollection services)
{
    services.AddControllersWithViews(options =>
    {
        options.Conventions.Add(new RouteTokenTransformerConvention(
                                     new SlugifyParameterTransformer()));
    });
}

Slug'ın tanımı için bkz . Slug üzerinde MDN web belgeleri.

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.

Birden çok öznitelik yolu

Öznitelik yönlendirme, aynı eyleme ulaşan birden çok yol tanımlamayı destekler. Bunun en yaygın kullanımı, aşağıdaki örnekte gösterildiği gibi varsayılan geleneksel yolun davranışını taklit etmektir:

[Route("[controller]")]
public class Products13Controller : Controller
{
    [Route("")]     // Matches 'Products13'
    [Route("Index")] // Matches 'Products13/Index'
    public IActionResult Index()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

Denetleyiciye birden çok yol özniteliği koymak, her birinin eylem yöntemlerindeki yol özniteliklerinin her biriyle birleştirilmesi anlamına gelir:

[Route("Store")]
[Route("[controller]")]
public class Products6Controller : Controller
{
    [HttpPost("Buy")]       // Matches 'Products6/Buy' and 'Store/Buy'
    [HttpPost("Checkout")]  // Matches 'Products6/Checkout' and 'Store/Checkout'
    public IActionResult Buy()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

Tüm HTTP fiil yolu kısıtlamaları uygularIActionConstraint.

Uygulayan IActionConstraint birden çok yol özniteliği bir eyleme yerleştirildiğinde:

  • Her eylem kısıtlaması, denetleyiciye uygulanan yol şablonuyla birleştirilir.
[Route("api/[controller]")]
public class Products7Controller : ControllerBase
{
    [HttpPut("Buy")]        // Matches PUT 'api/Products7/Buy'
    [HttpPost("Checkout")]  // Matches POST 'api/Products7/Checkout'
    public IActionResult Buy()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

Eylemlerde birden çok yol kullanmak yararlı ve güçlü görünebilir; uygulamanızın URL alanını temel ve iyi tanımlanmış olarak tutmak daha iyidir. Eylemlerde yalnızca gerektiğinde, örneğin mevcut istemcileri desteklemek için birden çok yol kullanın.

Öznitelik yolu isteğe bağlı parametreleri, varsayılan değerleri ve kısıtlamaları belirtme

Öznitelik yolları isteğe bağlı parametreleri, varsayılan değerleri ve kısıtlamaları belirtmek için geleneksel yollar ile aynı satır içi söz dizimini destekler.

public class Products14Controller : Controller
{
    [HttpPost("product14/{id:int}")]
    public IActionResult ShowProduct(int id)
    {
        return ControllerContext.MyDisplayRouteInfo(id);
    }
}

Yukarıdaki kodda bir [HttpPost("product14/{id:int}")] yol kısıtlaması uygular. Eylem Products14Controller.ShowProduct yalnızca gibi /product14/3URL yollarıyla eşleştirilir. Yol şablonu bölümü {id:int} , bu segmenti yalnızca tamsayılarla kısıtlar.

Yol şablonu söz diziminin ayrıntılı açıklaması için bkz . Yol Şablonu Başvurusu .

IRouteTemplateProvider kullanan özel yol öznitelikleri

Tüm yol öznitelikleri uygularIRouteTemplateProvider. ASP.NET Core çalışma zamanı:

  • Uygulama başlatıldığında denetleyici sınıflarında ve eylem yöntemlerinde öznitelikleri arar.
  • İlk yol kümesini oluşturmak için uygulayan IRouteTemplateProvider öznitelikleri kullanır.

Özel yol özniteliklerini tanımlamak için uygulayın IRouteTemplateProvider . Her IRouteTemplateProvider bir özel yol şablonu, sırası ve adıyla tek bir yol tanımlamanızı sağlar:

public class MyApiControllerAttribute : Attribute, IRouteTemplateProvider
{
    public string Template => "api/[controller]";
    public int? Order => 2;
    public string Name { get; set; }
}

[MyApiController]
[ApiController]
public class MyTestApiController : ControllerBase
{
    // GET /api/MyTestApi
    [HttpGet]
    public IActionResult Get()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

Yukarıdaki Get yöntem döndürür Order = 2, Template = api/MyTestApi.

Öznitelik yollarını özelleştirmek için uygulama modelini kullanma

Uygulama modeli:

  • Başlangıçta oluşturulan bir nesne modelidir.
  • bir uygulamada eylemleri yönlendirmek ve yürütmek için ASP.NET Core tarafından kullanılan tüm meta verileri içerir.

Uygulama modeli, yol özniteliklerinden toplanan tüm verileri içerir. Yol özniteliklerindeki veriler uygulama tarafından IRouteTemplateProvider sağlanır. Kural -ları:

  • Yönlendirmenin davranışını özelleştirmek için uygulama modelini değiştirmek için yazılabilir.
  • Uygulama başlangıcında okunur.

Bu bölümde, uygulama modelini kullanarak yönlendirmeyi özelleştirmeye yönelik temel bir örnek gösterilmektedir. Aşağıdaki kod, yolları kabaca projenin klasör yapısıyla hizalar.

public class NamespaceRoutingConvention : Attribute, IControllerModelConvention
{
    private readonly string _baseNamespace;

    public NamespaceRoutingConvention(string baseNamespace)
    {
        _baseNamespace = baseNamespace;
    }

    public void Apply(ControllerModel controller)
    {
        var hasRouteAttributes = controller.Selectors.Any(selector =>
                                                selector.AttributeRouteModel != null);
        if (hasRouteAttributes)
        {
            return;
        }

        var namespc = controller.ControllerType.Namespace;
        if (namespc == null)
            return;
        var template = new StringBuilder();
        template.Append(namespc, _baseNamespace.Length + 1,
                        namespc.Length - _baseNamespace.Length - 1);
        template.Replace('.', '/');
        template.Append("/[controller]/[action]/{id?}");

        foreach (var selector in controller.Selectors)
        {
            selector.AttributeRouteModel = new AttributeRouteModel()
            {
                Template = template.ToString()
            };
        }
    }
}

Aşağıdaki kod, kuralın namespace yönlendirilen öznitelik denetleyicilerine uygulanmasını engeller:

public void Apply(ControllerModel controller)
{
    var hasRouteAttributes = controller.Selectors.Any(selector =>
                                            selector.AttributeRouteModel != null);
    if (hasRouteAttributes)
    {
        return;
    }

Örneğin, aşağıdaki denetleyici şunu kullanmaz NamespaceRoutingConvention:

[Route("[controller]/[action]/{id?}")]
public class ManagersController : Controller
{
    // /managers/index
    public IActionResult Index()
    {
        var template = ControllerContext.ActionDescriptor.AttributeRouteInfo?.Template;
        return Content($"Index- template:{template}");
    }

    public IActionResult List(int? id)
    {
        var path = Request.Path.Value;
        return Content($"List- Path:{path}");
    }
}

NamespaceRoutingConvention.Apply yöntemi:

  • Denetleyici öznitelik yönlendirildiyse hiçbir şey yapmaz.
  • temeli kaldırılmış olarak namespace denetleyiciler şablonunu temel alarak namespaceayarlar.

NamespaceRoutingConvention içinde uygulanabilirStartup.ConfigureServices:

namespace My.Application
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllersWithViews(options =>
            {
                options.Conventions.Add(
                    new NamespaceRoutingConvention(typeof(Startup).Namespace));
            });
        }
        // Remaining code ommitted for brevity.

Örneğin, aşağıdaki denetleyiciyi göz önünde bulundurun:

using Microsoft.AspNetCore.Mvc;

namespace My.Application.Admin.Controllers
{
    public class UsersController : Controller
    {
        // GET /admin/controllers/users/index
        public IActionResult Index()
        {
            var fullname = typeof(UsersController).FullName;
            var template = 
                ControllerContext.ActionDescriptor.AttributeRouteInfo?.Template;
            var path = Request.Path.Value;

            return Content($"Path: {path} fullname: {fullname}  template:{template}");
        }

        public IActionResult List(int? id)
        {
            var path = Request.Path.Value;
            return Content($"Path: {path} ID:{id}");
        }
    }
}

Önceki kodda:

  • Taban namespace şeklindedir My.Application.
  • Önceki denetleyicinin tam adı şeklindedir My.Application.Admin.Controllers.UsersController.
  • denetleyiciler NamespaceRoutingConvention şablonunu olarak Admin/Controllers/Users/[action]/{id?ayarlar.

, NamespaceRoutingConvention bir denetleyiciye öznitelik olarak da uygulanabilir:

[NamespaceRoutingConvention("My.Application")]
public class TestController : Controller
{
    // /admin/controllers/test/index
    public IActionResult Index()
    {
        var template = ControllerContext.ActionDescriptor.AttributeRouteInfo?.Template;
        var actionname = ControllerContext.ActionDescriptor.ActionName;
        return Content($"Action- {actionname} template:{template}");
    }

    public IActionResult List(int? id)
    {
        var path = Request.Path.Value;
        return Content($"List- Path:{path}");
    }
}

Karma yönlendirme: Öznitelik yönlendirmesi ile geleneksel yönlendirme karşılaştırması

ASP.NET Core uygulamaları, geleneksel yönlendirme ve öznitelik yönlendirme kullanımını karıştırabilir. Tarayıcılar için HTML sayfaları sunan denetleyiciler için geleneksel yolların ve API'leri sunan REST denetleyiciler için öznitelik yönlendirmenin kullanılması normaldir.

Eylemler geleneksel olarak yönlendirilir veya öznitelik yönlendirilir. Denetleyiciye veya eyleme bir yol yerleştirmek, bunun yönlendirilmiş özniteliğini oluşturur. Öznitelik yollarını tanımlayan eylemlere geleneksel yollar üzerinden (veya tam tersi) erişilemez. Denetleyicideki herhangi bir yol özniteliği, denetleyici özniteliğindeki tüm eylemlerin yönlendirilmiş olmasını sağlar.

Öznitelik yönlendirme ve geleneksel yönlendirme aynı yönlendirme altyapısını kullanır.

URL Oluşturma ve ortam değerleri

Uygulamalar, eylemlere URL bağlantıları oluşturmak için yönlendirme URL'si oluşturma özelliklerini kullanabilir. URL'lerin oluşturulması sabit kodlama URL'lerini ortadan kaldırarak kodu daha sağlam ve sürdürülebilir hale getirir. Bu bölüm, MVC tarafından sağlanan URL oluşturma özelliklerine odaklanır ve yalnızca URL oluşturmanın nasıl çalıştığına ilişkin temel bilgileri kapsar. URL oluşturmanın ayrıntılı açıklaması için bkz . Yönlendirme .

IUrlHelper Arabirim, MVC ile URL oluşturma için yönlendirme arasındaki altyapının temel öğesidir. örneğini IUrlHelper denetleyiciler, görünümler ve görünüm bileşenlerindeki özelliği aracılığıyla Url kullanabilirsiniz.

Aşağıdaki örnekte, IUrlHelper arabirim özelliği aracılığıyla başka bir eylemin Controller.Url URL'sini oluşturmak için kullanılır.

public class UrlGenerationController : Controller
{
    public IActionResult Source()
    {
        // Generates /UrlGeneration/Destination
        var url = Url.Action("Destination");
        return ControllerContext.MyDisplayRouteInfo("", $" URL = {url}");
    }

    public IActionResult Destination()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }
}

Uygulama varsayılan geleneksel yolu kullanıyorsa değişkeninin url değeri URL yol dizesidir /UrlGeneration/Destination. Bu URL yolu, aşağıdakiler birleştirilerek yönlendirmeyle oluşturulur:

  • Geçerli istekten gelen ve ortam değerleri olarak adlandırılan yol değerleri.
  • yol şablonuna Url.Action geçirilen ve bu değerlerin yerine geçen değerler:
ambient values: { controller = "UrlGeneration", action = "Source" }
values passed to Url.Action: { controller = "UrlGeneration", action = "Destination" }
route template: {controller}/{action}/{id?}

result: /UrlGeneration/Destination

Yol şablonundaki her yol parametresinin değeri, değerleri ve ortam değerleriyle eşleşen adlarla değiştirilir. Değeri olmayan bir yol parametresi şu şekilde olabilir:

  • Varsa varsayılan bir değer kullanın.
  • İsteğe bağlıysa atlanır. Örneğin, id rota şablonundan {controller}/{action}/{id?}.

Gerekli bir yol parametresine karşılık gelen bir değer yoksa URL oluşturma işlemi başarısız olur. URL oluşturma bir yol için başarısız olursa, tüm yollar denenene veya eşleşme bulunana kadar sonraki yol denener.

Yukarıdaki örnek, Url.Action geleneksel yönlendirmeyi varsayar. URL oluşturma, öznitelik yönlendirmede benzer şekilde çalışır ancak kavramlar farklıdır. Geleneksel yönlendirme ile:

  • Yol değerleri, şablonu genişletmek için kullanılır.
  • ve action için controller yol değerleri genellikle bu şablonda görünür. Yönlendirme tarafından eşleşen URL'ler bir kurala bağlı olduğundan bu işe yarar.

Aşağıdaki örnek öznitelik yönlendirmeyi kullanır:

public class UrlGenerationAttrController : Controller
{
    [HttpGet("custom")]
    public IActionResult Source()
    {
        var url = Url.Action("Destination");
        return ControllerContext.MyDisplayRouteInfo("", $" URL = {url}");
    }

    [HttpGet("custom/url/to/destination")]
    public IActionResult Destination()
    {
       return ControllerContext.MyDisplayRouteInfo();
    }
}

Yukarıdaki Source koddaki eylem oluşturur custom/url/to/destination.

LinkGenerator ASP.NET Core 3.0'a IUrlHelperalternatif olarak eklendi. LinkGenerator benzer ama daha esnek işlevler sunar. üzerindeki IUrlHelper her yöntemin de üzerinde karşılık gelen bir yöntem LinkGenerator ailesi vardır.

Eylem adına göre URL oluşturma

Url.Action, LinkGenerator.GetPathByAction ve tüm ilgili aşırı yüklemeler, bir denetleyici adı ve eylem adı belirterek hedef uç noktayı oluşturmak üzere tasarlanmıştır.

kullanırken Url.Actionve action için controller geçerli yol değerleri çalışma zamanı tarafından sağlanır:

  • ve action değeri controller hem ortam değerlerinin hem de değerlerin bir parçasıdır. yöntemi Url.Action her zaman geçerli ve controller değerlerini action kullanır ve geçerli eyleme yönlendiren bir URL yolu oluşturur.

Yönlendirme, bir URL oluşturulurken sağlanmayan bilgileri doldurmak için ortam değerlerindeki değerleri kullanmayı dener. Ortam değerleriyle { a = Alice, b = Bob, c = Carol, d = David }gibi {a}/{b}/{c}/{d} bir yol düşünün:

  • Yönlendirme, ek değer içermeyen bir URL oluşturmak için yeterli bilgiye sahiptir.
  • Tüm yol parametrelerinin bir değeri olduğundan yönlendirme yeterli bilgiye sahiptir.

Değer { d = Donovan } eklenirse:

  • Değer { d = David } yoksayılır.
  • Oluşturulan URL yolu şeklindedir Alice/Bob/Carol/Donovan.

Uyarı: URL yolları hiyerarşiktir. Yukarıdaki örnekte, değer { c = Cheryl } eklenirse:

  • Her iki değer { c = Carol, d = David } de yoksayılır.
  • artık için d bir değer yok ve URL oluşturma başarısız oluyor.
  • URL oluşturmak için istenen ve d değerleri c belirtilmelidir.

Bu soruna varsayılan yoluyla {controller}/{action}/{id?}ulaşmayı bekleyebilirsiniz. Her zaman bir controller ve action değerini açıkça belirttiği için Url.Action bu sorun pratikte nadir görülür.

Url.Action'ın çeşitli aşırı yüklemeleri, ve actiondışındaki controller yol parametreleri için değerler sağlamak üzere bir yol değerleri nesnesi alır. Yol değerleri nesnesi ile idsık sık kullanılır. Örneğin, Url.Action("Buy", "Products", new { id = 17 }). Yol değerleri nesnesi:

  • Kurala göre genellikle anonim türde bir nesnedir.
  • veya POCO olabilirIDictionary<>).

Yol parametreleriyle eşleşmeyen ek yol değerleri sorgu dizesine eklenir.

public IActionResult Index()
{
    var url = Url.Action("Buy", "Products", new { id = 17, color = "red" });
    return Content(url);
}

Yukarıdaki kod oluşturur /Products/Buy/17?color=red.

Aşağıdaki kod mutlak bir URL oluşturur:

public IActionResult Index2()
{
    var url = Url.Action("Buy", "Products", new { id = 17 }, protocol: Request.Scheme);
    // Returns https://localhost:5001/Products/Buy/17
    return Content(url);
}

Mutlak URL oluşturmak için aşağıdakilerden birini kullanın:

Rotaya göre URL'ler oluşturma

Yukarıdaki kod, denetleyiciyi ve eylem adını geçirerek URL oluşturmayı gösterdi. IUrlHelperayrıca Url.RouteUrl yöntem ailesini de sağlar. Bu yöntemler Url.Action'a benzer, ancak geçerli ve controller değerlerini action yol değerlerine kopyalamaz. en yaygın kullanımı Url.RouteUrl:

  • URL'yi oluşturmak için bir yol adı belirtir.
  • Genellikle bir denetleyici veya eylem adı belirtmez.
public class UrlGeneration2Controller : Controller
{
    [HttpGet("")]
    public IActionResult Source()
    {
        var url = Url.RouteUrl("Destination_Route");
        return ControllerContext.MyDisplayRouteInfo("", $" URL = {url}");
    }

    [HttpGet("custom/url/to/destination2", Name = "Destination_Route")]
    public IActionResult Destination()
    {
        return ControllerContext.MyDisplayRouteInfo();
    }

Aşağıdaki Razor dosya, dosyasına Destination_Routebir HTML bağlantısı oluşturur:

<h1>Test Links</h1>

<ul>
    <li><a href="@Url.RouteUrl("Destination_Route")">Test Destination_Route</a></li>
</ul>

HTML'de URL'ler oluşturma ve Razor

IHtmlHelperHtmlHelper, ve öğelerini oluşturmak <form> için sırasıyla Html.BeginForm ve <a> Html.ActionLink yöntemlerini sağlar. Bu yöntemler url oluşturmak için Url.Action yöntemini kullanır ve benzer bağımsız değişkenleri kabul eder. Url.RouteUrl için HtmlHelper eşlikçiler Html.BeginRouteFormHtml.RouteLink ve benzer işlevlere sahiptir.

TagHelpers, TagHelper ve <a> TagHelper aracılığıyla form URL'ler oluşturur. Bunların her ikisi de uygulamaları için kullanılır IUrlHelper . Daha fazla bilgi için bkz . Formlardaki Etiket Yardımcıları.

İç görünümler, IUrlHelper yukarıdakilerin kapsamına Url alınmayan geçici URL'ler için özelliği aracılığıyla kullanılabilir.

Eylem Sonuçlarında URL oluşturma

Yukarıdaki örnekler bir denetleyicide kullanılarak IUrlHelper gösterildi. Denetleyicideki en yaygın kullanım, eylem sonucunun bir parçası olarak BIR URL oluşturmaktır.

ControllerBase ve Controller temel sınıfları, başka bir eyleme başvuran eylem sonuçları için kolaylık yöntemleri sağlar. Tipik kullanımlardan biri, kullanıcı girişini kabul ettikten sonra yeniden yönlendirmektir:

[HttpPost]
[ValidateAntiForgeryToken]
public IActionResult Edit(int id, Customer customer)
{
    if (ModelState.IsValid)
    {
        // Update DB with new details.
        ViewData["Message"] = $"Successful edit of customer {id}";
        return RedirectToAction("Index");
    }
    return View(customer);
}

Eylem, ve gibi RedirectToActionCreatedAtAction fabrika yöntemlerini ve üzerindeki IUrlHelperyöntemlere benzer bir deseni izler.

Ayrılmış geleneksel yollar için özel durum

Geleneksel yönlendirme , ayrılmış geleneksel yol olarak adlandırılan özel bir yol tanımı türü kullanabilir. Aşağıdaki örnekte adlı blog yol ayrılmış bir geleneksel yoldur:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute(name: "blog",
                pattern: "blog/{*article}",
                defaults: new { controller = "Blog", action = "Article" });
    endpoints.MapControllerRoute(name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
});

Önceki yol tanımlarını kullanarak, Url.Action("Index", "Home") yolu kullanarak default URL yolunu / oluşturur, ancak neden? yol değerlerinin { controller = Home, action = Index } kullanarak blogbir URL oluşturmak için yeterli olacağını ve sonucun olacağını /blog?action=Index&controller=Hometahmin edebilirsiniz.

Ayrılmış geleneksel yollar , url oluşturmada yolun çok doyumsuz olmasını engelleyen ilgili bir yol parametresi olmayan varsayılan değerlerin özel bir davranışına dayanır. Bu durumda varsayılan değerler şeklindedir { controller = Blog, action = Article }ve controlleraction yol parametresi olarak gösterilmez. Yönlendirme URL oluşturmayı gerçekleştirirken, sağlanan değerlerin varsayılan değerlerle eşleşmesi gerekir. değerleri { controller = Home, action = Index } eşleşmediğinden { controller = Blog, action = Article }kullanarak blog URL oluşturma işlemi başarısız oluyor. Ardından yönlendirme, başarılı olan öğesini denemek defaultiçin geri döner.

Alanlar

Alanlar , ilgili işlevleri ayrı bir grup halinde düzenlemek için kullanılan bir MVC özelliğidir:

  • Denetleyici eylemleri için yönlendirme ad alanı.
  • Görünümler için klasör yapısı.

Alanların kullanılması, bir uygulamanın farklı alanlara sahip olduğu sürece aynı ada sahip birden çok denetleyiciye sahip olmasını sağlar. Alanları kullanmak, ve action'ye controller başka bir yol parametresi area ekleyerek yönlendirme amacıyla bir hiyerarşi oluşturur. Bu bölümde yönlendirmenin alanlarla nasıl etkileşime geçtiği açıklanır. Alanların görünümlerle nasıl kullanıldığı hakkında ayrıntılı bilgi için bkz. Alanlar.

Aşağıdaki örnek MVC'yi varsayılan geleneksel yolu ve adlandırılmış Blogbir areaarea yolu kullanacak şekilde yapılandırılır:

app.UseEndpoints(endpoints =>
{
    endpoints.MapAreaControllerRoute("blog_route", "Blog",
        "Manage/{controller}/{action}/{id?}");
    endpoints.MapControllerRoute("default_route", "{controller}/{action}/{id?}");
});

Yukarıdaki kodda, MapAreaControllerRoute oluşturmak için çağrılır "blog_route". İkinci parametre olan "Blog", alan adıdır.

gibi /Manage/Users/AddUser"blog_route" bir URL yolu eşleştirildiğinde yol, yol değerlerini { area = Blog, controller = Users, action = AddUser }oluşturur. Yol area değeri için areavarsayılan değer tarafından oluşturulur. tarafından MapAreaControllerRoute oluşturulan yol aşağıdakine eşdeğerdir:

app.UseEndpoints(endpoints =>
{
    endpoints.MapControllerRoute("blog_route", "Manage/{controller}/{action}/{id?}",
        defaults: new { area = "Blog" }, constraints: new { area = "Blog" });
    endpoints.MapControllerRoute("default_route", "{controller}/{action}/{id?}");
});

MapAreaControllerRoute , sağlanan alan adını kullanmak için area hem varsayılan değeri hem de kısıtlamayı kullanarak bir yol oluşturur. Bu durumda Blog. Varsayılan değer, yolun her zaman üretmesini { area = Blog, ... }sağlar. Kısıtlama, URL oluşturma için değeri { area = Blog, ... } gerektirir.

Geleneksel yönlendirme, siparişe bağlıdır. Genel olarak, alanları olan yollar, alanı olmayan rotalara göre daha belirgin olduğundan daha erken yerleştirilmelidir.

Yukarıdaki örneği kullanarak yol değerleri aşağıdaki eylemle eşleşmektedir { area = Blog, controller = Users, action = AddUser } :

using Microsoft.AspNetCore.Mvc;

namespace MyApp.Namespace1
{
    [Area("Blog")]
    public class UsersController : Controller
    {
        // GET /manage/users/adduser
        public IActionResult AddUser()
        {
            var area = ControllerContext.ActionDescriptor.RouteValues["area"];
            var actionName = ControllerContext.ActionDescriptor.ActionName;
            var controllerName = ControllerContext.ActionDescriptor.ControllerName;

            return Content($"area name:{area}" +
                $" controller:{controllerName}  action name: {actionName}");
        }        
    }
}

[Alan] özniteliği, bir alanın parçası olarak denetleyiciyi gösteren özelliktir. Bu denetleyici Blog bölgede. Özniteliği olmayan [Area] denetleyiciler hiçbir alanın üyesi değildir ve yönlendirme tarafından yol değeri sağlandığında area eşleşmez. Aşağıdaki örnekte, yalnızca listelenen ilk denetleyici yol değerleriyle { area = Blog, controller = Users, action = AddUser }eşleşebilir.

using Microsoft.AspNetCore.Mvc;

namespace MyApp.Namespace1
{
    [Area("Blog")]
    public class UsersController : Controller
    {
        // GET /manage/users/adduser
        public IActionResult AddUser()
        {
            var area = ControllerContext.ActionDescriptor.RouteValues["area"];
            var actionName = ControllerContext.ActionDescriptor.ActionName;
            var controllerName = ControllerContext.ActionDescriptor.ControllerName;

            return Content($"area name:{area}" +
                $" controller:{controllerName}  action name: {actionName}");
        }        
    }
}
using Microsoft.AspNetCore.Mvc;

namespace MyApp.Namespace2
{
    // Matches { area = Zebra, controller = Users, action = AddUser }
    [Area("Zebra")]
    public class UsersController : Controller
    {
        // GET /zebra/users/adduser
        public IActionResult AddUser()
        {
            var area = ControllerContext.ActionDescriptor.RouteValues["area"];
            var actionName = ControllerContext.ActionDescriptor.ActionName;
            var controllerName = ControllerContext.ActionDescriptor.ControllerName;

            return Content($"area name:{area}" +
                $" controller:{controllerName}  action name: {actionName}");
        }        
    }
}
using Microsoft.AspNetCore.Mvc;

namespace MyApp.Namespace3
{
    // Matches { area = string.Empty, controller = Users, action = AddUser }
    // Matches { area = null, controller = Users, action = AddUser }
    // Matches { controller = Users, action = AddUser }
    public class UsersController : Controller
    {
        // GET /users/adduser
        public IActionResult AddUser()
        {
            var area = ControllerContext.ActionDescriptor.RouteValues["area"];
            var actionName = ControllerContext.ActionDescriptor.ActionName;
            var controllerName = ControllerContext.ActionDescriptor.ControllerName;

            return Content($"area name:{area}" +
                $" controller:{controllerName}  action name: {actionName}");
        }
    }
}

Her denetleyicinin ad alanı tamlık için burada gösterilir. Önceki denetleyiciler aynı ad alanını kullandıysa bir derleyici hatası oluşturulur. Sınıf ad alanlarının MVC'nin yönlendirmesi üzerinde hiçbir etkisi yoktur.

İlk iki denetleyici, alanların üyeleridir ve yalnızca ilgili alan adları yol değeri tarafından area sağlandığında eşleşilir. Üçüncü denetleyici herhangi bir alanın üyesi değildir ve yalnızca yönlendirme tarafından değeri area sağlanmayanlarla eşleşebilir.

Değer eşleştirme açısından değerinarea olmaması, değerin null veya boş dize olmasıyla area aynıdır.

Bir alanın içinde bir eylem yürütürken için yol değeri area , URL oluşturma için kullanılacak yönlendirme için bir ortam değeri olarak kullanılabilir. Bu, aşağıdaki örnekte gösterildiği gibi, varsayılan olarak ALANLARıN URL oluşturma için yapışkan davrandığı anlamına gelir.

app.UseEndpoints(endpoints =>
{
    endpoints.MapAreaControllerRoute(name: "duck_route", 
                                     areaName: "Duck",
                                     pattern: "Manage/{controller}/{action}/{id?}");
    endpoints.MapControllerRoute(name: "default",
                                 pattern: "Manage/{controller=Home}/{action=Index}/{id?}");
});
using Microsoft.AspNetCore.Mvc;

namespace MyApp.Namespace4
{
    [Area("Duck")]
    public class UsersController : Controller
    {
        // GET /Manage/users/GenerateURLInArea
        public IActionResult GenerateURLInArea()
        {
            // Uses the 'ambient' value of area.
            var url = Url.Action("Index", "Home");
            // Returns /Manage/Home/Index
            return Content(url);
        }

        // GET /Manage/users/GenerateURLOutsideOfArea
        public IActionResult GenerateURLOutsideOfArea()
        {
            // Uses the empty value for area.
            var url = Url.Action("Index", "Home", new { area = "" });
            // Returns /Manage
            return Content(url);
        }
    }
}

Aşağıdaki kod için /Zebra/Users/AddUserbir URL oluşturur:

public class HomeController : Controller
{
    public IActionResult About()
    {
        var url = Url.Action("AddUser", "Users", new { Area = "Zebra" });
        return Content($"URL: {url}");
    }

Eylem tanımı

NonAction özniteliğine sahip olanlar dışında bir denetleyicideki genel yöntemler eylemlerdir.

Örnek kod

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"
    }
  }
}