Směrování na akce kontroleru v ASP.NET Core
Ryan Nowak, Kirk Larkin a Rick Anderson
Poznámka:
Toto není nejnovější verze tohoto článku. Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Upozorňující
Tato verze ASP.NET Core se už nepodporuje. Další informace najdete v zásadách podpory .NET a .NET Core. Aktuální verzi najdete v tomto článku ve verzi .NET 9.
Důležité
Tyto informace se týkají předběžného vydání produktu, který může být podstatně změněn před komerčním vydáním. Microsoft neposkytuje žádné záruky, výslovné ani předpokládané, týkající se zde uváděných informací.
Aktuální verzi najdete v tomto článku ve verzi .NET 9.
ASP.NET kontrolery Core používají middleware směrování, aby odpovídaly adresám URL příchozích požadavků a mapovaly je na akce. Šablony tras:
- Jsou definovány při spuštění v
Program.cs
atributech nebo v atributech. - Popište, jak se cesty URL shodují s akcemi.
- Slouží ke generování adres URL pro odkazy. Vygenerované odkazy se obvykle vrací v odpovědích.
Akce jsou buď obvykle směrovány, nebo jsou směrovány atributem. Když umístíte trasu na kontroler nebo akci , bude směrovaná atributem. Další informace najdete v tématu Smíšené směrování .
Tento dokument:
- Vysvětluje interakce mezi MVC a směrováním:
- Jak typické aplikace MVC využívají funkce směrování.
- Probírá obojí:
- Běžné směrování se obvykle používá u kontrolerů a zobrazení.
- Směrování atributů používané s rozhraními REST API Pokud vás zajímá především směrování pro REST rozhraní API, přejděte do části Směrování atributů pro REST rozhraní API .
- Podrobnosti o rozšířeném směrování najdete v tématu Směrování .
- Odkazuje na výchozí systém směrování označovaný jako směrování koncového bodu. Pro účely kompatibility je možné používat kontrolery s předchozí verzí směrování. Pokyny najdete v průvodci migrací verze 2.2-3.0.
Nastavení konvenční trasy
Šablona ASP.NET Core MVC generuje konvenční směrovací kód podobný následujícímu:
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 slouží k vytvoření jedné trasy. Jedna trasa má název default
trasy. Většina aplikací s kontrolery a zobrazeními používá šablonu trasy podobnou default
této trase. REST Rozhraní API by měla používat směrování atributů.
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Šablona "{controller=Home}/{action=Index}/{id?}"
trasy:
Odpovídá cestě URL, jako je
/Products/Details/5
Extrahuje hodnoty
{ controller = Products, action = Details, id = 5 }
trasy tokenizací cesty. Extrahování hodnot tras vede ke shodě, pokud má aplikace pojmenovaný kontrolerProductsController
aDetails
akci:public class ProductsController : Controller { public IActionResult Details(int id) { return ControllerContext.MyDisplayRouteInfo(id); } }
MyDisplayRouteInfo poskytuje balíček NuGet Rick.Docs.Samples.RouteInfo a zobrazí informace o trase.
/Products/Details/5
model sváže hodnotuid = 5
nastavení parametruid
na5
. Další podrobnosti najdete v tématu Vazby modelu.{controller=Home}
definujeHome
jako výchozícontroller
.{action=Index}
definujeIndex
jako výchozíaction
.Znak
?
v{id?}
definici jeid
volitelný.- Výchozí a volitelné parametry trasy nemusí být v cestě URL pro shodu. Podrobný popis syntaxe šablony trasy najdete v referenčních informacích k šabloně trasy.
Odpovídá cestě
/
URL .Vytvoří hodnoty
{ controller = Home, action = Index }
trasy .
Hodnoty pro controller
výchozí hodnoty a action
jejich použití. id
nevytvoří hodnotu, protože v cestě URL neexistuje žádný odpovídající segment. /
odpovídá pouze v případě, že existuje nějaká HomeController
akce:Index
public class HomeController : Controller
{
public IActionResult Index() { ... }
}
Pomocí předchozí definice kontroleru a šablony trasy se HomeController.Index
akce spustí pro následující cesty URL:
/Home/Index/17
/Home/Index
/Home
/
Cesta /
URL používá výchozí Home
kontrolery a Index
akci šablony trasy. Cesta URL /Home
používá výchozí Index
akci šablony trasy.
Metoda MapDefaultControllerRoutepohodlí:
app.MapDefaultControllerRoute();
Nahrazuje:
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Důležité
Směrování se konfiguruje pomocí middlewaruUseRouting.UseEndpoints Použití kontrolerů:
- Volání MapControllers mapovaných kontrolerů atributů
- Volání MapControllerRoute nebo MapAreaControllerRoute, mapovat jak běžně směrované kontrolery, tak i směrované kontrolery atributů.
Aplikace obvykle nemusí volat UseRouting
ani UseEndpoints
. WebApplicationBuilder konfiguruje middlewarový kanál, který zabalí middleware přidaný do Program.cs
UseRouting
a UseEndpoints
. Další informace najdete v tématu Směrování v ASP.NET Core.
Konvenční směrování
Konvenční směrování se používá s řadiči a zobrazeními. Trasa default
:
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Předchozí příklad je příkladem konvenční trasy. Říká se tomu konvenční směrování , protože vytváří konvenci pro cesty url:
- První segment cesty ,
{controller=Home}
mapuje na název kontroleru. - Druhý segment,
{action=Index}
, mapuje na název akce . - Třetí segment se používá pro volitelný
id
.{id?}
Hodnota?
in{id?}
je volitelná.id
slouží k mapování na entitu modelu.
Pomocí této default
trasy cesta URL:
/Products/List
se mapuje naProductsController.List
akci./Blog/Article/17
mapujeid
aBlogController.Article
obvykle model sváže parametr na 17.
Toto mapování:
- Je založen pouze na názvech kontroleru a akcí.
- Není založená na oborech názvů, umístěních zdrojových souborů nebo parametrech metody.
Použití konvenčního směrování s výchozí trasou umožňuje vytvořit aplikaci, aniž by bylo nutné pro každou akci vytvořit nový vzor adresy URL. U aplikace s akcemi stylu CRUD mají konzistenci adres URL napříč řadiči:
- Pomáhá zjednodušit kód.
- Zpřístupňuje uživatelské rozhraní předvídatelněji.
Upozorňující
V id
předchozím kódu je definována jako volitelná šablona trasy. Akce se můžou spouštět bez volitelného ID zadaného jako součást adresy URL. Obecně platí, že pokud id
je vynechán z adresy URL:
id
je nastavena0
vazbou modelu.- V porovnávání
id == 0
databáze nebyla nalezena žádná entita .
Směrování atributů poskytuje jemně odstupňované řízení, aby se ID vyžadovalo pro některé akce, a ne pro jiné. Podle konvence obsahuje dokumentace volitelné parametry, jako id
když se pravděpodobně objeví ve správném použití.
Většina aplikací by měla zvolit základní a popisné schéma směrování, aby adresy URL byly čitelné a smysluplné. Výchozí konvenční trasa {controller=Home}/{action=Index}/{id?}
:
- Podporuje základní a popisné schéma směrování.
- Je užitečný výchozí bod pro aplikace založené na uživatelském rozhraní.
- Je jediná šablona trasy potřebná pro mnoho aplikací webového uživatelského rozhraní. U větších aplikací webového uživatelského rozhraní je další trasa využívající oblasti často všechna potřebná.
MapControllerRoute a MapAreaRoute :
- Automaticky přiřaďte jejich koncovým bodům hodnotu objednávky na základě pořadí, ve které jsou vyvolány.
Směrování koncových bodů v ASP.NET Core:
- Nemá koncept tras.
- Neposkytuje záruky řazení pro provádění rozšiřitelnosti, všechny koncové body se zpracovávají najednou.
Povolte protokolování , abyste viděli, jak integrované implementace směrování, například Route, odpovídají požadavkům.
Směrování atributů je vysvětleno dále v tomto dokumentu.
Více konvenčních tras
Více konvenčních tras lze nakonfigurovat přidáním dalších volání do MapControllerRoute a MapAreaControllerRoute. To umožňuje definovat více konvencí nebo přidat konvenční trasy, které jsou vyhrazené pro konkrétní akci, například:
app.MapControllerRoute(name: "blog",
pattern: "blog/{*article}",
defaults: new { controller = "Blog", action = "Article" });
app.MapControllerRoute(name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Trasa blog
v předchozím kódu je vyhrazená konvenční trasa. Označuje se jako vyhrazená konvenční trasa, protože:
- Používá konvenční směrování.
- Je vyhrazená pro konkrétní akci.
Vzhledem k tomu, controller
že se action
v šabloně "blog/{*article}"
trasy nezobrazují jako parametry:
- Mohou mít pouze výchozí hodnoty
{ controller = "Blog", action = "Article" }
. - Tato trasa se vždy mapuje na akci
BlogController.Article
.
/Blog
, /Blog/Article
a /Blog/{any-string}
jsou jediné cesty URL, které odpovídají trase blogu.
Předchozí příklad:
blog
trasa má vyšší prioritudefault
pro shody než trasa, protože je přidána jako první.- Je příkladem směrování stylu Slug , kde je typické mít název článku jako součást adresy URL.
Upozorňující
V ASP.NET Core směrování ne:
- Definujte koncept označovaný jako trasa.
UseRouting
přidá trasu odpovídající kanálu middlewaru. MiddlewareUseRouting
se podívá na sadu koncových bodů definovaných v aplikaci a vybere nejlepší shodu koncového bodu na základě požadavku. - Poskytovat záruky týkající se pořadí provádění rozšiřitelnosti, jako IRouteConstraint nebo IActionConstraint.
Viz Směrovací materiál pro směrování.
Konvenční pořadí směrování
Konvenční směrování odpovídá pouze kombinaci akce a kontroleru definované aplikací. Cílem je zjednodušit případy, kdy se běžné trasy překrývají.
Přidání tras pomocí MapControllerRoutea MapDefaultControllerRouteMapAreaControllerRoute automatické přiřazení hodnoty objednávky ke svým koncovým bodům na základě pořadí, ve které jsou vyvolány. Shody z trasy, která se zobrazí dříve, mají vyšší prioritu. Konvenční směrování je závislé na pořadí. Obecně platí, že trasy s oblastmi by měly být umístěny dříve, protože jsou konkrétnější než trasy bez oblasti. Vyhrazené konvenční trasy s parametry trasy catch-all, jako {*article}
je může vytvořit trasu příliš greedy, což znamená, že odpovídá adresám URL, které jste chtěli spárovat jinými trasami. Trasu greedy umístěte později do směrovací tabulky, aby se zabránilo shodám greedy.
Upozorňující
Parametr catch-all může nesprávně odpovídat trasám kvůli chybě při směrování. Aplikace ovlivněné touto chybou mají následující charakteristiky:
- Například trasa pro zachytávání– vše
{**slug}"
- Trasa catch-all neodpovídá požadavkům, které by se měly shodovat.
- Odebráním jiných tras začne fungovat zachytávání všech tras.
Podívejte se na chyby GitHubu 18677 a 16579 , například případy, které tuto chybu narazily.
Oprava výslovného souhlasu s touto chybou je obsažená v sadě .NET Core 3.1.301 SDK a novějších verzích. Následující kód nastaví interní přepínač, který tuto chybu opraví:
public static void Main(string[] args)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Routing.UseCorrectCatchAllBehavior",
true);
CreateHostBuilder(args).Build().Run();
}
// Remaining code removed for brevity.
Řešení nejednoznačných akcí
Když se dva koncové body shodují prostřednictvím směrování, musí směrování provést jednu z těchto věcí:
- Vyberte nejlepšího kandidáta.
- Vyvolá výjimku.
Příklad:
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);
}
}
Předchozí kontroler definuje dvě akce, které odpovídají:
- Cesta URL
/Products33/Edit/17
- Směrovat data
{ controller = Products33, action = Edit, id = 17 }
.
Toto je typický vzor pro kontrolery MVC:
Edit(int)
zobrazí formulář pro úpravu produktu.Edit(int, Product)
zpracuje vystavený formulář.
Řešení správné trasy:
Edit(int, Product)
je vybrána, pokud je požadavek HTTPPOST
.Edit(int)
je vybrána, pokud je příkaz HTTP cokoli jiného.Edit(int)
je obecně volána prostřednictvímGET
.
, HttpPostAttribute[HttpPost]
je poskytována pro směrování tak, aby mohl zvolit na základě metody HTTP požadavku. Edit(int, Product)
Dělá HttpPostAttribute
lepší shodu než Edit(int)
.
Je důležité pochopit roli atributů, jako HttpPostAttribute
je . Podobné atributy jsou definovány pro jiné příkazy HTTP. U konvenčního směrování je běžné, že akce používají stejný název akce, když jsou součástí formuláře pro zobrazení a odesílají pracovní postup formuláře. Podívejte se například na prozkoumání dvou metod akce Upravit.
Pokud směrování nemůže zvolit nejlepšího kandidáta, vyvolá AmbiguousMatchException se výpis několika odpovídajících koncových bodů.
Konvenční názvy tras
Řetězce a "default"
v následujících příkladech "blog"
jsou konvenční názvy tras:
app.MapControllerRoute(name: "blog",
pattern: "blog/{*article}",
defaults: new { controller = "Blog", action = "Article" });
app.MapControllerRoute(name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Názvy tras dávají této trase logický název. Pojmenovanou trasu lze použít pro generování adres URL. Použití pojmenované trasy zjednodušuje vytváření adres URL, když řazení tras může komplikovat generování adres URL. Názvy tras musí být jedinečné pro celou aplikaci.
Názvy tras:
- Nemá žádný vliv na porovnávání adres URL ani zpracování požadavků.
- Používají se jenom pro generování adres URL.
Koncept názvu trasy je reprezentován ve směrování jako IEndpointNameMetadata. Název trasy termínů a název koncového bodu:
- Jsou zaměnitelné.
- Který z nich se používá v dokumentaci a kódu, závisí na popsaném rozhraní API.
Směrování atributů pro REST rozhraní API
REST Rozhraní API by měla používat směrování atributů k modelování funkčnosti aplikace jako sady prostředků, ve kterých jsou operace reprezentovány příkazy HTTP.
Směrování atributů používá sadu atributů k mapování akcí přímo na šablony směrování. Následující kód je typický pro REST rozhraní API a používá se v další ukázce:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
V předchozím kódu se MapControllers volá k mapování směrovaných kontrolerů atributů.
V následujícím příkladu:
HomeController
odpovídá sadě adres URL podobných výchozím běžným trasám{controller=Home}/{action=Index}/{id?}
.
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);
}
}
Akce HomeController.Index
se spustí pro některou z cest /
URL , /Home
, /Home/Index
, nebo /Home/Index/3
.
Tento příklad zvýrazňuje klíčový programovací rozdíl mezi směrováním atributů a konvenčním směrováním. Směrování atributů vyžaduje k zadání trasy další vstup. Konvenční výchozí trasa zpracovává trasy rychleji. Směrování atributů však umožňuje a vyžaduje přesnou kontrolu nad tím, které šablony tras se vztahují na každou akci.
Při směrování atributů nehrají názvy kontroleru a akcí žádnou roli, ve které se akce shoduje, pokud se nepoužije nahrazení tokenu. Následující příklad odpovídá stejným adresám URL jako v předchozím příkladu:
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);
}
}
Následující kód používá nahrazení tokenu pro action
a controller
:
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();
}
}
Následující kód se vztahuje [Route("[controller]/[action]")]
na kontroler:
[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();
}
}
V předchozím kódu Index
musí šablony metod předcházet /
nebo ~/
směrovat šablony. Směrovací šablony použité na akci, která začíná /
nebo ~/
se nezkombinuje se šablonami tras použitými na kontroler.
Informace o výběru šablony trasy najdete v tématu Priorita šablony trasy.
Rezervované názvy směrování
Následující klíčová slova jsou vyhrazena názvy parametrů trasy při použití kontrolerů nebo Razor stránek:
action
area
controller
handler
page
Použití page
jako parametru trasy se směrováním atributů je běžnou chybou. Výsledkem je nekonzistentní a matoucí chování při generování adresy URL.
public class MyDemo2Controller : Controller
{
[Route("/articles/{page}")]
public IActionResult ListArticles(int page)
{
return ControllerContext.MyDisplayRouteInfo(page);
}
}
Speciální názvy parametrů používají generování adresy URL k určení, jestli operace generování adresy URL odkazuje na Razor stránku nebo na kontroler.
Následující klíčová slova jsou vyhrazena v kontextu Razor zobrazení nebo Razor stránky:
page
using
namespace
inject
section
inherits
model
addTagHelper
removeTagHelper
Tato klíčová slova by se neměla používat pro generace propojení, parametry vázané na model ani vlastnosti nejvyšší úrovně.
Šablony příkazů HTTP
ASP.NET Core obsahuje následující šablony příkazů HTTP:
Šablony tras
ASP.NET Core má následující šablony tras:
Směrování atributů s atributy příkazů HTTP
Vezměte v úvahu následující kontroler:
[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);
}
}
V předchozím kódu:
- Každá akce obsahuje
[HttpGet]
atribut, který omezuje pouze porovnávání požadavků HTTP GET. - Akce
GetProduct
obsahuje"{id}"
šablonu, protoid
je připojena k"api/[controller]"
šabloně na kontroleru. Šablona metod je"api/[controller]/{id}"
. Tato akce proto odpovídá pouze požadavkům GET pro formulář/api/test2/xyz
,/api/test2/123
,/api/test2/{any string}
, atd.[HttpGet("{id}")] // GET /api/test2/xyz public IActionResult GetProduct(string id) { return ControllerContext.MyDisplayRouteInfo(id); }
- Akce
GetIntProduct
obsahuje"int/{id:int}"
šablonu. Část:int
šablony omezuje směrovacíid
hodnoty na řetězce, které lze převést na celé číslo. Požadavek GET na/api/test2/int/abc
:- Neodpovídá této akci.
- Vrátí chybu 404 Nenalezena.
[HttpGet("int/{id:int}")] // GET /api/test2/int/3 public IActionResult GetIntProduct(int id) { return ControllerContext.MyDisplayRouteInfo(id); }
- Akce
GetInt2Product
obsahuje{id}
v šabloně, ale neomezujeid
na hodnoty, které lze převést na celé číslo. Požadavek GET na/api/test2/int2/abc
:- Odpovídá této trase.
- Vazba modelu se nepodaří převést
abc
na celé číslo. Parametrid
metody je celé číslo. - Vrátí chybu 400 Chybný požadavek , protože vazbu modelu se nepodařilo převést
abc
na celé číslo.[HttpGet("int2/{id}")] // GET /api/test2/int2/3 public IActionResult GetInt2Product(int id) { return ControllerContext.MyDisplayRouteInfo(id); }
Směrování atributů může používat HttpMethodAttribute atributy, jako HttpPostAttributeje , HttpPutAttributea HttpDeleteAttribute. Všechny atributy příkazu HTTP přijímají šablonu trasy. Následující příklad ukazuje dvě akce, které odpovídají stejné šabloně trasy:
[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);
}
}
Pomocí cesty /products3
URL:
- Akce
MyProductsController.ListProducts
se spustí, když jeGET
příkaz HTTP . - Akce
MyProductsController.CreateProduct
se spustí, když jePOST
příkaz HTTP .
Při vytváření REST rozhraní API je vzácné, že budete muset použít [Route(...)]
metodu akce, protože akce přijímá všechny metody HTTP. Lepší je použít konkrétnější atribut příkazu HTTP, aby byl přesný o tom, co vaše rozhraní API podporuje. REST Očekává se, že klienti rozhraní API vědí, jaké cesty a příkazy HTTP se mapují na konkrétní logické operace.
REST Rozhraní API by měla používat směrování atributů k modelování funkčnosti aplikace jako sady prostředků, ve kterých jsou operace reprezentovány příkazy HTTP. To znamená, že mnoho operací, například GET a POST ve stejném logickém prostředku, používá stejnou adresu URL. Směrování atributů poskytuje úroveň řízení, která je nutná k pečlivému návrhu rozložení veřejného koncového bodu rozhraní API.
Vzhledem k tomu, že trasa atributu se vztahuje na konkrétní akci, je snadné nastavit parametry vyžadované jako součást definice šablony trasy. V následujícím příkladu id
se vyžaduje jako součást cesty URL:
[ApiController]
public class Products2ApiController : ControllerBase
{
[HttpGet("/products2/{id}", Name = "Products_List")]
public IActionResult GetProduct(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
}
Akce Products2ApiController.GetProduct(int)
:
- Spouští se s cestou URL, jako je
/products2/3
- Nejde spustit s cestou
/products2
URL .
Atribut [Consumes] umožňuje akci omezit podporované typy obsahu požadavku. Další informace najdete v tématu Definování podporovaných typů obsahu požadavku pomocí atributu Consumes.
Úplný popis šablon tras a souvisejících možností najdete v tématu Směrování .
Další informace o [ApiController]
, viz ApiController atribut.
Název trasy
Následující kód definuje název Products_List
trasy:
[ApiController]
public class Products2ApiController : ControllerBase
{
[HttpGet("/products2/{id}", Name = "Products_List")]
public IActionResult GetProduct(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
}
Názvy tras se dají použít k vygenerování adresy URL na základě konkrétní trasy. Názvy tras:
- Nemá žádný vliv na chování přiřazování adres URL směrování.
- Používají se jenom pro generování adres URL.
Názvy tras musí být jedinečné pro celou aplikaci.
Porovnejte předchozí kód s konvenční výchozí trasou, která definuje id
parametr jako volitelný ({id?}
). Schopnost přesně specifikovat rozhraní API má výhody, jako je povolení /products
a /products/5
odeslání do různých akcí.
Kombinování tras atributů
Aby směrování atributů bylo méně opakované, atributy směrování na kontroleru se zkombinují s atributy trasy u jednotlivých akcí. Všechny šablony tras definované v kontroleru jsou předem nastavené tak, aby směrovaly šablony akcí. Umístění atributu trasy na kontroler provede všechny akce ve směrování atributů kontroleru.
[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);
}
}
V předchozím příkladu:
- Cesta
/products
url se může shodovat.ProductsApi.ListProducts
- Cesta
/products/5
url se může shodovatProductsApi.GetProduct(int)
.
Obě tyto akce odpovídají protokolu HTTP GET
, protože jsou označené atributem [HttpGet]
.
Směrovací šablony použité na akci, která začíná /
nebo ~/
se nezkombinuje se šablonami tras použitými na kontroler. Následující příklad odpovídá sadě cest URL podobných výchozí trase.
[Route("Home")]
public class HomeController : Controller
{
[Route("")]
[Route("Index")]
[Route("/")]
public IActionResult Index()
{
return ControllerContext.MyDisplayRouteInfo();
}
[Route("About")]
public IActionResult About()
{
return ControllerContext.MyDisplayRouteInfo();
}
}
Následující tabulka vysvětluje [Route]
atributy v předchozím kódu:
Atribut | Kombinuje s [Route("Home")] |
Definuje šablonu trasy. |
---|---|---|
[Route("")] |
Ano | "Home" |
[Route("Index")] |
Ano | "Home/Index" |
[Route("/")] |
Ne | "" |
[Route("About")] |
Ano | "Home/About" |
Pořadí tras atributů
Směrování vytvoří strom a odpovídá všem koncovým bodům současně:
- Položky trasy se chovají tak, jako by byly umístěny v ideálním pořadí.
- Nejvýraznější trasy mají možnost spustit před obecnějšími trasami.
Například trasa atributu, jako blog/search/{topic}
je konkrétnější než trasa atributu, jako blog/{*article}
je . Trasa blog/search/{topic}
má ve výchozím nastavení vyšší prioritu, protože je konkrétnější. Pomocí konvenčního směrování zodpovídá vývojář za umístění tras do požadovaného pořadí.
Trasy atributů můžou nakonfigurovat pořadí pomocí Order vlastnosti. Všechny atributy trasy poskytované architekturou zahrnují Order
. Trasy se zpracovávají podle vzestupného řazení Order
vlastnosti. Výchozí pořadí je 0
. Nastavení trasy pomocí Order = -1
spuštění před trasami, které nenastavují pořadí Nastavení trasy pomocí Order = 1
spuštění po výchozím pořadí tras
Vyhněte se v závislosti na Order
. Pokud prostor adres URL aplikace vyžaduje správné směrování explicitních hodnot objednávek, pravděpodobně je také matoucí pro klienty. Obecně platí, že směrování atributů vybere správnou trasu s odpovídající adresou URL. Pokud výchozí pořadí použité pro generování adresy URL nefunguje, použití názvu trasy jako přepsání je obvykle jednodušší než použití Order
vlastnosti.
Vezměte v úvahu následující dva kontrolery, které definují porovnávání /home
tras:
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
Požadavek s předchozím kódem vyvolá výjimku podobnou následující:
AmbiguousMatchException: The request matched multiple endpoints. Matches:
WebMvcRouting.Controllers.HomeController.Index
WebMvcRouting.Controllers.MyDemoController.MyIndex
Přidání Order
do jednoho z atributů trasy vyřeší nejednoznačnost:
[Route("")]
[Route("Home", Order = 2)]
[Route("Home/MyIndex")]
public IActionResult MyIndex()
{
return ControllerContext.MyDisplayRouteInfo();
}
S předchozím kódem /home
spustí HomeController.Index
koncový bod. Chcete-li se dostat k MyDemoController.MyIndex
žádosti /home/MyIndex
. Poznámka:
- Předchozí kód je příkladem nebo špatným návrhem směrování. Byla použita k ilustraci
Order
vlastnosti. - Vlastnost
Order
přeloží pouze nejednoznačnost, kterou nelze shodovat. Bylo by lepší šablonu odebrat[Route("Home")]
.
Viz Razor Zásady směrování stránek a aplikací: Pořadí tras pro informace o pořadí tras pomocí Razor stránek.
V některých případech se vrátí chyba HTTP 500 s nejednoznačnými trasami. Pomocí protokolování zjistíte, které koncové body způsobily AmbiguousMatchException
.
Výměna tokenů v šablonách tras [kontroler], [akce], [oblast]
Pro usnadnění práce trasy atributů podporují nahrazení tokenu uzavřením tokenu do hranatých závorek ([
, ]
). Tokeny , [area]
a [controller]
jsou nahrazeny [action]
hodnotami názvu akce, název oblasti a název kontroleru z akce, kde je trasa definována:
[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);
}
}
V předchozím kódu:
[HttpGet]
public IActionResult List()
{
return ControllerContext.MyDisplayRouteInfo();
}
- Zápasy
/Products0/List
[HttpGet("{id}")]
public IActionResult Edit(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
- Zápasy
/Products0/Edit/{id}
Nahrazení tokenu probíhá jako poslední krok sestavení tras atributů. Předchozí příklad se chová stejně jako následující kód:
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);
}
}
Pokud to čtete v jiném jazyce než v angličtině, dejte nám vědět v tomto problému s diskuzí na GitHubu, pokud chcete vidět komentáře ke kódu ve vašem nativním jazyce.
Trasy atributů lze také kombinovat s dědičností. Jedná se o výkonnou kombinaci s nahrazením tokenů. Nahrazení tokenu se vztahuje také na názvy tras definovaných trasami atributů.
[Route("[controller]/[action]", Name="[controller]_[action]")]
vygeneruje jedinečný název trasy pro každou akci:
[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);
}
}
Chcete-li se shodovat s oddělovačem [
nahrazení literálového tokenu nebo ]
ho umistit opakováním znaku ([[
nebo ]]
).
Přizpůsobení nahrazení tokenu pomocí transformátoru parametrů
Nahrazení tokenů lze přizpůsobit pomocí transformátoru parametrů. Transformátor parametrů implementuje IOutboundParameterTransformer a transformuje hodnotu parametrů. Například vlastní SlugifyParameterTransformer
transformátor parametru SubscriptionManagement
změní hodnotu trasy na subscription-management
:
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();
}
}
Jedná se RouteTokenTransformerConvention o konvenci modelu aplikace, která:
- Použije transformátor parametrů na všechny trasy atributů v aplikaci.
- Přizpůsobí hodnoty tokenu trasy atributu při jejich nahrazení.
public class SubscriptionManagementController : Controller
{
[HttpGet("[controller]/[action]")]
public IActionResult ListAll()
{
return ControllerContext.MyDisplayRouteInfo();
}
}
Předchozí ListAll
metoda odpovídá /subscription-management/list-all
.
Tato RouteTokenTransformerConvention
možnost je zaregistrovaná jako:
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();
Definice Slug najdete ve webové dokumentaci MDN na Slug .
Upozorňující
Při zpracování System.Text.RegularExpressions nedůvěryhodného vstupu předejte vypršení časového limitu. Uživatel se zlými úmysly může poskytnout vstup, který RegularExpressions
způsobí útok na dostupnost služby. ASP.NET rozhraní API architektury Core, která používají RegularExpressions
vypršení časového limitu.
Více tras atributů
Směrování atributů podporuje definování více tras, které se dostanou ke stejné akci. Nejběžnějším použitím je napodobit chování výchozí konvenční trasy, jak je znázorněno v následujícím příkladu:
[Route("[controller]")]
public class Products13Controller : Controller
{
[Route("")] // Matches 'Products13'
[Route("Index")] // Matches 'Products13/Index'
public IActionResult Index()
{
return ControllerContext.MyDisplayRouteInfo();
}
Umístění více atributů směrování na kontroler znamená, že každý z nich kombinuje s jednotlivými atributy trasy v metodách akce:
[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();
}
}
Implementují IActionConstraint
se všechna omezení směrování příkazů HTTP .
Pokud je u akce umístěno více atributů trasy, které se implementují IActionConstraint :
- Každé omezení akce kombinuje šablonu trasy použitou na kontroler.
[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();
}
}
Použití více tras u akcí může vypadat jako užitečné a výkonné, je lepší zachovat základní a dobře definovaný prostor adres URL vaší aplikace. Pro akce používejte více tras pouze tam, kde je to potřeba, například pro podporu stávajících klientů.
Určení volitelných parametrů trasy atributů, výchozích hodnot a omezení
Trasy atributů podporují stejnou vloženou syntaxi jako běžné trasy a určují volitelné parametry, výchozí hodnoty a omezení.
public class Products14Controller : Controller
{
[HttpPost("product14/{id:int}")]
public IActionResult ShowProduct(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
}
V předchozím kódu [HttpPost("product14/{id:int}")]
použije omezení trasy. Akce Products14Controller.ShowProduct
se shoduje pouze s cestami URL, jako je /product14/3
. Část šablony {id:int}
trasy omezuje tento segment pouze na celá čísla.
Podrobný popis syntaxe šablony trasy najdete v referenčních informacích k šabloně trasy.
Vlastní atributy trasy pomocí IRouteTemplateProvider
Všechny atributy trasy implementují IRouteTemplateProvider. Modul runtime ASP.NET Core:
- Vyhledá atributy tříd kontroleru a metod akcí při spuštění aplikace.
- Používá atributy, které implementují
IRouteTemplateProvider
k sestavení počáteční sady tras.
Implementujte IRouteTemplateProvider
definování vlastních atributů trasy. Každá IRouteTemplateProvider
umožňuje definovat jednu trasu s vlastní šablonou trasy, pořadím a názvem:
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();
}
}
Předchozí Get
metoda vrátí Order = 2, Template = api/MyTestApi
.
Přizpůsobení tras atributů pomocí aplikačního modelu
Aplikační model:
- Je objektový model vytvořený při spuštění v
Program.cs
. - Obsahuje všechna metadata používaná ASP.NET Core ke směrování a provádění akcí v aplikaci.
Aplikační model zahrnuje všechna data shromážděná z atributů trasy. Implementace poskytuje IRouteTemplateProvider
data z atributů trasy. Konvence:
- Lze napsat a upravit aplikační model tak, aby přizpůsobil chování směrování.
- Čtou se při spuštění aplikace.
Tato část ukazuje základní příklad přizpůsobení směrování pomocí aplikačního modelu. Následující kód vytváří trasy zhruba zarovná do struktury složek projektu.
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()
};
}
}
}
Následující kód zabraňuje namespace
použití konvence na kontrolery, které jsou směrovány atributem:
public void Apply(ControllerModel controller)
{
var hasRouteAttributes = controller.Selectors.Any(selector =>
selector.AttributeRouteModel != null);
if (hasRouteAttributes)
{
return;
}
Například následující kontroler nepoužívá 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}");
}
}
Metoda NamespaceRoutingConvention.Apply
:
- Nedělá nic, pokud je kontroler směrován atributem.
- Nastaví šablonu kontrolerů na
namespace
základě , s odebranou základnounamespace
.
Lze použít NamespaceRoutingConvention
v Program.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();
Představte si například následující kontroler:
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}");
}
}
}
V předchozím kódu:
- Základ
namespace
jeMy.Application
. - Úplný název předchozího kontroleru je
My.Application.Admin.Controllers.UsersController
. - Nastaví
NamespaceRoutingConvention
šablonu kontrolerů naAdmin/Controllers/Users/[action]/{id?
.
Dá NamespaceRoutingConvention
se také použít jako atribut na kontroleru:
[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}");
}
}
Smíšené směrování: Směrování atributů vs. konvenční směrování
ASP.NET základní aplikace můžou kombinovat použití konvenčního směrování a směrování atributů. Pro kontrolery obsluhující stránky HTML pro prohlížeče a směrování atributů pro kontrolery, které obsluhují REST rozhraní API, je typické použití konvenčních tras.
Akce se směrují buď konvenčně, nebo jsou směrovány atributem. Umístěním trasy na kontroler nebo akci se směruje atribut. Akce, které definují trasy atributů, nelze dosáhnout prostřednictvím konvenčních tras a naopak. Jakýkoli atribut trasy na kontroleru provede všechny akce ve směrovaném atributu kontroleru.
Směrování atributů a konvenční směrování používají stejný směrovací modul.
Směrování se speciálními znaky
Směrování se speciálními znaky může vést k neočekávaným výsledkům. Představte si například kontroler s následující metodou akce:
[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;
}
Pokud string id
obsahuje následující kódované hodnoty, mohou dojít k neočekávaným výsledkům:
ASCII | Encoded |
---|---|
/ |
%2F |
|
+ |
Parametry trasy nejsou vždy dekódovány adresou URL. Tento problém může být vyřešen v budoucnu. Další informace najdete v tomto problému na GitHubu.
Generování adres URL a okolní hodnoty
Aplikace můžou pomocí funkcí generování adres URL směrování generovat odkazy na adresy URL na akce. Generování adres URL eliminuje pevně zakódované adresy URL, takže je kód robustnější a udržovatelný. Tato část se zaměřuje na funkce generování adres URL, které poskytuje MVC, a zabývá se jenom základy fungování generování adres URL. Podrobný popis generování adres URL najdete v tématu Směrování .
Rozhraní IUrlHelper je základní prvek infrastruktury mezi MVC a směrováním pro generování adres URL. Instance IUrlHelper
je k dispozici prostřednictvím Url
vlastnosti v kontrolerů, zobrazeních a komponentách zobrazení.
V následujícím příkladu se IUrlHelper
rozhraní používá prostřednictvím Controller.Url
vlastnosti k vygenerování adresy URL jiné akce.
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();
}
}
Pokud aplikace používá výchozí konvenční trasu, hodnota url
proměnné je řetězec /UrlGeneration/Destination
cesty url . Tuto cestu URL vytvoří směrováním zkombinováním:
- Směrovací hodnoty z aktuálního požadavku, které se nazývají okolní hodnoty.
- Hodnoty předané
Url.Action
a nahrazující tyto hodnoty do šablony trasy:
ambient values: { controller = "UrlGeneration", action = "Source" }
values passed to Url.Action: { controller = "UrlGeneration", action = "Destination" }
route template: {controller}/{action}/{id?}
result: /UrlGeneration/Destination
Každý parametr trasy v šabloně trasy má hodnotu nahrazenou odpovídajícími názvy s hodnotami a okolními hodnotami. Parametr trasy, který nemá hodnotu, může:
- Pokud má výchozí hodnotu, použijte ji.
- Pokud je nepovinný, přeskočí se. Například
id
ze šablony{controller}/{action}/{id?}
trasy .
Generování adresy URL selže, pokud některý parametr požadované trasy nemá odpovídající hodnotu. Pokud generování adresy URL pro trasu selže, zkusí se další trasa, dokud se nezkouší všechny trasy nebo se nenajde shoda.
Předchozí příklad Url.Action
předpokládá konvenční směrování. Generování adres URL funguje podobně se směrováním atributů, i když se koncepty liší. S konvenčním směrováním:
- Hodnoty tras slouží k rozbalení šablony.
- Hodnoty tras pro
controller
aaction
obvykle se v této šabloně zobrazují. To funguje, protože adresy URL odpovídající směrováním dodržují konvenci.
Následující příklad používá směrování atributů:
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();
}
}
Akce Source
v předchozím kódu vygeneruje custom/url/to/destination
.
LinkGenerator byl přidán v ASP.NET Core 3.0 jako alternativu k IUrlHelper
. LinkGenerator
nabízí podobné, ale flexibilnější funkce. Každá metoda má IUrlHelper
také odpovídající řadu metod LinkGenerator
.
Generování adres URL podle názvu akce
Url.Action, LinkGenerator.GetPathByAction a všechna související přetížení jsou navržena tak, aby vygenerovala cílový koncový bod zadáním názvu kontroleru a názvu akce.
Pokud používáte Url.Action
, aktuální hodnoty tras pro controller
a action
jsou poskytovány modulem runtime:
- Hodnota
controller
aaction
jsou součástí okolních hodnot i hodnot. MetodaUrl.Action
vždy používá aktuální hodnotyaction
acontroller
generuje cestu URL, která směruje na aktuální akci.
Směrování se pokusí použít hodnoty v okolních hodnotách k vyplnění informací, které nebyly poskytnuty při generování adresy URL. Představte si trasu jako {a}/{b}/{c}/{d}
s okolními hodnotami { a = Alice, b = Bob, c = Carol, d = David }
:
- Směrování má dostatek informací k vygenerování adresy URL bez dalších hodnot.
- Směrování má dostatek informací, protože všechny parametry trasy mají hodnotu.
Pokud se hodnota { d = Donovan }
přidá:
- Hodnota
{ d = David }
se ignoruje. - Vygenerovaná cesta URL je
Alice/Bob/Carol/Donovan
.
Upozornění: Cesty url jsou hierarchické. Pokud se v předchozím příkladu přidá hodnota { c = Cheryl }
:
- Obě hodnoty
{ c = Carol, d = David }
jsou ignorovány. - Generování adresy URL už nemá hodnotu
d
a generování adresy URL se nezdaří. - Požadované hodnoty
c
ad
musí být zadány pro vygenerování adresy URL.
U výchozí trasy {controller}/{action}/{id?}
můžete očekávat, že dojde k tomuto problému . Tento problém je v praxi vzácný, protože Url.Action
vždy explicitně určuje controller
hodnotu a action
hodnotu.
Několik přetížení Url.Action provede objekt směrovacích hodnot, který poskytuje hodnoty pro parametry trasy jiné než controller
a action
. Objekt hodnot tras se často používá s id
. Například Url.Action("Buy", "Products", new { id = 17 })
. Objekt hodnot trasy:
Všechny další hodnoty tras, které neodpovídají parametrům trasy, se vloží do řetězce dotazu.
public IActionResult Index()
{
var url = Url.Action("Buy", "Products", new { id = 17, color = "red" });
return Content(url!);
}
Předchozí kód vygeneruje /Products/Buy/17?color=red
.
Následující kód vygeneruje absolutní adresu URL:
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!);
}
Pokud chcete vytvořit absolutní adresu URL, použijte jednu z následujících možností:
- Přetížení, které přijímá .
protocol
Například předchozí kód. - LinkGenerator.GetUriByAction, který ve výchozím nastavení generuje absolutní identifikátory URI.
Generování adres URL podle trasy
Předchozí kód demonstroval generování adresy URL předáním názvu kontroleru a akce. IUrlHelper
poskytuje také řadu metod Url.RouteUrl . Tyto metody jsou podobné url.Action, ale nekopírují aktuální hodnoty action
a controller
směrovací hodnoty. Nejběžnější použití Url.RouteUrl
:
- Určuje název trasy pro vygenerování adresy URL.
- Obecně se nezadá název kontroleru ani akce.
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();
}
Následující Razor soubor vygeneruje odkaz HTML na Destination_Route
:
<h1>Test Links</h1>
<ul>
<li><a href="@Url.RouteUrl("Destination_Route")">Test Destination_Route</a></li>
</ul>
Generování adres URL ve formátu HTML a Razor
IHtmlHelperHtmlHelper poskytuje metody Html.BeginForm a Html.ActionLink pro generování <form>
a <a>
elementy v uvedeném pořadí. Tyto metody používají metodu Url.Action k vygenerování adresy URL a přijímají podobné argumenty. Společníci Url.RouteUrl
jsou HtmlHelper
Html.BeginRouteForm
a Html.RouteLink
mají podobné funkce.
TagHelpers generují adresy URL prostřednictvím form
tagHelperu a TagHelperu <a>
. Obě tyto možnosti se používají IUrlHelper
pro jejich implementaci. Další informace najdete v tématu Pomocné rutiny značek ve formulářích .
Uvnitř zobrazení IUrlHelper
je k dispozici prostřednictvím Url
vlastnosti pro jakékoli generování ad hoc adres URL, které nejsou popsány výše.
Generování adres URL ve výsledcích akce
Předchozí příklady ukázaly použití IUrlHelper
v kontroleru. Nejběžnějším použitím kontroleru je vygenerovat adresu URL jako součást výsledku akce.
Controller Základní ControllerBase třídy poskytují metody usnadnění pro výsledky akcí, které odkazují na jinou akci. Jedním z typických použití je přesměrování po přijetí uživatelského vstupu:
[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);
}
Akce výsledky factory metody, jako RedirectToAction CreatedAtAction a sledovat podobný vzor jako metody na IUrlHelper
.
Speciální případ pro vyhrazené konvenční trasy
Konvenční směrování může používat speciální druh definice trasy označované jako vyhrazená konvenční trasa. V následujícím příkladu je pojmenovaná blog
trasa vyhrazená konvenční trasa:
app.MapControllerRoute(name: "blog",
pattern: "blog/{*article}",
defaults: new { controller = "Blog", action = "Article" });
app.MapControllerRoute(name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Pomocí předchozích definic Url.Action("Index", "Home")
tras vygeneruje cestu /
URL pomocí default
trasy, ale proč? Můžete uhodnout, že hodnoty { controller = Home, action = Index }
trasy budou stačit k vygenerování adresy URL pomocí blog
a výsledek bude /blog?action=Index&controller=Home
.
Vyhrazené konvenční trasy spoléhají na speciální chování výchozích hodnot, které nemají odpovídající parametr trasy, který brání příliš greedy trasy při generování adresy URL. V tomto případě jsou { controller = Blog, action = Article }
výchozí hodnoty a ani controller
action
se nezobrazují jako parametr trasy. Při generování adresy URL směrování musí zadané hodnoty odpovídat výchozím hodnotám. Generování adresy URL selhává blog
, protože hodnoty { controller = Home, action = Index }
se neshodovaly { controller = Blog, action = Article }
. Směrování se pak vrátí k vyzkoušení default
, což bude úspěšné.
Oblasti
Oblasti jsou funkce MVC sloužící k uspořádání souvisejících funkcí do skupiny jako samostatné:
- Obor názvů směrování pro akce kontroleru
- Struktura složek pro zobrazení
Použití oblastí umožňuje aplikaci mít více kontrolerů se stejným názvem, pokud mají různé oblasti. Použití oblastí vytvoří hierarchii pro účely směrování přidáním dalšího parametru area
trasy do controller
a action
. Tato část popisuje, jak směrování komunikuje s oblastmi. Podrobnosti o tom, jak se oblasti používají se zobrazeními, najdete v části Oblasti .
Následující příklad nakonfiguruje MVC tak, aby používal výchozí konvenční trasu a trasu area
pro pojmenovanou area
Blog
:
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();
V předchozím kódu je MapAreaControllerRoute volána k vytvoření "blog_route"
. Druhý parametr, "Blog"
je název oblasti.
Při porovnávání cesty URL, jako /Manage/Users/AddUser
je , "blog_route"
trasa generuje hodnoty { area = Blog, controller = Users, action = AddUser }
trasy . Hodnota area
trasy je vytvořena výchozí hodnotou pro area
. Trasa vytvořená MapAreaControllerRoute
pomocí je ekvivalentní následujícímu:
app.MapControllerRoute("blog_route", "Manage/{controller}/{action}/{id?}",
defaults: new { area = "Blog" }, constraints: new { area = "Blog" });
app.MapControllerRoute("default_route", "{controller}/{action}/{id?}");
MapAreaControllerRoute
vytvoří trasu pomocí výchozí hodnoty i omezení pro area
použití zadaného názvu oblasti, v tomto případě Blog
. Výchozí hodnota zajišťuje, že trasa vždy vytvoří { area = Blog, ... }
, omezení vyžaduje hodnotu { area = Blog, ... }
pro generování adresy URL.
Konvenční směrování je závislé na pořadí. Obecně platí, že trasy s oblastmi by měly být umístěny dříve, protože jsou konkrétnější než trasy bez oblasti.
V předchozím příkladu se hodnoty { area = Blog, controller = Users, action = AddUser }
tras shodují s následující akcí:
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}");
}
}
}
Atribut [Area] označuje kontroler jako součást oblasti. Tento kontroler je v Blog
oblasti. Kontrolery bez atributu [Area]
nejsou členy žádné oblasti a neodpovídají, pokud area
je hodnota trasy poskytována směrováním. V následujícím příkladu může pouze první uvedený kontroler odpovídat hodnotám { area = Blog, controller = Users, action = AddUser }
trasy .
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}");
}
}
}
Obor názvů každého kontroleru je zde zobrazen pro úplnost. Pokud předchozí kontrolery používaly stejný obor názvů, vygenerovala by se chyba kompilátoru. Obory názvů tříd nemají žádný vliv na směrování MVC.
První dva kontrolery jsou členy oblastí a shodují se pouze v případě, že je jejich název oblasti zadaný area
hodnotou trasy. Třetí kontroler není členem žádné oblasti a může se shodovat pouze v případě, že směrování neposkytuje žádnou hodnotu area
.
Pokud jde o odpovídající žádnou hodnotu, absence area
hodnoty je stejná, jako kdyby hodnota pro area
hodnotu byla null nebo prázdný řetězec.
Při provádění akce uvnitř oblasti je hodnota area
trasy dostupná jako okolní hodnota pro směrování, která se má použít pro generování adresy URL. To znamená, že ve výchozím nastavení se oblasti chovají jako rychlé pro generování adres URL, jak ukazuje následující ukázka.
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);
}
}
}
Následující kód vygeneruje adresu URL pro /Zebra/Users/AddUser
:
public class HomeController : Controller
{
public IActionResult About()
{
var url = Url.Action("AddUser", "Users", new { Area = "Zebra" });
return Content($"URL: {url}");
}
Definice akce
Veřejné metody v kontroleru s výjimkou těch s atributem NonAction jsou akce.
Ukázkový kód
- MyDisplayRouteInfo poskytuje balíček NuGet Rick.Docs.Samples.RouteInfo a zobrazí informace o trase.
- Zobrazení nebo stažení ukázkového kódu (postup stažení)
Ladění diagnostiky
Podrobný výstup diagnostiky směrování nastavíte Logging:LogLevel:Microsoft
na Debug
hodnotu . Ve vývojovém prostředí nastavte úroveň protokolu v appsettings.Development.json
:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Debug",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
ASP.NET kontrolery Core používají middleware směrování, aby odpovídaly adresám URL příchozích požadavků a mapovaly je na akce. Šablony tras:
- Jsou definovány ve spouštěcím kódu nebo atributech.
- Popište, jak se cesty URL shodují s akcemi.
- Slouží ke generování adres URL pro odkazy. Vygenerované odkazy se obvykle vrací v odpovědích.
Akce jsou buď obvykle směrovány, nebo jsou směrovány atributem. Když umístíte trasu na kontroler nebo akci , bude směrovaná atributem. Další informace najdete v tématu Smíšené směrování .
Tento dokument:
- Vysvětluje interakce mezi MVC a směrováním:
- Jak typické aplikace MVC využívají funkce směrování.
- Probírá obojí:
- Běžné směrování se obvykle používá u kontrolerů a zobrazení.
- Směrování atributů používané s rozhraními REST API Pokud vás zajímá především směrování pro REST rozhraní API, přejděte do části Směrování atributů pro REST rozhraní API .
- Podrobnosti o rozšířeném směrování najdete v tématu Směrování .
- Odkazuje na výchozí systém směrování přidaný v ASP.NET Core 3.0 označovaný jako směrování koncových bodů. Pro účely kompatibility je možné používat kontrolery s předchozí verzí směrování. Pokyny najdete v průvodci migrací verze 2.2-3.0. Referenční materiály pro starší systém směrování najdete ve verzi 2.2 tohoto dokumentu.
Nastavení konvenční trasy
Startup.Configure
Při použití konvenčního směrování má obvykle kód podobný následujícímu:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
Uvnitř volání UseEndpointsMapControllerRoute se používá k vytvoření jedné trasy. Jedna trasa má název default
trasy. Většina aplikací s kontrolery a zobrazeními používá šablonu trasy podobnou default
této trase. REST Rozhraní API by měla používat směrování atributů.
Šablona "{controller=Home}/{action=Index}/{id?}"
trasy:
Odpovídá cestě URL, jako je
/Products/Details/5
Extrahuje hodnoty
{ controller = Products, action = Details, id = 5 }
trasy tokenizací cesty. Extrahování hodnot tras vede ke shodě, pokud má aplikace pojmenovaný kontrolerProductsController
aDetails
akci:public class ProductsController : Controller { public IActionResult Details(int id) { return ControllerContext.MyDisplayRouteInfo(id); } }
MyDisplayRouteInfo poskytuje balíček NuGet Rick.Docs.Samples.RouteInfo a zobrazí informace o trase.
/Products/Details/5
model sváže hodnotuid = 5
nastavení parametruid
na5
. Další podrobnosti najdete v tématu Vazby modelu.{controller=Home}
definujeHome
jako výchozícontroller
.{action=Index}
definujeIndex
jako výchozíaction
.Znak
?
v{id?}
definici jeid
volitelný.Výchozí a volitelné parametry trasy nemusí být v cestě URL pro shodu. Podrobný popis syntaxe šablony trasy najdete v referenčních informacích k šabloně trasy.
Odpovídá cestě
/
URL .Vytvoří hodnoty
{ controller = Home, action = Index }
trasy .
Hodnoty pro controller
výchozí hodnoty a action
jejich použití. id
nevytvoří hodnotu, protože v cestě URL neexistuje žádný odpovídající segment. /
odpovídá pouze v případě, že existuje nějaká HomeController
akce:Index
public class HomeController : Controller
{
public IActionResult Index() { ... }
}
Pomocí předchozí definice kontroleru a šablony trasy se HomeController.Index
akce spustí pro následující cesty URL:
/Home/Index/17
/Home/Index
/Home
/
Cesta /
URL používá výchozí Home
kontrolery a Index
akci šablony trasy. Cesta URL /Home
používá výchozí Index
akci šablony trasy.
Metoda MapDefaultControllerRoutepohodlí:
endpoints.MapDefaultControllerRoute();
Nahrazuje:
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
Důležité
Směrování je nakonfigurováno pomocí UseRoutingnástroje , MapControllerRoute
a MapAreaControllerRoute
middleware . Použití kontrolerů:
- Volání MapControllers uvnitř
UseEndpoints
mapování směrovaných kontrolerů atributů - Volání MapControllerRoute nebo MapAreaControllerRoute, mapovat jak běžně směrované kontrolery, tak i směrované kontrolery atributů.
Konvenční směrování
Konvenční směrování se používá s řadiči a zobrazeními. Trasa default
:
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Předchozí příklad je příkladem konvenční trasy. Říká se tomu konvenční směrování , protože vytváří konvenci pro cesty url:
- První segment cesty ,
{controller=Home}
mapuje na název kontroleru. - Druhý segment,
{action=Index}
, mapuje na název akce . - Třetí segment se používá pro volitelný
id
.{id?}
Hodnota?
in{id?}
je volitelná.id
slouží k mapování na entitu modelu.
Pomocí této default
trasy cesta URL:
/Products/List
se mapuje naProductsController.List
akci./Blog/Article/17
mapujeid
aBlogController.Article
obvykle model sváže parametr na 17.
Toto mapování:
- Je založen pouze na názvech kontroleru a akcí.
- Není založená na oborech názvů, umístěních zdrojových souborů nebo parametrech metody.
Použití konvenčního směrování s výchozí trasou umožňuje vytvořit aplikaci, aniž by bylo nutné pro každou akci vytvořit nový vzor adresy URL. U aplikace s akcemi stylu CRUD mají konzistenci adres URL napříč řadiči:
- Pomáhá zjednodušit kód.
- Zpřístupňuje uživatelské rozhraní předvídatelněji.
Upozorňující
V id
předchozím kódu je definována jako volitelná šablona trasy. Akce se můžou spouštět bez volitelného ID zadaného jako součást adresy URL. Obecně platí, že pokud id
je vynechán z adresy URL:
id
je nastavena0
vazbou modelu.- V porovnávání
id == 0
databáze nebyla nalezena žádná entita .
Směrování atributů poskytuje jemně odstupňované řízení, aby se ID vyžadovalo pro některé akce, a ne pro jiné. Podle konvence obsahuje dokumentace volitelné parametry, jako id
když se pravděpodobně objeví ve správném použití.
Většina aplikací by měla zvolit základní a popisné schéma směrování, aby adresy URL byly čitelné a smysluplné. Výchozí konvenční trasa {controller=Home}/{action=Index}/{id?}
:
- Podporuje základní a popisné schéma směrování.
- Je užitečný výchozí bod pro aplikace založené na uživatelském rozhraní.
- Je jediná šablona trasy potřebná pro mnoho aplikací webového uživatelského rozhraní. U větších aplikací webového uživatelského rozhraní je další trasa využívající oblasti často všechna potřebná.
MapControllerRoute a MapAreaRoute :
- Automaticky přiřaďte jejich koncovým bodům hodnotu objednávky na základě pořadí, ve které jsou vyvolány.
Směrování koncových bodů v ASP.NET Core 3.0 a novější:
- Nemá koncept tras.
- Neposkytuje záruky řazení pro provádění rozšiřitelnosti, všechny koncové body se zpracovávají najednou.
Povolte protokolování , abyste viděli, jak integrované implementace směrování, například Route, odpovídají požadavkům.
Směrování atributů je vysvětleno dále v tomto dokumentu.
Více konvenčních tras
Více konvenčních tras lze přidat dovnitř UseEndpoints
přidáním dalších volání do MapControllerRoute a MapAreaControllerRoute. To umožňuje definovat více konvencí nebo přidat konvenční trasy, které jsou vyhrazené pro konkrétní akci, například:
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?}");
});
Trasa blog
v předchozím kódu je vyhrazená konvenční trasa. Označuje se jako vyhrazená konvenční trasa, protože:
- Používá konvenční směrování.
- Je vyhrazená pro konkrétní akci.
Vzhledem k tomu, controller
že se action
v šabloně "blog/{*article}"
trasy nezobrazují jako parametry:
- Mohou mít pouze výchozí hodnoty
{ controller = "Blog", action = "Article" }
. - Tato trasa se vždy mapuje na akci
BlogController.Article
.
/Blog
, /Blog/Article
a /Blog/{any-string}
jsou jediné cesty URL, které odpovídají trase blogu.
Předchozí příklad:
blog
trasa má vyšší prioritudefault
pro shody než trasa, protože je přidána jako první.- Je příkladem směrování stylu Slug , kde je typické mít název článku jako součást adresy URL.
Upozorňující
V ASP.NET Core 3.0 a novějším směrování ne:
- Definujte koncept označovaný jako trasa.
UseRouting
přidá trasu odpovídající kanálu middlewaru. MiddlewareUseRouting
se podívá na sadu koncových bodů definovaných v aplikaci a vybere nejlepší shodu koncového bodu na základě požadavku. - Poskytovat záruky týkající se pořadí provádění rozšiřitelnosti, jako IRouteConstraint nebo IActionConstraint.
Viz Směrovací materiál pro směrování.
Konvenční pořadí směrování
Konvenční směrování odpovídá pouze kombinaci akce a kontroleru definované aplikací. Cílem je zjednodušit případy, kdy se běžné trasy překrývají.
Přidání tras pomocí MapControllerRoutea MapDefaultControllerRouteMapAreaControllerRoute automatické přiřazení hodnoty objednávky ke svým koncovým bodům na základě pořadí, ve které jsou vyvolány. Shody z trasy, která se zobrazí dříve, mají vyšší prioritu. Konvenční směrování je závislé na pořadí. Obecně platí, že trasy s oblastmi by měly být umístěny dříve, protože jsou konkrétnější než trasy bez oblasti. Vyhrazené konvenční trasy s parametry trasy catch-all, jako {*article}
je může vytvořit trasu příliš greedy, což znamená, že odpovídá adresám URL, které jste chtěli spárovat jinými trasami. Trasu greedy umístěte později do směrovací tabulky, aby se zabránilo shodám greedy.
Upozorňující
Parametr catch-all může nesprávně odpovídat trasám kvůli chybě při směrování. Aplikace ovlivněné touto chybou mají následující charakteristiky:
- Například trasa pro zachytávání– vše
{**slug}"
- Trasa catch-all neodpovídá požadavkům, které by se měly shodovat.
- Odebráním jiných tras začne fungovat zachytávání všech tras.
Podívejte se na chyby GitHubu 18677 a 16579 , například případy, které tuto chybu narazily.
Oprava výslovného souhlasu s touto chybou je obsažená v sadě .NET Core 3.1.301 SDK a novějších verzích. Následující kód nastaví interní přepínač, který tuto chybu opraví:
public static void Main(string[] args)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Routing.UseCorrectCatchAllBehavior",
true);
CreateHostBuilder(args).Build().Run();
}
// Remaining code removed for brevity.
Řešení nejednoznačných akcí
Když se dva koncové body shodují prostřednictvím směrování, musí směrování provést jednu z těchto věcí:
- Vyberte nejlepšího kandidáta.
- Vyvolá výjimku.
Příklad:
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);
}
}
}
Předchozí kontroler definuje dvě akce, které odpovídají:
- Cesta URL
/Products33/Edit/17
- Směrovat data
{ controller = Products33, action = Edit, id = 17 }
.
Toto je typický vzor pro kontrolery MVC:
Edit(int)
zobrazí formulář pro úpravu produktu.Edit(int, Product)
zpracuje vystavený formulář.
Řešení správné trasy:
Edit(int, Product)
je vybrána, pokud je požadavek HTTPPOST
.Edit(int)
je vybrána, pokud je příkaz HTTP cokoli jiného.Edit(int)
je obecně volána prostřednictvímGET
.
, HttpPostAttribute[HttpPost]
je poskytována pro směrování tak, aby mohl zvolit na základě metody HTTP požadavku. Edit(int, Product)
Dělá HttpPostAttribute
lepší shodu než Edit(int)
.
Je důležité pochopit roli atributů, jako HttpPostAttribute
je . Podobné atributy jsou definovány pro jiné příkazy HTTP. U konvenčního směrování je běžné, že akce používají stejný název akce, když jsou součástí formuláře pro zobrazení a odesílají pracovní postup formuláře. Podívejte se například na prozkoumání dvou metod akce Upravit.
Pokud směrování nemůže zvolit nejlepšího kandidáta, vyvolá AmbiguousMatchException se výpis několika odpovídajících koncových bodů.
Konvenční názvy tras
Řetězce a "default"
v následujících příkladech "blog"
jsou konvenční názvy tras:
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?}");
});
Názvy tras dávají této trase logický název. Pojmenovanou trasu lze použít pro generování adres URL. Použití pojmenované trasy zjednodušuje vytváření adres URL, když řazení tras může komplikovat generování adres URL. Názvy tras musí být jedinečné pro celou aplikaci.
Názvy tras:
- Nemá žádný vliv na porovnávání adres URL ani zpracování požadavků.
- Používají se jenom pro generování adres URL.
Koncept názvu trasy je reprezentován ve směrování jako IEndpointNameMetadata. Název trasy termínů a název koncového bodu:
- Jsou zaměnitelné.
- Který z nich se používá v dokumentaci a kódu, závisí na popsaném rozhraní API.
Směrování atributů pro REST rozhraní API
REST Rozhraní API by měla používat směrování atributů k modelování funkčnosti aplikace jako sady prostředků, ve kterých jsou operace reprezentovány příkazy HTTP.
Směrování atributů používá sadu atributů k mapování akcí přímo na šablony směrování. Následující StartUp.Configure
kód je typický pro REST rozhraní API a používá se v další ukázce:
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();
});
}
V předchozím kódu se MapControllers volá uvnitř UseEndpoints
mapovat směrované kontrolery atributů.
V následujícím příkladu:
HomeController
odpovídá sadě adres URL podobných výchozím běžným trasám{controller=Home}/{action=Index}/{id?}
.
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);
}
}
Akce HomeController.Index
se spustí pro některou z cest /
URL , /Home
, /Home/Index
, nebo /Home/Index/3
.
Tento příklad zvýrazňuje klíčový programovací rozdíl mezi směrováním atributů a konvenčním směrováním. Směrování atributů vyžaduje k zadání trasy další vstup. Konvenční výchozí trasa zpracovává trasy rychleji. Směrování atributů však umožňuje a vyžaduje přesnou kontrolu nad tím, které šablony tras se vztahují na každou akci.
Při směrování atributů nehrají názvy kontroleru a akcí žádnou roli, ve které se akce shoduje, pokud se nepoužije nahrazení tokenu. Následující příklad odpovídá stejným adresám URL jako v předchozím příkladu:
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);
}
}
Následující kód používá nahrazení tokenu pro action
a controller
:
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();
}
}
Následující kód se vztahuje [Route("[controller]/[action]")]
na kontroler:
[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();
}
}
V předchozím kódu Index
musí šablony metod předcházet /
nebo ~/
směrovat šablony. Směrovací šablony použité na akci, která začíná /
nebo ~/
se nezkombinuje se šablonami tras použitými na kontroler.
Informace o výběru šablony trasy najdete v tématu Priorita šablony trasy.
Rezervované názvy směrování
Následující klíčová slova jsou vyhrazena názvy parametrů trasy při použití kontrolerů nebo Razor stránek:
action
area
controller
handler
page
Použití page
jako parametru trasy se směrováním atributů je běžnou chybou. Výsledkem je nekonzistentní a matoucí chování při generování adresy URL.
public class MyDemo2Controller : Controller
{
[Route("/articles/{page}")]
public IActionResult ListArticles(int page)
{
return ControllerContext.MyDisplayRouteInfo(page);
}
}
Speciální názvy parametrů používají generování adresy URL k určení, jestli operace generování adresy URL odkazuje na Razor stránku nebo na kontroler.
Následující klíčová slova jsou vyhrazena v kontextu Razor zobrazení nebo Razor stránky:
page
using
namespace
inject
section
inherits
model
addTagHelper
removeTagHelper
Tato klíčová slova by se neměla používat pro generace propojení, parametry vázané na model ani vlastnosti nejvyšší úrovně.
Šablony příkazů HTTP
ASP.NET Core obsahuje následující šablony příkazů HTTP:
Šablony tras
ASP.NET Core má následující šablony tras:
Směrování atributů s atributy příkazů HTTP
Vezměte v úvahu následující kontroler:
[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);
}
}
V předchozím kódu:
- Každá akce obsahuje
[HttpGet]
atribut, který omezuje pouze porovnávání požadavků HTTP GET. - Akce
GetProduct
obsahuje"{id}"
šablonu, protoid
je připojena k"api/[controller]"
šabloně na kontroleru. Šablona metod je"api/[controller]/{id}"
. Tato akce proto odpovídá pouze požadavkům GET pro formulář/api/test2/xyz
,/api/test2/123
,/api/test2/{any string}
, atd.[HttpGet("{id}")] // GET /api/test2/xyz public IActionResult GetProduct(string id) { return ControllerContext.MyDisplayRouteInfo(id); }
- Akce
GetIntProduct
obsahuje"int/{id:int}"
šablonu. Část:int
šablony omezuje směrovacíid
hodnoty na řetězce, které lze převést na celé číslo. Požadavek GET na/api/test2/int/abc
:- Neodpovídá této akci.
- Vrátí chybu 404 Nenalezena.
[HttpGet("int/{id:int}")] // GET /api/test2/int/3 public IActionResult GetIntProduct(int id) { return ControllerContext.MyDisplayRouteInfo(id); }
- Akce
GetInt2Product
obsahuje{id}
v šabloně, ale neomezujeid
na hodnoty, které lze převést na celé číslo. Požadavek GET na/api/test2/int2/abc
:- Odpovídá této trase.
- Vazba modelu se nepodaří převést
abc
na celé číslo. Parametrid
metody je celé číslo. - Vrátí chybu 400 Chybný požadavek , protože vazbu modelu se nepodařilo převést
abc
na celé číslo.[HttpGet("int2/{id}")] // GET /api/test2/int2/3 public IActionResult GetInt2Product(int id) { return ControllerContext.MyDisplayRouteInfo(id); }
Směrování atributů může používat HttpMethodAttribute atributy, jako HttpPostAttributeje , HttpPutAttributea HttpDeleteAttribute. Všechny atributy příkazu HTTP přijímají šablonu trasy. Následující příklad ukazuje dvě akce, které odpovídají stejné šabloně trasy:
[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);
}
}
Pomocí cesty /products3
URL:
- Akce
MyProductsController.ListProducts
se spustí, když jeGET
příkaz HTTP . - Akce
MyProductsController.CreateProduct
se spustí, když jePOST
příkaz HTTP .
Při vytváření REST rozhraní API je vzácné, že budete muset použít [Route(...)]
metodu akce, protože akce přijímá všechny metody HTTP. Lepší je použít konkrétnější atribut příkazu HTTP, aby byl přesný o tom, co vaše rozhraní API podporuje. REST Očekává se, že klienti rozhraní API vědí, jaké cesty a příkazy HTTP se mapují na konkrétní logické operace.
REST Rozhraní API by měla používat směrování atributů k modelování funkčnosti aplikace jako sady prostředků, ve kterých jsou operace reprezentovány příkazy HTTP. To znamená, že mnoho operací, například GET a POST ve stejném logickém prostředku, používá stejnou adresu URL. Směrování atributů poskytuje úroveň řízení, která je nutná k pečlivému návrhu rozložení veřejného koncového bodu rozhraní API.
Vzhledem k tomu, že trasa atributu se vztahuje na konkrétní akci, je snadné nastavit parametry vyžadované jako součást definice šablony trasy. V následujícím příkladu id
se vyžaduje jako součást cesty URL:
[ApiController]
public class Products2ApiController : ControllerBase
{
[HttpGet("/products2/{id}", Name = "Products_List")]
public IActionResult GetProduct(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
}
Akce Products2ApiController.GetProduct(int)
:
- Spouští se s cestou URL, jako je
/products2/3
- Nejde spustit s cestou
/products2
URL .
Atribut [Consumes] umožňuje akci omezit podporované typy obsahu požadavku. Další informace najdete v tématu Definování podporovaných typů obsahu požadavku pomocí atributu Consumes.
Úplný popis šablon tras a souvisejících možností najdete v tématu Směrování .
Další informace o [ApiController]
, viz ApiController atribut.
Název trasy
Následující kód definuje název Products_List
trasy:
[ApiController]
public class Products2ApiController : ControllerBase
{
[HttpGet("/products2/{id}", Name = "Products_List")]
public IActionResult GetProduct(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
}
Názvy tras se dají použít k vygenerování adresy URL na základě konkrétní trasy. Názvy tras:
- Nemá žádný vliv na chování přiřazování adres URL směrování.
- Používají se jenom pro generování adres URL.
Názvy tras musí být jedinečné pro celou aplikaci.
Porovnejte předchozí kód s konvenční výchozí trasou, která definuje id
parametr jako volitelný ({id?}
). Schopnost přesně specifikovat rozhraní API má výhody, jako je povolení /products
a /products/5
odeslání do různých akcí.
Kombinování tras atributů
Aby směrování atributů bylo méně opakované, atributy směrování na kontroleru se zkombinují s atributy trasy u jednotlivých akcí. Všechny šablony tras definované v kontroleru jsou předem nastavené tak, aby směrovaly šablony akcí. Umístění atributu trasy na kontroler provede všechny akce ve směrování atributů kontroleru.
[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);
}
}
V předchozím příkladu:
- Cesta
/products
url se může shodovat.ProductsApi.ListProducts
- Cesta
/products/5
url se může shodovatProductsApi.GetProduct(int)
.
Obě tyto akce odpovídají protokolu HTTP GET
, protože jsou označené atributem [HttpGet]
.
Směrovací šablony použité na akci, která začíná /
nebo ~/
se nezkombinuje se šablonami tras použitými na kontroler. Následující příklad odpovídá sadě cest URL podobných výchozí trase.
[Route("Home")]
public class HomeController : Controller
{
[Route("")]
[Route("Index")]
[Route("/")]
public IActionResult Index()
{
return ControllerContext.MyDisplayRouteInfo();
}
[Route("About")]
public IActionResult About()
{
return ControllerContext.MyDisplayRouteInfo();
}
}
Následující tabulka vysvětluje [Route]
atributy v předchozím kódu:
Atribut | Kombinuje s [Route("Home")] |
Definuje šablonu trasy. |
---|---|---|
[Route("")] |
Ano | "Home" |
[Route("Index")] |
Ano | "Home/Index" |
[Route("/")] |
Ne | "" |
[Route("About")] |
Ano | "Home/About" |
Pořadí tras atributů
Směrování vytvoří strom a odpovídá všem koncovým bodům současně:
- Položky trasy se chovají tak, jako by byly umístěny v ideálním pořadí.
- Nejvýraznější trasy mají možnost spustit před obecnějšími trasami.
Například trasa atributu, jako blog/search/{topic}
je konkrétnější než trasa atributu, jako blog/{*article}
je . Trasa blog/search/{topic}
má ve výchozím nastavení vyšší prioritu, protože je konkrétnější. Pomocí konvenčního směrování zodpovídá vývojář za umístění tras do požadovaného pořadí.
Trasy atributů můžou nakonfigurovat pořadí pomocí Order vlastnosti. Všechny atributy trasy poskytované architekturou zahrnují Order
. Trasy se zpracovávají podle vzestupného řazení Order
vlastnosti. Výchozí pořadí je 0
. Nastavení trasy pomocí Order = -1
spuštění před trasami, které nenastavují pořadí Nastavení trasy pomocí Order = 1
spuštění po výchozím pořadí tras
Vyhněte se v závislosti na Order
. Pokud prostor adres URL aplikace vyžaduje správné směrování explicitních hodnot objednávek, pravděpodobně je také matoucí pro klienty. Obecně platí, že směrování atributů vybere správnou trasu s odpovídající adresou URL. Pokud výchozí pořadí použité pro generování adresy URL nefunguje, použití názvu trasy jako přepsání je obvykle jednodušší než použití Order
vlastnosti.
Vezměte v úvahu následující dva kontrolery, které definují porovnávání /home
tras:
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
Požadavek s předchozím kódem vyvolá výjimku podobnou následující:
AmbiguousMatchException: The request matched multiple endpoints. Matches:
WebMvcRouting.Controllers.HomeController.Index
WebMvcRouting.Controllers.MyDemoController.MyIndex
Přidání Order
do jednoho z atributů trasy vyřeší nejednoznačnost:
[Route("")]
[Route("Home", Order = 2)]
[Route("Home/MyIndex")]
public IActionResult MyIndex()
{
return ControllerContext.MyDisplayRouteInfo();
}
S předchozím kódem /home
spustí HomeController.Index
koncový bod. Chcete-li se dostat k MyDemoController.MyIndex
žádosti /home/MyIndex
. Poznámka:
- Předchozí kód je příkladem nebo špatným návrhem směrování. Byla použita k ilustraci
Order
vlastnosti. - Vlastnost
Order
přeloží pouze nejednoznačnost, kterou nelze shodovat. Bylo by lepší šablonu odebrat[Route("Home")]
.
Viz Razor Zásady směrování stránek a aplikací: Pořadí tras pro informace o pořadí tras pomocí Razor stránek.
V některých případech se vrátí chyba HTTP 500 s nejednoznačnými trasami. Pomocí protokolování zjistíte, které koncové body způsobily AmbiguousMatchException
.
Výměna tokenů v šablonách tras [kontroler], [akce], [oblast]
Pro usnadnění práce trasy atributů podporují nahrazení tokenu uzavřením tokenu do hranatých závorek ([
, ]
). Tokeny , [area]
a [controller]
jsou nahrazeny [action]
hodnotami názvu akce, název oblasti a název kontroleru z akce, kde je trasa definována:
[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);
}
}
V předchozím kódu:
[HttpGet]
public IActionResult List()
{
return ControllerContext.MyDisplayRouteInfo();
}
- Zápasy
/Products0/List
[HttpGet("{id}")]
public IActionResult Edit(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
- Zápasy
/Products0/Edit/{id}
Nahrazení tokenu probíhá jako poslední krok sestavení tras atributů. Předchozí příklad se chová stejně jako následující kód:
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);
}
}
Pokud to čtete v jiném jazyce než v angličtině, dejte nám vědět v tomto problému s diskuzí na GitHubu, pokud chcete vidět komentáře ke kódu ve vašem nativním jazyce.
Trasy atributů lze také kombinovat s dědičností. Jedná se o výkonnou kombinaci s nahrazením tokenů. Nahrazení tokenu se vztahuje také na názvy tras definovaných trasami atributů.
[Route("[controller]/[action]", Name="[controller]_[action]")]
vygeneruje jedinečný název trasy pro každou akci:
[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);
}
}
Chcete-li se shodovat s oddělovačem [
nahrazení literálového tokenu nebo ]
ho umistit opakováním znaku ([[
nebo ]]
).
Přizpůsobení nahrazení tokenu pomocí transformátoru parametrů
Nahrazení tokenů lze přizpůsobit pomocí transformátoru parametrů. Transformátor parametrů implementuje IOutboundParameterTransformer a transformuje hodnotu parametrů. Například vlastní SlugifyParameterTransformer
transformátor parametru SubscriptionManagement
změní hodnotu trasy na subscription-management
:
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();
}
}
Jedná se RouteTokenTransformerConvention o konvenci modelu aplikace, která:
- Použije transformátor parametrů na všechny trasy atributů v aplikaci.
- Přizpůsobí hodnoty tokenu trasy atributu při jejich nahrazení.
public class SubscriptionManagementController : Controller
{
[HttpGet("[controller]/[action]")]
public IActionResult ListAll()
{
return ControllerContext.MyDisplayRouteInfo();
}
}
Předchozí ListAll
metoda odpovídá /subscription-management/list-all
.
Je RouteTokenTransformerConvention
registrován jako možnost v ConfigureServices
.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews(options =>
{
options.Conventions.Add(new RouteTokenTransformerConvention(
new SlugifyParameterTransformer()));
});
}
Definice Slug najdete ve webové dokumentaci MDN na Slug .
Upozorňující
Při zpracování System.Text.RegularExpressions nedůvěryhodného vstupu předejte vypršení časového limitu. Uživatel se zlými úmysly může poskytnout vstup, který RegularExpressions
způsobí útok na dostupnost služby. ASP.NET rozhraní API architektury Core, která používají RegularExpressions
vypršení časového limitu.
Více tras atributů
Směrování atributů podporuje definování více tras, které se dostanou ke stejné akci. Nejběžnějším použitím je napodobit chování výchozí konvenční trasy, jak je znázorněno v následujícím příkladu:
[Route("[controller]")]
public class Products13Controller : Controller
{
[Route("")] // Matches 'Products13'
[Route("Index")] // Matches 'Products13/Index'
public IActionResult Index()
{
return ControllerContext.MyDisplayRouteInfo();
}
Umístění více atributů směrování na kontroler znamená, že každý z nich kombinuje s jednotlivými atributy trasy v metodách akce:
[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();
}
}
Implementují IActionConstraint
se všechna omezení směrování příkazů HTTP .
Pokud je u akce umístěno více atributů trasy, které se implementují IActionConstraint :
- Každé omezení akce kombinuje šablonu trasy použitou na kontroler.
[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();
}
}
Použití více tras u akcí může vypadat jako užitečné a výkonné, je lepší zachovat základní a dobře definovaný prostor adres URL vaší aplikace. Pro akce používejte více tras pouze tam, kde je to potřeba, například pro podporu stávajících klientů.
Určení volitelných parametrů trasy atributů, výchozích hodnot a omezení
Trasy atributů podporují stejnou vloženou syntaxi jako běžné trasy a určují volitelné parametry, výchozí hodnoty a omezení.
public class Products14Controller : Controller
{
[HttpPost("product14/{id:int}")]
public IActionResult ShowProduct(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
}
V předchozím kódu [HttpPost("product14/{id:int}")]
použije omezení trasy. Akce Products14Controller.ShowProduct
se shoduje pouze s cestami URL, jako je /product14/3
. Část šablony {id:int}
trasy omezuje tento segment pouze na celá čísla.
Podrobný popis syntaxe šablony trasy najdete v referenčních informacích k šabloně trasy.
Vlastní atributy trasy pomocí IRouteTemplateProvider
Všechny atributy trasy implementují IRouteTemplateProvider. Modul runtime ASP.NET Core:
- Vyhledá atributy tříd kontroleru a metod akcí při spuštění aplikace.
- Používá atributy, které implementují
IRouteTemplateProvider
k sestavení počáteční sady tras.
Implementujte IRouteTemplateProvider
definování vlastních atributů trasy. Každá IRouteTemplateProvider
umožňuje definovat jednu trasu s vlastní šablonou trasy, pořadím a názvem:
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();
}
}
Předchozí Get
metoda vrátí Order = 2, Template = api/MyTestApi
.
Přizpůsobení tras atributů pomocí aplikačního modelu
Aplikační model:
- Je objektový model vytvořený při spuštění.
- Obsahuje všechna metadata používaná ASP.NET Core ke směrování a provádění akcí v aplikaci.
Aplikační model zahrnuje všechna data shromážděná z atributů trasy. Implementace poskytuje IRouteTemplateProvider
data z atributů trasy. Konvence:
- Lze napsat a upravit aplikační model tak, aby přizpůsobil chování směrování.
- Čtou se při spuštění aplikace.
Tato část ukazuje základní příklad přizpůsobení směrování pomocí aplikačního modelu. Následující kód vytváří trasy zhruba zarovná do struktury složek projektu.
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()
};
}
}
}
Následující kód zabraňuje namespace
použití konvence na kontrolery, které jsou směrovány atributem:
public void Apply(ControllerModel controller)
{
var hasRouteAttributes = controller.Selectors.Any(selector =>
selector.AttributeRouteModel != null);
if (hasRouteAttributes)
{
return;
}
Například následující kontroler nepoužívá 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}");
}
}
Metoda NamespaceRoutingConvention.Apply
:
- Nedělá nic, pokud je kontroler směrován atributem.
- Nastaví šablonu kontrolerů na
namespace
základě , s odebranou základnounamespace
.
Lze použít NamespaceRoutingConvention
v Startup.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.
Představte si například následující kontroler:
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}");
}
}
}
V předchozím kódu:
- Základ
namespace
jeMy.Application
. - Úplný název předchozího kontroleru je
My.Application.Admin.Controllers.UsersController
. - Nastaví
NamespaceRoutingConvention
šablonu kontrolerů naAdmin/Controllers/Users/[action]/{id?
.
Dá NamespaceRoutingConvention
se také použít jako atribut na kontroleru:
[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}");
}
}
Smíšené směrování: Směrování atributů vs. konvenční směrování
ASP.NET základní aplikace můžou kombinovat použití konvenčního směrování a směrování atributů. Pro kontrolery obsluhující stránky HTML pro prohlížeče a směrování atributů pro kontrolery, které obsluhují REST rozhraní API, je typické použití konvenčních tras.
Akce se směrují buď konvenčně, nebo jsou směrovány atributem. Umístěním trasy na kontroler nebo akci se směruje atribut. Akce, které definují trasy atributů, nelze dosáhnout prostřednictvím konvenčních tras a naopak. Jakýkoli atribut trasy na kontroleru provede všechny akce ve směrovaném atributu kontroleru.
Směrování atributů a konvenční směrování používají stejný směrovací modul.
Generování adres URL a okolní hodnoty
Aplikace můžou pomocí funkcí generování adres URL směrování generovat odkazy na adresy URL na akce. Generování adres URL eliminuje pevně zakódované adresy URL, což zpřístupňuje kód robustnějším a udržovatelným. Tato část se zaměřuje na funkce generování adres URL, které poskytuje MVC, a zabývá se jenom základy fungování generování adres URL. Podrobný popis generování adres URL najdete v tématu Směrování .
Rozhraní IUrlHelper je základní prvek infrastruktury mezi MVC a směrováním pro generování adres URL. Instance IUrlHelper
je k dispozici prostřednictvím Url
vlastnosti v kontrolerů, zobrazeních a komponentách zobrazení.
V následujícím příkladu se IUrlHelper
rozhraní používá prostřednictvím Controller.Url
vlastnosti k vygenerování adresy URL jiné akce.
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();
}
}
Pokud aplikace používá výchozí konvenční trasu, hodnota url
proměnné je řetězec /UrlGeneration/Destination
cesty url . Tuto cestu URL vytvoří směrováním zkombinováním:
- Směrovací hodnoty z aktuálního požadavku, které se nazývají okolní hodnoty.
- Hodnoty předané
Url.Action
a nahrazující tyto hodnoty do šablony trasy:
ambient values: { controller = "UrlGeneration", action = "Source" }
values passed to Url.Action: { controller = "UrlGeneration", action = "Destination" }
route template: {controller}/{action}/{id?}
result: /UrlGeneration/Destination
Každý parametr trasy v šabloně trasy má hodnotu nahrazenou odpovídajícími názvy s hodnotami a okolními hodnotami. Parametr trasy, který nemá hodnotu, může:
- Pokud má výchozí hodnotu, použijte ji.
- Pokud je nepovinný, přeskočí se. Například
id
ze šablony{controller}/{action}/{id?}
trasy .
Generování adresy URL selže, pokud některý parametr požadované trasy nemá odpovídající hodnotu. Pokud generování adresy URL pro trasu selže, zkusí se další trasa, dokud se nezkouší všechny trasy nebo se nenajde shoda.
Předchozí příklad Url.Action
předpokládá konvenční směrování. Generování adres URL funguje podobně se směrováním atributů, i když se koncepty liší. S konvenčním směrováním:
- Hodnoty tras slouží k rozbalení šablony.
- Hodnoty tras pro
controller
aaction
obvykle se v této šabloně zobrazují. To funguje, protože adresy URL odpovídající směrováním dodržují konvenci.
Následující příklad používá směrování atributů:
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();
}
}
Akce Source
v předchozím kódu vygeneruje custom/url/to/destination
.
LinkGenerator byl přidán v ASP.NET Core 3.0 jako alternativu k IUrlHelper
. LinkGenerator
nabízí podobné, ale flexibilnější funkce. Každá metoda má IUrlHelper
také odpovídající řadu metod LinkGenerator
.
Generování adres URL podle názvu akce
Url.Action, LinkGenerator.GetPathByAction a všechna související přetížení jsou navržena tak, aby vygenerovala cílový koncový bod zadáním názvu kontroleru a názvu akce.
Pokud používáte Url.Action
, aktuální hodnoty tras pro controller
a action
jsou poskytovány modulem runtime:
- Hodnota
controller
aaction
jsou součástí okolních hodnot i hodnot. MetodaUrl.Action
vždy používá aktuální hodnotyaction
acontroller
generuje cestu URL, která směruje na aktuální akci.
Směrování se pokusí použít hodnoty v okolních hodnotách k vyplnění informací, které nebyly poskytnuty při generování adresy URL. Představte si trasu jako {a}/{b}/{c}/{d}
s okolními hodnotami { a = Alice, b = Bob, c = Carol, d = David }
:
- Směrování má dostatek informací k vygenerování adresy URL bez dalších hodnot.
- Směrování má dostatek informací, protože všechny parametry trasy mají hodnotu.
Pokud se hodnota { d = Donovan }
přidá:
- Hodnota
{ d = David }
se ignoruje. - Vygenerovaná cesta URL je
Alice/Bob/Carol/Donovan
.
Upozornění: Cesty url jsou hierarchické. Pokud se v předchozím příkladu přidá hodnota { c = Cheryl }
:
- Obě hodnoty
{ c = Carol, d = David }
jsou ignorovány. - Generování adresy URL už nemá hodnotu
d
a generování adresy URL se nezdaří. - Požadované hodnoty
c
ad
musí být zadány pro vygenerování adresy URL.
U výchozí trasy {controller}/{action}/{id?}
můžete očekávat, že dojde k tomuto problému . Tento problém je v praxi vzácný, protože Url.Action
vždy explicitně určuje controller
hodnotu a action
hodnotu.
Několik přetížení Url.Action provede objekt směrovacích hodnot, který poskytuje hodnoty pro parametry trasy jiné než controller
a action
. Objekt hodnot tras se často používá s id
. Například Url.Action("Buy", "Products", new { id = 17 })
. Objekt hodnot trasy:
Všechny další hodnoty tras, které neodpovídají parametrům trasy, se vloží do řetězce dotazu.
public IActionResult Index()
{
var url = Url.Action("Buy", "Products", new { id = 17, color = "red" });
return Content(url);
}
Předchozí kód vygeneruje /Products/Buy/17?color=red
.
Následující kód vygeneruje absolutní adresu URL:
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);
}
Pokud chcete vytvořit absolutní adresu URL, použijte jednu z následujících možností:
- Přetížení, které přijímá .
protocol
Například předchozí kód. - LinkGenerator.GetUriByAction, který ve výchozím nastavení generuje absolutní identifikátory URI.
Generování adres URL podle trasy
Předchozí kód demonstroval generování adresy URL předáním názvu kontroleru a akce. IUrlHelper
poskytuje také řadu metod Url.RouteUrl . Tyto metody jsou podobné url.Action, ale nekopírují aktuální hodnoty action
a controller
směrovací hodnoty. Nejběžnější použití Url.RouteUrl
:
- Určuje název trasy pro vygenerování adresy URL.
- Obecně se nezadá název kontroleru ani akce.
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();
}
Následující Razor soubor vygeneruje odkaz HTML na Destination_Route
:
<h1>Test Links</h1>
<ul>
<li><a href="@Url.RouteUrl("Destination_Route")">Test Destination_Route</a></li>
</ul>
Generování adres URL ve formátu HTML a Razor
IHtmlHelperHtmlHelper poskytuje metody Html.BeginForm a Html.ActionLink pro generování <form>
a <a>
elementy v uvedeném pořadí. Tyto metody používají metodu Url.Action k vygenerování adresy URL a přijímají podobné argumenty. Společníci Url.RouteUrl
jsou HtmlHelper
Html.BeginRouteForm
a Html.RouteLink
mají podobné funkce.
TagHelpers generují adresy URL prostřednictvím form
tagHelperu a TagHelperu <a>
. Obě tyto možnosti se používají IUrlHelper
pro jejich implementaci. Další informace najdete v tématu Pomocné rutiny značek ve formulářích .
Uvnitř zobrazení IUrlHelper
je k dispozici prostřednictvím Url
vlastnosti pro jakékoli generování ad hoc adres URL, které nejsou popsány výše.
Generování adres URL ve výsledcích akce
Předchozí příklady ukázaly použití IUrlHelper
v kontroleru. Nejběžnějším použitím kontroleru je vygenerovat adresu URL jako součást výsledku akce.
Controller Základní ControllerBase třídy poskytují metody usnadnění pro výsledky akcí, které odkazují na jinou akci. Jedním z typických použití je přesměrování po přijetí uživatelského vstupu:
[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);
}
Akce výsledky factory metody, jako RedirectToAction CreatedAtAction a sledovat podobný vzor jako metody na IUrlHelper
.
Speciální případ pro vyhrazené konvenční trasy
Konvenční směrování může používat speciální druh definice trasy označované jako vyhrazená konvenční trasa. V následujícím příkladu je pojmenovaná blog
trasa vyhrazená konvenční trasa:
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?}");
});
Pomocí předchozích definic Url.Action("Index", "Home")
tras vygeneruje cestu /
URL pomocí default
trasy, ale proč? Můžete uhodnout, že hodnoty { controller = Home, action = Index }
trasy budou stačit k vygenerování adresy URL pomocí blog
a výsledek bude /blog?action=Index&controller=Home
.
Vyhrazené konvenční trasy spoléhají na speciální chování výchozích hodnot, které nemají odpovídající parametr trasy, který brání příliš greedy trasy při generování adresy URL. V tomto případě jsou { controller = Blog, action = Article }
výchozí hodnoty a ani controller
action
se nezobrazují jako parametr trasy. Při generování adresy URL směrování musí zadané hodnoty odpovídat výchozím hodnotám. Generování adresy URL selhává blog
, protože hodnoty { controller = Home, action = Index }
se neshodovaly { controller = Blog, action = Article }
. Směrování se pak vrátí k vyzkoušení default
, což bude úspěšné.
Oblasti
Oblasti jsou funkce MVC sloužící k uspořádání souvisejících funkcí do skupiny jako samostatné:
- Obor názvů směrování pro akce kontroleru
- Struktura složek pro zobrazení
Použití oblastí umožňuje aplikaci mít více kontrolerů se stejným názvem, pokud mají různé oblasti. Použití oblastí vytvoří hierarchii pro účely směrování přidáním dalšího parametru area
trasy do controller
a action
. Tato část popisuje, jak směrování komunikuje s oblastmi. Podrobnosti o tom, jak se oblasti používají se zobrazeními, najdete v části Oblasti .
Následující příklad nakonfiguruje MVC tak, aby používal výchozí konvenční trasu a trasu area
pro pojmenovanou area
Blog
:
app.UseEndpoints(endpoints =>
{
endpoints.MapAreaControllerRoute("blog_route", "Blog",
"Manage/{controller}/{action}/{id?}");
endpoints.MapControllerRoute("default_route", "{controller}/{action}/{id?}");
});
V předchozím kódu je MapAreaControllerRoute volána k vytvoření "blog_route"
. Druhý parametr, "Blog"
je název oblasti.
Při porovnávání cesty URL, jako /Manage/Users/AddUser
je , "blog_route"
trasa generuje hodnoty { area = Blog, controller = Users, action = AddUser }
trasy . Hodnota area
trasy je vytvořena výchozí hodnotou pro area
. Trasa vytvořená MapAreaControllerRoute
pomocí je ekvivalentní následujícímu:
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
vytvoří trasu pomocí výchozí hodnoty i omezení pro area
použití zadaného názvu oblasti, v tomto případě Blog
. Výchozí hodnota zajišťuje, že trasa vždy vytvoří { area = Blog, ... }
, omezení vyžaduje hodnotu { area = Blog, ... }
pro generování adresy URL.
Konvenční směrování je závislé na pořadí. Obecně platí, že trasy s oblastmi by měly být umístěny dříve, protože jsou konkrétnější než trasy bez oblasti.
V předchozím příkladu se hodnoty { area = Blog, controller = Users, action = AddUser }
tras shodují s následující akcí:
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}");
}
}
}
Atribut [Area] označuje kontroler jako součást oblasti. Tento kontroler je v Blog
oblasti. Kontrolery bez atributu [Area]
nejsou členy žádné oblasti a neodpovídají, pokud area
je hodnota trasy poskytována směrováním. V následujícím příkladu může pouze první uvedený kontroler odpovídat hodnotám { area = Blog, controller = Users, action = AddUser }
trasy .
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}");
}
}
}
Obor názvů každého kontroleru je zde zobrazen pro úplnost. Pokud předchozí kontrolery používaly stejný obor názvů, vygenerovala by se chyba kompilátoru. Obory názvů tříd nemají žádný vliv na směrování MVC.
První dva kontrolery jsou členy oblastí a shodují se pouze v případě, že je jejich název oblasti zadaný area
hodnotou trasy. Třetí kontroler není členem žádné oblasti a může se shodovat pouze v případě, že směrování neposkytuje žádnou hodnotu area
.
Pokud jde o odpovídající žádnou hodnotu, absence area
hodnoty je stejná, jako kdyby hodnota pro area
hodnotu byla null nebo prázdný řetězec.
Při provádění akce uvnitř oblasti je hodnota area
trasy dostupná jako okolní hodnota pro směrování, která se má použít pro generování adresy URL. To znamená, že ve výchozím nastavení se oblasti chovají jako rychlé pro generování adres URL, jak ukazuje následující ukázka.
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);
}
}
}
Následující kód vygeneruje adresu URL pro /Zebra/Users/AddUser
:
public class HomeController : Controller
{
public IActionResult About()
{
var url = Url.Action("AddUser", "Users", new { Area = "Zebra" });
return Content($"URL: {url}");
}
Definice akce
Veřejné metody v kontroleru s výjimkou těch s atributem NonAction jsou akce.
Ukázkový kód
- MyDisplayRouteInfo poskytuje balíček NuGet Rick.Docs.Samples.RouteInfo a zobrazí informace o trase.
- Zobrazení nebo stažení ukázkového kódu (postup stažení)
Ladění diagnostiky
Podrobný výstup diagnostiky směrování nastavíte Logging:LogLevel:Microsoft
na Debug
hodnotu . Ve vývojovém prostředí nastavte úroveň protokolu v appsettings.Development.json
:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Debug",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}