Směrování na akce kontroleru v ASP.NET Core
Služba Ryan Nowak, Kirka Larkina Rick Anderson
řadiče ASP.NET Core používají middleware směrování ke spárování adres url příchozích požadavků a jejich mapování na akce. Šablony směrování:
- Jsou definovány při spuštění v programu program. cs nebo v atributech.
- Popisuje, jak se shodují cesty URL k akcím.
- Slouží ke generování adres URL pro odkazy. Vygenerované odkazy jsou obvykle vraceny v odpovědích.
Akce jsou směrovány buď podle konvence , nebo podle atributů. Umístěním trasy do kontroleru nebo Akce se nastaví směrování atributů. 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í.
- Pokrývá obojí:
- Konvenční směrování se obvykle používá s řadiči a zobrazeními.
- Směrování atributů používané s rozhraními REST API. Pokud se primárně zajímáte o směrování pro rozhraní REST API, přejděte na oddíl Směrování atributů pro rozhraní REST 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í nazývaný směrování koncového bodu. Pro účely kompatibility je možné použít řadiče s předchozí verzí směrování. Pokyny najdete v příručce k migraci 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 Route. Většina aplikací s řadiči a zobrazeními používá šablonu směrování podobnou default trase. Rozhraní REST API by měly používat Směrování atributů.
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Šablona trasy "{controller=Home}/{action=Index}/{id?}" :
Odpovídá cestě URL jako
/Products/Details/5Extrahuje hodnoty tras
{ controller = Products, action = Details, id = 5 }tím, že tokenizací cestu. Výsledkem extrakce hodnot tras je shoda, pokud má aplikace kontroler s názvemProductsControlleraDetailsakci:public class ProductsController : Controller { public IActionResult Details(int id) { return ControllerContext.MyDisplayRouteInfo(id); } }MyDisplayRouteInfo poskytuje balíček NuGet Rick.Docs.Samples.RouteInfo a zobrazuje informace o trasách.
/Products/Details/5model váže hodnotuid = 5pro nastaveníidparametru5. Další podrobnosti najdete v tématu vazba modelu .{controller=Home}definujeHomejako výchozícontroller.{action=Index}definujeIndexjako výchozíaction.?Znak v{id?}definujeidjako volitelné.Výchozí a volitelné parametry směrování nemusejí být v cestě URL pro porovnávání k dispozici. Podrobný popis syntaxe šablony směrování naleznete v tématu Referenční dokumentace k šabloně směrování .
Odpovídá cestě URL
/.Vytvoří hodnoty trasy
{ controller = Home, action = Index }.
Hodnoty pro controller a action využívají výchozí hodnoty. id nevytváří hodnotu, protože v cestě URL není žádný odpovídající segment. / odpovídá pouze v případě, že HomeController existuje Index akce a:
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 řadiče a akci šablony směrování Index . Cesta URL /Home používá výchozí akci šablony směrování Index .
Způsob usnadnění MapDefaultControllerRoute :
app.MapDefaultControllerRoute();
LPRMON
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Důležité
Směrování je nakonfigurované pomocí UseRouting UseEndpoints middlewaru a. Použití řadičů:
- Volá MapControllers se, aby se namapovaly řadiče směrovaného atributu .
- Zavolejte MapControllerRoute nebo MapAreaControllerRoute , pokud chcete namapovat obě konvence směrované na řadiče a ovladače směrovaného atributu .
Konvenční směrování
Konvenční směrování se používá s řadiči a zobrazeními. defaultTrasa:
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Předchozí je příklad konvenční trasy. Nazývá se 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
{id?}je použit pro volitelnéid. V nástroji je?{id?}volitelné.idslouží k mapování na entitu modelu.
Pomocí této default trasy adresa URL:
/Products/Listprovede mapování naProductsController.Listakci./Blog/Article/17mapuje naBlogController.Articlemodel a obvykle model vážeidparametr na 17.
Toto mapování:
- Je založena pouze na názvech kontroléru a Akce .
- Není založen na oborech názvů, umístěních zdrojového souboru nebo parametrech metody.
Použití konvenčního směrování s výchozí trasou umožňuje vytvoření aplikace bez nutnosti sestavovat nový vzor adresy URL pro každou akci. Pro aplikaci s akcemi stylu CRUD s konzistencí pro adresy URL napříč řadiči:
- Pomáhá zjednodušit kód.
- Provede více předvídatelného uživatelského rozhraní.
Upozornění
idV předchozím kódu je šablona trasy definována jako volitelná. Akce se můžou provádět bez volitelného ID, které jste zadali jako součást adresy URL. Obecně platí, že pokud id je vynechána adresa URL:
idje nastaven na0základě vazby modelu.- V porovnání s databází nebyla nalezena žádná entita
id == 0.
Směrování atributů poskytuje jemně odstupňovaný ovládací prvek, který umožňuje, aby se ID vyžadovalo u některých akcí, a ne pro ostatní. V dokumentaci podle konvence obsahuje volitelné parametry, jako id když se pravděpodobně budou zobrazovat ve správném použití.
Většina aplikací by měla zvolit základní a popisné schéma směrování, aby byly adresy URL č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ým výchozím bodem pro aplikace založené na uživatelském rozhraní.
- Je jedinou šablonou směrování, která je nutná pro mnoho webových aplikací uživatelského rozhraní. Pro větší webové uživatelské rozhraní jsou jiné trasy, které používají oblasti , často všechny potřebné.
MapControllerRoute a MapAreaRoute :
- Automatické přiřazení hodnoty objednávky ke svým koncovým bodům podle pořadí, ve kterém jsou vyvolány.
Směrování koncového bodu v ASP.NET Core:
- Nemá koncept tras.
- Neposkytuje zaručené řazení pro provádění rozšiřitelnosti, všechny koncové body jsou zpracovávány současně.
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.
Několik konvenčních tras
V rámci lze přidat více konvenčních tras UseEndpoints přidáním dalších volání do MapControllerRoute a MapAreaControllerRoute . To umožňuje definovat více konvencí nebo přidávat konvenční trasy, které jsou vyhrazeny určité 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?}");
blogTrasa v předchozím kódu je vyhrazená konvenční trasa. Nazývá se vyhrazená konvenční trasa z těchto důvodů:
Protože controller a se v action šabloně trasy nezobrazují "blog/{*article}" 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 jsou jediné cesty /Blog/{any-string} URL, které odpovídají trase blogu.
Předchozí příklad:
blogTrasa má vyšší prioritu pro shody neždefaulttrasa, protože se přidá jako první.- Je příkladem směrování ve stylu Slug, kde je typické, že jako součást adresy URL je název článku.
Upozornění
V ASP.NET Core směrování:
- Definujte koncept, který se nazývá trasa.
UseRoutingpřidá do middlewarového kanálu párování tras. Middleware se podívá na sadu koncových bodů definovaných v aplikaci a vybere nejlepší shodu koncovéhoUseRoutingbodu na základě požadavku. - Poskytovat záruky týkající se pořadí provádění rozšiřitelnosti, jako IRouteConstraint je nebo IActionConstraint .
Viz Směrování referenčních materiálů při směrování.
Konvenční pořadí směrování
Konvenční směrování odpovídá pouze kombinaci akce a kontroleru, které jsou definovány aplikací. Cílem je zjednodušit případy, kdy se konvenční trasy překrývají.
Přidání tras pomocí , a automaticky přiřadí hodnotu objednávky koncovým bodům na základě MapControllerRoute MapDefaultControllerRoute MapAreaControllerRoute 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 se měly umisťovat dříve, protože jsou konkrétnější než trasy bez oblasti. Vyhrazené konvenční trasy s parametry zachytání všech tras, jako je , znamenají, že trasa je příliš greedy, což znamená, že odpovídá adresám URL, které by se měly spárovat s {*article} jinými trasami. Trasy greedy umístěte do směrovací tabulky později, aby se zabránilo shodám s greedy.
Upozornění
Parametr catch-All může nesprávně odpovídat trasy z důvodu chyby v směrování. Aplikace ovlivněné touto chybou mají následující vlastnosti:
- Například trasa typu catch-ALL.
{**slug}" - Trasa catch-All nesplňuje požadavky, které by se měla shodovat.
- Při odebrání jiných tras bude vše začít pracovat.
Příklady přístupů k této chybě najdete v tématu chyby GitHubu 18677 a 16579 .
Oprava pro tuto chybu je obsažená v sadě .NET Core 3.1.301 SDK a novější. Následující kód nastaví interní přepínač, který vyřeší tuto chybu:
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í
Pokud se při směrování shodují dva koncové body, směrování musí provést jednu z následujících akcí:
- Zvolte nejlepšího kandidáta.
- Vyvolá výjimku.
Napří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 zveřejněný formulář.
Pokud chcete vyřešit správnou trasu:
Edit(int, Product)se vybere, pokud je požadavkem httpPOST.Edit(int)se vybere, pokud příkaz HTTP je cokoli jiného.Edit(int)se obvykle volá prostřednictvímGET.
, HttpPostAttribute [HttpPost] , je k dispozici pro směrování, aby mohl zvolit na základě metody HTTP požadavku. HttpPostAttributeJe lepší Edit(int, Product) shoda než Edit(int) .
Je důležité pochopit roli atributů, jako je HttpPostAttribute . Podobné atributy jsou definované pro jiné příkazy HTTP. Při konvenčnímsměrování je běžné, že akce používají stejný název akce, pokud jsou součástí formuláře pro zobrazení, a pracovní postup odeslání formuláře. Příklad najdete v tématu Prozkoumání dvou metod akce Upravit.
Pokud směrování nemůže zvolit nejlepšího kandidáta, vyvolá se objekt se seznamem AmbiguousMatchException několika shodných koncových bodů.
Názvy konvenčních tras
Řetězce a "blog" "default" v následujících příkladech jsou názvy konvenčních 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í trase logický název. Pojmenovanou trasu lze použít pro generování adres URL. Použití pojmenované trasy zjednodušuje vytváření adres URL, pokud by se při řazení tras mohlo generování adres URL komplikovat. Názvy tras musí být jedinečné pro celou aplikaci.
Názvy tras:
- Nemají žádný vliv na párování adres URL ani zpracování požadavků.
- Používají se pouze pro generování adres URL.
Koncept názvu trasy je ve směrování reprezentován jako IEndpointNameMetadata. Pojmy název trasy a název koncového bodu:
- Jsou zaměnitelné.
- To, které se používá v dokumentaci a kódu, závisí na popsaném rozhraní API.
Směrování atributů pro rozhraní REST API
Rozhraní REST API by měla používat směrování atributů k modelování funkcí aplikace jako sady prostředků, ve kterých jsou operace reprezentované 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 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 volá uvnitř pro mapování MapControllers UseEndpoints kontrolerů směrovaných podle atributů.
V následujícím příkladu:
HomeControllerodpovídá sadě adres URL, které odpovídají výchozí konvenční{controller=Home}/{action=Index}/{id?}trase.
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 libovolnou cestu URL , , nebo / /Home /Home/Index /Home/Index/3 .
Tento příklad zvýrazní 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 více vstupů pro určení trasy. Konvenční výchozí trasa zpracovává trasy výstižněji. Směrování atributů ale umožňuje a vyžaduje přesnou kontrolu nad tím, které šablony tras se u každé akce použijí.
Se směrováním atributů nehrají názvy kontroleru a akcí žádnou roli v tom, kdy se akce shoduje, pokud není použito nahrazení tokenu. Následující příklad se shoduje se stejnými adresami 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 a action 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();
}
}
Pro kontroler [Route("[controller]/[action]")] platí následující kód:
[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 musí šablony Index metod předcházet / nebo ~/ šablonám tras. Šablony tras 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.
Vyhrazené názvy směrování
Následující klíčová slova jsou názvy rezervovaných parametrů trasy při použití kontrolerů nebo Razor stránek:
actionareacontrollerhandlerpage
Běžnou chybou je použití parametru trasy page se směrováním atributů. Výsledkem je nekonzistentní a matoucí chování při generování adres URL.
public class MyDemo2Controller : Controller
{
[Route("/articles/{page}")]
public IActionResult ListArticles(int page)
{
return ControllerContext.MyDisplayRouteInfo(page);
}
}
Generování adresy URL používá speciální názvy parametrů k určení, jestli operace generování adresy URL odkazuje na Razor stránku nebo kontroler.
- Následující klíčová slova jsou vyhrazena v kontextu Razor zobrazení nebo Razor stránky:
pageusingnamespaceinjectsectioninheritsmodeladdTagHelperremoveTagHelper
Tato klíčová slova by se neměla používat pro generování propojení, parametry vázané na model ani vlastnosti nejvyšší úrovně.
Šablony sloves HTTP
ASP.NET Core má následující šablony sloves HTTP:
Šablony tras
ASP.NET Core má následující šablony tras:
- Všechny šablony operací HTTP jsou šablony směrování.
- [Trasa]
Směrování atributů s atributy operace HTTP
Zvažte použití následujícího kontroleru:
[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 porovnání pouze s požadavky HTTP GET. - Tato
GetProductakce zahrnuje"{id}"šablonu, protoidje připojená k"api/[controller]"šabloně na řadiči. Šablona metod je"api/[controller]/"{id}"". Proto tato akce odpovídá pouze požadavkům get pro formulář/api/test2/xyz,/api/test2/123, atd/api/test2/{any string}.[HttpGet("{id}")] // GET /api/test2/xyz public IActionResult GetProduct(string id) { return ControllerContext.MyDisplayRouteInfo(id); } GetIntProductAkce obsahuje"int/{id:int}")šablonu.:intČást šablony omezujeidhodnoty směrování 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 typu 404, která nebyla nalezena .
[HttpGet("int/{id:int}")] // GET /api/test2/int/3 public IActionResult GetIntProduct(int id) { return ControllerContext.MyDisplayRouteInfo(id); }
GetInt2ProductAkce obsahuje{id}v šabloně, ale neomezíidna hodnoty, které lze převést na celé číslo. Požadavek GET na/api/test2/int2/abc:- Odpovídá této trase.
- Vazbu modelu se nepodařilo převést
abcna celé číslo.idParametr metody je celé číslo. - Vrátí chybný požadavek 400 , protože vazba modelu selhala při převodu
abcna 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 HttpPostAttribute , HttpPutAttribute a HttpDeleteAttribute . Všechny atributy příkazu http přijímají šablonu směrování. Následující příklad ukazuje dvě akce, které odpovídají stejné šabloně směrování:
[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 URL /products3 :
MyProductsController.ListProductsAkce se spustí, když je příkaz HTTPGET.MyProductsController.CreateProductAkce se spustí, když je příkaz HTTPPOST.
Při sestavování REST API je zřídka nutné použít [Route(...)] metodu akce, protože akce akceptuje všechny metody HTTP. Je lepší použít konkrétnější atribut příkazu http , abyste mohli přesně zjistit, co vaše rozhraní API podporuje. Očekává se, že klienti rozhraní REST API znají, které cesty a příkazy HTTP se mapují na konkrétní logické operace.
Rozhraní REST API by měly používat směrování atributů k modelování funkčnosti aplikace jako sady prostředků, ve kterých jsou operace reprezentované příkazy HTTP. To znamená, že mnohé operace, například GET a POST u stejného logického prostředku, používají 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é vytvořit parametry požadované v rámci definice šablony trasy. V následujícím příkladu id je vyžadována 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);
}
}
Products2ApiController.GetProduct(int)Akce:
- Se spouští s cestou URL jako
/products2/3 - Není spuštěn s cestou URL
/products2.
Atribut [ ] umožňuje akci omezit podporované typy obsahu požadavků. Další informace najdete v tématu Definování podporovaných typů obsahu požadavků pomocí atributu spotřebes.
Úplný popis šablon směrování a souvisejících možností najdete v tématu věnovaném Směrování .
Další informace o naleznete v [ApiController] tématu atribut ApiController.
Název trasy
Následující kód definuje název trasy Products_List :
[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í směrování, které odpovídá adrese URL.
- Používá se pouze pro generování adresy URL.
Názvy tras musí být jedinečné aplikace v rozsahu.
Na rozdíl od předchozího kódu s konvenční výchozí trasou, která definuje id parametr jako volitelné ( {id?} ). Možnost přesně zadat rozhraní API má výhody, jako je povolení /products a /products/5 odeslání do různých akcí.
Kombinování tras atributů
Aby bylo směrování atributů méně opakované, jsou atributy směrování na kontroleru kombinovány s atributy směrování na jednotlivých akcích. Každá šablona trasy definovaná na řadiči je předá směrování šablon na akcích. Umístěním atributu směrování na řadiči se vytvoří všechny akce v řadiči použít směrování atributů.
[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 URL se
/productsmůže shodovat.ProductsApi.ListProducts - Cesta URL se
/products/5může shodovatProductsApi.GetProduct(int).
Obě tyto akce odpovídají pouze HTTP, GET protože jsou označeny [HttpGet] atributem.
Šablony směrování použité pro akci, která začíná / nebo ~/ není kombinována s šablonami směrování použitými pro kontroler. Následující příklad odpovídá sadě cest URL podobně jako výchozí trasa.
[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 popisuje [Route] atributy v předchozím kódu:
| Atribut | Kombinuje s [Route("Home")] |
Definuje šablonu směrování. |
|---|---|---|
[Route("")] |
Yes | "Home" |
[Route("Index")] |
Yes | "Home/Index" |
[Route("/")] |
Ne | "" |
[Route("About")] |
Yes | "Home/About" |
Pořadí směrování atributu
Směrování sestaví strom a porovnává se všemi koncovými body současně:
- Položky směrování se chovají stejně, jako kdyby byly umístěny v ideálním pořadí.
- Nejvíce konkrétní trasy mají možnost provést před obecnější trasy.
Například trasa atributu jako blog/search/{topic} je konkrétnější než trasa atributu jako blog/{*article} . blog/search/{topic}Ve výchozím nastavení tras má vyšší prioritu, protože je konkrétnější. Pomocí konvenčního směrovánízodpovídá vývojář za umístění tras v požadovaném pořadí.
Trasy atributů mohou konfigurovat objednávku pomocí Order Vlastnosti. Součástí jsou všechny atributy tras , které poskytuje rozhraní Order . Trasy jsou zpracovávány podle vzestupného řazení Order Vlastnosti. Výchozí pořadí je 0 . Nastavování trasy pomocí Order = -1 spuštění před trasami, které nenastaví objednávku. Nastavení trasy pomocí Order = 1 spuštění po výchozím řazení směrování.
Nepoužívejte v závislosti Order . Pokud je místo na adrese URL aplikace nutné správně směrovat hodnoty pořadí, je pravděpodobné, že budou i u klientů matoucí. 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, je použití názvu trasy jako přepsání obvykle jednodušší než použití Order Vlastnosti.
Vezměte v úvahu následující dva řadiče, které definují obě trasy /home :
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);
}
}
Požadavek /home s předchozím kódem vyvolá výjimku, která je podobná 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 ř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. Pro získání MyDemoController.MyIndex žádosti /home/MyIndex . Poznámka:
- Předchozí kód je příkladem nebo nekvalitní návrh směrování. Byla použita k ilustraci
OrderVlastnosti. OrderVlastnost pouze vyřeší nejednoznačnost, tuto šablonu nelze spárovat. Je lepší odebrat[Route("Home")]šablonu.
Podívejte se na Razor stránky směrování a konvence aplikace: pořadí tras pro informace o pořadí směrování se Razor stránkami.
V některých případech se k chybě HTTP 500 vrátí nejednoznačné trasy. Pomocí protokolování zjistíte, které koncové body způsobily AmbiguousMatchException .
Nahrazení tokenu v šablonách směrování [Controller], [akce], [oblast]
Pro usnadnění pohodlí trasy atributů podporují Nahrazení tokenu uzavřením tokenu do hranatých závorek ( [ , ] ). Tokeny [action] , [area] a [controller] jsou nahrazeny hodnotami názvu akce, názvu oblasti a názvu 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();
}
- Vyhovují
/Products0/List
[HttpGet("{id}")]
public IActionResult Edit(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
- Vyhovují
/Products0/Edit/{id}
Nahrazení tokenu probíhá jako poslední krok při vytváření 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 tento kód čtete v jiném jazyce než angličtině, dejte nám vědět v tomto problému diskuze 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í. Tato funkce je výkonná v kombinaci s nahrazením tokenu. Nahrazení tokenu platí také pro názvy tras definované 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);
}
}
Pokud chcete použít oddělovač pro nahrazení literálového tokenu nebo , uvozte ho opakováním [ ] znaku ( [[ nebo ]] ).
Přizpůsobení nahrazení tokenů pomocí parameter transformeru
Nahrazení tokenu je možné přizpůsobit pomocí parameter transformeru. Transformace parametrů implementuje a IOutboundParameterTransformer transformuje hodnotu parametrů. Například transformátor vlastních SlugifyParameterTransformer parametrů změní hodnotu trasy na SubscriptionManagement 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();
}
}
RouteTokenTransformerConventionje konvence aplikačního modelu, která:
- Použije transformátor parametrů na všechny trasy atributů v aplikaci.
- Přizpůsobí hodnoty tokenu trasy atributu při jejich nahrazované trase.
public class SubscriptionManagementController : Controller
{
[HttpGet("[controller]/[action]")]
public IActionResult ListAll()
{
return ControllerContext.MyDisplayRouteInfo();
}
}
Předchozí metoda ListAll odpovídá /subscription-management/list-all .
Parametr RouteTokenTransformerConvention je zaregistrovaný jako možnost:
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();
Definici Slug najdete v tématu Dokumentace k MDN pro Slug.
Upozornění
Při použití System.Text.RegularExpressions ke zpracování nedůvěryhodného vstupu předejte časový limit. Uživatel se zlými úmysly může poskytnout vstup pro RegularExpressions útok DoS (Denial-of-Service). Rozhraní API rozhraní ASP.NET Core Framework, která používají RegularExpressions předávat časový limit.
Trasy s více atributy
Směrování atributů podporuje definování více tras, které dosáhnou stejné akce. Nejběžnějším využitím je napodobování 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();
}
Vložení více atributů trasy do kontroleru znamená, že každý z nich se kombinuje s jednotlivými atributy trasy v metodách akcí:
[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();
}
}
Všechna omezení směrování operací HTTP implementují IActionConstraint .
Když se na akci umístí více IActionConstraint atributů trasy, které implementují :
- Každé omezení akce se kombinuje se šablonou 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í se může zdát 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 jenom tam, kde je to potřeba, například pro podporu stávajících klientů.
Zadání volitelných parametrů, výchozích hodnot a omezení směrování atributů
Trasy atributů podporují stejnou vnořenou syntaxi jako konvenč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 se [HttpPost("product14/{id:int}")] použije omezení trasy. Tato Products14Controller.ShowProduct akce se shoduje pouze s cestami URL, jako je /product14/3 . Část šablony trasy omezuje {id:int} tento segment pouze na celá čísla.
Podrobný popis syntaxe šablony trasy najdete v referenčních informacích k šabloně tras.
Vlastní atributy trasy pomocí objektu IRouteTemplateProvider
Všechny atributy trasy implementují IRouteTemplateProvider . Modul runtime ASP.NET Core:
- Při spuštění aplikace hledá atributy ve třídách kontroleru a metodách akcí.
- Používá atributy implementované
IRouteTemplateProviderk sestavení počáteční sady tras.
Implementujte IRouteTemplateProvider a definujte vlastní atributy trasy. Každá IRouteTemplateProvider z nich 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í metoda Get 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 souboru 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. Data z atributů trasy poskytuje IRouteTemplateProvider implementace . Úmluv:
- Lze napsat pro úpravu aplikačního modelu, aby bylo možné přizpůsobit chování směrování.
- Jsou přečtené 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 vytvoří trasy, které jsou zhruba za řádkové se strukturou 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 zabrání použití namespace konvence na kontrolery, které jsou směrovány atributy:
public void Apply(ControllerModel controller)
{
var hasRouteAttributes = controller.Selectors.Any(selector =>
selector.AttributeRouteModel != null);
if (hasRouteAttributes)
{
return;
}
Například následující kontroler nepodporuje 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 :
- Pokud je kontroler směrován atributem, nic neprodá.
- Nastaví šablonu kontrolerů na základě
namespaces odebranýmnamespacezákladem.
Lze NamespaceRoutingConvention použít v souboru 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ákladem je
namespaceMy.Application. - Úplný název předchozího kontroleru je
My.Application.Admin.Controllers.UsersController. - Nastavuje
NamespaceRoutingConventionšablonu kontrolerů naAdmin/Controllers/Users/[action]/{id?.
Lze NamespaceRoutingConvention také použít jako atribut v 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 Core aplikace mohou kombinovat použití konvenčního směrování a směrování atributů. Obvykle se používají konvenční trasy pro kontrolery obsluhující stránky HTML pro prohlížeče a směrování atributů pro kontrolery obsluhující rozhraní REST API.
Akce se směruje buď konvenčně, nebo se směruje atribut. Umístění trasy do kontroleru nebo akce zajistí, že se atribut bude směrovat. Akce, které definují trasy atributů, není možné dosáhnout konvenčními trasami a naopak. *Jakýkoli atribut _route v kontroleru provádí _ všechny akce * v atributu kontroleru směrované.
Směrování atributů a konvenční směrování používají stejný směrovací modul.
Generování adres URL a ambientní hodnoty
Aplikace mohou používat funkce generování adres URL pro směrování k vygenerování odkazů na adresy URL na akce. Generování adres URL eliminuje pevné kódování adres URL, díky tomu je kód robustnější a udržovatelnější. Tato část se zaměřuje na funkce generování adres URL, které MVC poskytuje, a zaměřuje se pouze na základní informace o tom, jak generování adres URL funguje. Podrobný popis generování adres URL najdete v tématu Směrování.
Rozhraní IUrlHelper je základním prvkem infrastruktury mezi MVC a směrováním pro generování adres URL. Instance je IUrlHelper k dispozici prostřednictvím vlastnosti v Url kontrolerů, zobrazeních a komponentách zobrazení.
V následujícím příkladu se rozhraní používá prostřednictvím vlastnosti IUrlHelper Controller.Url k vygenerování adresy URL pro jinou akci.
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 proměnné je url řetězec cesty URL /UrlGeneration/Destination . Tato cesta URL se vytvoří směrováním, a to kombinací:
- Hodnoty tras z aktuálního požadavku, které se nazývají ambientní hodnoty.
- Hodnoty předané do šablony trasy a jejich nahrazování
Url.Actiondo š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á svou 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 volitelný, přeskočte ho. Například ze
idšablony trasy{controller}/{action}/{id?}.
Generování adresy URL selže, pokud některý povinný parametr trasy nemá odpovídající hodnotu. Pokud se generování adresy URL pro trasu nezdaří, bude se pokus o další trasu, dokud se nezkusí všechny trasy nebo dokud se nenajde shoda.
Předchozí příklad předpokládá Url.Action 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 se používají k rozbalení šablony.
- V této šabloně
controllerse obvykle zobrazují hodnoty tras pro aaction. To funguje, protože adresy URL odpovídající směrování 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 .
LinkGeneratorbyl přidán ASP.NET Core 3.0 jako alternativu k IUrlHelper . LinkGenerator nabízí podobné, ale flexibilnější funkce. Každá metoda na IUrlHelper má také odpovídající rodinu LinkGenerator metod.
Generování adres URL podle názvu akce
Url.Action, LinkGenerator.GetPathByActiona všechna související přetížení jsou navržená tak, aby generují cílový koncový bod zadáním názvu kontroleru a názvu akce.
Při použití poskytuje modul runtime hodnoty aktuální trasy pro Url.Action controller a action :
- Hodnota a
controlleractionje součástí okolních hodnot i hodnot. Metoda vždy používá aktuální hodnoty a a vygeneruje cestuUrl.ActionactioncontrollerURL, 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é se při generování adresy URL nezadá. Zvažte 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 jakýchkoli 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 je v předchozím příkladu { c = Cheryl } přidaná hodnota:
- Obě hodnoty
{ c = Carol, d = David }se ignorují. - Hodnota pro už neexistuje a
dgenerování adresy URL selže. - K vygenerování adresy
cdURL je nutné zadat požadované hodnoty a .
Můžete očekávat, že k tomuto problému nastane výchozí trasa {controller}/{action}/{id?} . Tento problém je v praxi zřídka, Url.Action protože vždy explicitně určuje hodnotu a controller action .
Několik přetížení metody Url.Action využívá objekt hodnot tras k poskytnutí hodnot pro jiné parametry trasy než a controller action . Objekt hodnot tras se často používá s id . Například, Url.Action("Buy", "Products", new { id = 17 }). Objekt hodnot tras:
- Podle konvence je obvykle objekt anonymního typu.
- Může to být
IDictionary<>objekt poco nebo .
Všechny další hodnoty tras, které neodpovídají parametrům trasy, se začtou 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 předvedl generování adresy URL předáním kontroleru a názvu akce. IUrlHelpertaké poskytuje rodinu metod Url.RouteUrl. Tyto metody se podobají metodě Url.Action,ale nekopírují aktuální hodnoty a action na hodnoty controller tras. Nejběžnější použití Url.RouteUrl :
- Určuje název trasy pro vygenerování adresy URL.
- Obvykle 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í soubor Razor 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 v HTML a Razor
IHtmlHelper poskytuje metody HtmlHelper Html.BeginForm a Html.ActionLink pro generování prvků <form> a v uvedeném <a> pořadí. Tyto metody používají metodu Url.Action k vygenerování adresy URL a přijímají podobné argumenty. Doprovodné Url.RouteUrl společnosti jsou a které mají podobné HtmlHelper Html.BeginRouteForm Html.RouteLink funkce.
TagHelpers generují adresy URL prostřednictvím form TagHelper a <a> TagHelper. Obě tyto funkce používají IUrlHelper pro svou implementaci. Další informace najdete v tématu Pomocníci značek ve formulářích.
V zobrazeních IUrlHelper je k dispozici prostřednictvím vlastnosti pro jakékoli generování ad hoc adresy Url URL, které výše uvedené možnosti nepokryje.
Generování adres URL ve výsledcích akce
Předchozí příklady ukázaly použití IUrlHelper v kontroleru. Nejběžnějším využitím kontroleru je vygenerovat adresu URL jako součást výsledku akce.
Základní ControllerBase třídy a poskytují metody usnadnění pro výsledky Controller akce, které odkazují na jinou akci. Jedním z typických využ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 vede k metodám továrny, jako je a , a dodržuje RedirectToAction podobný vzor jako metody v CreatedAtAction IUrlHelper .
Zvláštní případ pro vyhrazené konvenční trasy
Konvenční směrování může používat speciální druh definice trasy, který se nazývá vyhrazená konvenční trasa. V následujícím příkladu je trasa s názvem blog 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 tras Url.Action("Index", "Home") vygeneruje cestu URL / pomocí default trasy, ale proč? Můžete odhadnout, že hodnoty trasy budou stačit k vygenerování adresy URL pomocí { controller = Home, action = Index } a výsledkem bude blog /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 výchozí hodnoty { controller = Blog, action = Article } a ani se nezobrazí jako parametr controller action trasy. Když směrování provádí generování adres URL, zadané hodnoty musí odpovídat výchozím hodnotám. Generování adresy URL blog pomocí selže, protože { controller = Home, action = Index } hodnoty neodpovídají { controller = Blog, action = Article } . Směrování se pak vrátí zpět k akci default , která bude úspěšná.
Oblasti
Oblasti jsou funkce MVC, která slouží k uspořádání souvisejících funkcí do skupiny jako samostatných:
- 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 trasy do a area controller action . Tato část popisuje, jak směrování komunikuje s oblastmi. Podrobnosti o tom, jak se oblasti používají se zobrazeními, najdete v tématu Oblasti.
Následující příklad nakonfiguruje MVC na použití výchozí konvenční trasy a area trasy s area názvem 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 se MapAreaControllerRoute volá k vytvoření "blog_route" . Druhým parametrem je "Blog" název oblasti.
Při porovnávání cesty /Manage/Users/AddUser URL, jako je , trasa "blog_route" vygeneruje hodnoty trasy { area = Blog, controller = Users, action = AddUser } . Hodnota area trasy se vyprodukuje pomocí výchozí hodnoty pro area . Trasa vytvořená pomocí MapAreaControllerRoute je ekvivalentní následující trase:
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 s použitím výchozí hodnoty i omezení pro area použití poskytnutého názvu oblasti, v tomto případě Blog . Výchozí hodnota zajistí, že trasa vždy vytvoří , omezení vyžaduje { area = Blog, ... } hodnotu pro generování adresy { area = Blog, ... } URL.
Konvenční směrování je závislé na pořadí. Obecně platí, že trasy s oblastmi by se měly umisťovat dříve, protože jsou konkrétnější než trasy bez oblasti.
V předchozím příkladu se hodnoty trasy { area = Blog, controller = Users, action = AddUser } 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 nejsou členy žádné oblasti a neodpovídají, pokud je hodnota trasy [Area] area poskytnutá směrováním. V následujícím příkladu se může shodovat s hodnotami trasy pouze první kontroler uvedený v seznamu { area = Blog, controller = Users, action = AddUser } .
using Microsoft.AspNetCore.Mvc;
namespace MyApp.Namespace1
{
[Area("Blog")]
public class UsersController : Controller
{
// GET /manage/users/adduser
public IActionResult AddUser()
{
var area = ControllerContext.ActionDescriptor.RouteValues["area"];
var actionName = ControllerContext.ActionDescriptor.ActionName;
var controllerName = ControllerContext.ActionDescriptor.ControllerName;
return Content($"area name:{area}" +
$" controller:{controllerName} action name: {actionName}");
}
}
}
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}");
}
}
}
Pro úplnost se tady zobrazuje obor názvů každého kontroleru. Pokud by předchozí kontrolery používaly stejný obor názvů, vygenerovala by se chyba kompilátoru. Obory názvů třídy nemají žádný vliv na směrování MVC.
První dva kontrolery jsou členy oblastí a shodují se pouze v případě, že je název příslušné oblasti poskytnut area hodnotou trasy. Třetí kontroler není členem žádné oblasti a může se shodovat pouze v případě, že směrování neposkytuje area žádnou hodnotu pro .
Z hlediska porovnání žádné hodnoty je absence hodnoty stejná, jako kdyby hodnota pro byla null nebo area prázdný area řetězec.
Při provádění akce uvnitř oblasti je hodnota trasy pro k dispozici jako ambientní hodnota pro směrování, která area se má použít pro generování adresy URL. To znamená, že ve výchozím nastavení se oblasti při generování adresy URL chová přichyceně, 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ázka kódu
- MyDisplayRouteInfo poskytuje balíček NuGet Rick.Docs.Samples.RouteInfo a zobrazuje informace o trasách.
- Zobrazení nebo stažení ukázkového kódu (stažení)
Diagnostika ladění
Pro podrobný výstup diagnostiky směrování nastavte Logging:LogLevel:Microsoft na Debug . Ve vývojovém prostředí nastavte úroveň protokolu v appsettings.Development.jsna:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Debug",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
ASP.NET Core kontrolery používají middleware směrování k párování adres URL příchozích požadavků a namapují 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ď konvenčně směrované, nebo směrované na atributy. Umístění trasy do kontroleru nebo akce zajistí směrování podle atributů. 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 používají funkce směrování.
- Zahrnuje obojí:
- Konvenční směrování se obvykle používá s kontrolery a zobrazeními.
- Směrování atributů používané s rozhraními REST API. Pokud vás zajímá primárně směrování pro rozhraní REST API, přeskočte ke směrování atributů pro rozhraní REST API.
- Podrobnosti o pokročilé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, který se označuje jako směrování koncového bodu. Pro účely kompatibility je možné použít kontrolery s předchozí verzí směrování. Pokyny najdete v průvodci migrací 2.2–3.0. Referenční materiály ke staršímu systému směrování najdete ve verzi 2.2 tohoto dokumentu.
Nastavení konvenční trasy
Startup.ConfigurePři použití konvenčního směrování obvykle obsahuje kód podobný následujícímu:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
Uvnitř volání UseEndpoints se MapControllerRoute k vytvoření jedné trasy používá . Jedna trasa má název default route. Většina aplikací s kontrolery a zobrazeními používá šablonu trasy podobnou default trase. Rozhraní REST API by měla používat směrování atributů.
Šablona trasy "{controller=Home}/{action=Index}/{id?}" :
Odpovídá cestě URL, jako je .
/Products/Details/5Extrahuje hodnoty tras
{ controller = Products, action = Details, id = 5 }tokenizací cesty. Extrakce hodnot tras vede ke shodě, pokud má aplikace kontroler s názvemProductsControlleraDetailsakci:public class ProductsController : Controller { public IActionResult Details(int id) { return ControllerContext.MyDisplayRouteInfo(id); } }MyDisplayRouteInfo poskytuje balíček NuGet Rick.Docs.Samples.RouteInfo a zobrazuje informace o trasách.
/Products/Details/5model váže hodnotuid = 5parametruidna5. Další podrobnosti najdete v tématu Vazby modelu.{controller=Home}definujeHomejako výchozícontroller.{action=Index}definujeIndexjako výchozíaction.Znak
?v definuje jako{id?}idvolitelný.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ě tras.
Odpovídá cestě URL
/.Vytvoří hodnoty trasy
{ controller = Home, action = Index }.
Hodnoty a controller action používají výchozí hodnoty. id nevytváří hodnotu, protože v cestě URL není odpovídající segment. / odpovídá pouze v případě, že existuje HomeController Index akce a :
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í kontrolery a akci šablony Home Index trasy. Cesta URL používá /Home výchozí akci šablony Index trasy.
Metoda convenience MapDefaultControllerRoute :
endpoints.MapDefaultControllerRoute();
Nahradí:
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
Důležité
Směrování se konfiguruje pomocí UseRouting MapControllerRoute middlewaru , MapAreaControllerRoute a . Použití kontrolerů:
- Voláním MapControllers uvnitř
UseEndpointsmapy namapovat kontrolery směrované na atributy. - Voláním MapControllerRoute nebo MapAreaControllerRoute namapujete jak řadiče s konvenčním směrováním, tak kontrolery směrované podle atributů.
Konvenční směrování
Konvenční směrování se používá s kontrolery a zobrazeními. defaultTrasa:
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Předchozí příklad ukazuje konvenční trasu. Říká se mu konvenční směrování, protože zavádí konvenci pro cesty URL:
- První segment cesty se
{controller=Home}mapuje na název kontroleru. - Druhý segment se
{action=Index}mapuje na název akce. - Třetí segment se
{id?}používá pro volitelný segmentid. V?z něj dělá{id?}nepovinné.idslouží k mapování na entitu modelu.
Pomocí této default trasy cesta URL:
/Products/Listse mapuje naProductsController.Listakci./Blog/Article/17seBlogController.Articlemapuje na a obvykle model vážeidparametr na 17.
Toto mapování:
- Vychází pouze z názvů kontroleru a akce.
- Není založený na oborech názvů, umístění zdrojového souboru ani parametrech metody.
Použití konvenčního směrování s výchozí trasou umožňuje vytvoření aplikace bez nutnosti vytvářet pro každou akci nový vzor adresy URL. U aplikace s akcemi ve stylu CRUD je konzistence adres URL napříč kontrolery:
- Pomáhá zjednodušit kód.
- Díky tomu je uživatelské rozhraní předvídatelnější.
Upozornění
V předchozím kódu je šablona trasy definovaná jako id volitelná. Akce se mohou provádět bez volitelného ID poskytnutého jako součást adresy URL. Obecně platí, id že pokud je adresa URL vynechána:
idje nastavená na0pomocí vazby modelu.- V databázi, která odpovídá , se nenašla žádná
id == 0entita.
Směrování atributů poskytuje jemně odlišnou kontrolu, aby ID bylo nutné pro některé akce, a ne pro jiné. Podle konvence dokumentace obsahuje volitelné parametry, jako když se pravděpodobně objeví id 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 bylo čitelné a smysluplné. Výchozí konvenční {controller=Home}/{action=Index}/{id?} trasa:
- 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 často potřeba jiná trasa využívající oblasti.
MapControllerRoute a MapAreaRoute :
- Automaticky přiřadí hodnotu objednávky koncovým bodům na základě pořadí, ve které jsou vyvolané.
Směrování koncového bodu v ASP.NET Core 3.0 a novějších verzích:
- Nemá koncept tras.
- Neposkytuje záruky řazení pro provádění rozšiřitelnosti, všechny koncové body se zpracovávají najednou.
Povolením protokolování zobrazíte, 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.
Několik konvenčních tras
Do je možné přidat více konvenčních tras přidáním dalších volání do a UseEndpoints MapControllerRoute 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. Říká se jí vyhrazená konvenční trasa, protože:
Protože controller a se v action šabloně trasy nezobrazují "blog/{*article}" 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 jsou jediné cesty /Blog/{any-string} URL, které odpovídají trase blogu.
Předchozí příklad:
blogTrasa má vyšší prioritu pro shody neždefaulttrasa, protože se přidá jako první.- Je příkladem směrování ve stylu Slug, kde je typické, že jako součást adresy URL je název článku.
Upozornění
Ve ASP.NET Core verze 3.0 a novější směrování ne:
- Definujte koncept, který se nazývá trasa.
UseRoutingpřidá do middlewarového kanálu párování tras. Middleware se podívá na sadu koncových bodů definovaných v aplikaci a vybere nejlepší shodu koncovéhoUseRoutingbodu na základě požadavku. - Poskytovat záruky týkající se pořadí provádění rozšiřitelnosti, jako IRouteConstraint je nebo IActionConstraint .
Viz Směrování referenčních materiálů při směrování.
Konvenční pořadí směrování
Konvenční směrování odpovídá pouze kombinaci akce a kontroleru, které jsou definovány aplikací. Cílem je zjednodušit případy, kdy se konvenční trasy překrývají.
Přidání tras pomocí , a automaticky přiřadí hodnotu objednávky koncovým bodům na základě MapControllerRoute MapDefaultControllerRoute MapAreaControllerRoute 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 se měly umisťovat dříve, protože jsou konkrétnější než trasy bez oblasti. Vyhrazené konvenční trasy s parametry zachytání všech tras, jako je , znamenají, že trasa je příliš greedy, což znamená, že odpovídá adresám URL, které by se měly spárovat s {*article} jinými trasami. Trasy greedy umístěte do směrovací tabulky později, aby se zabránilo shodám s greedy.
Upozornění
Parametr catch-All může nesprávně odpovídat trasy z důvodu chyby v směrování. Aplikace ovlivněné touto chybou mají následující vlastnosti:
- Například trasa typu catch-ALL.
{**slug}" - Trasa catch-All nesplňuje požadavky, které by se měla shodovat.
- Při odebrání jiných tras bude vše začít pracovat.
Příklady přístupů k této chybě najdete v tématu chyby GitHubu 18677 a 16579 .
Oprava pro tuto chybu je obsažená v sadě .NET Core 3.1.301 SDK a novější. Následující kód nastaví interní přepínač, který vyřeší tuto chybu:
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í
Pokud se při směrování shodují dva koncové body, směrování musí provést jednu z následujících akcí:
- Zvolte nejlepšího kandidáta.
- Vyvolá výjimku.
Napří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 zveřejněný formulář.
Pokud chcete vyřešit správnou trasu:
Edit(int, Product)se vybere, pokud je požadavkem httpPOST.Edit(int)se vybere, pokud příkaz HTTP je cokoli jiného.Edit(int)se obvykle volá prostřednictvímGET.
, HttpPostAttribute [HttpPost] , je k dispozici pro směrování, aby mohl zvolit na základě metody HTTP požadavku. HttpPostAttributeJe lepší Edit(int, Product) shoda než Edit(int) .
Je důležité pochopit roli atributů, jako je HttpPostAttribute . Podobné atributy jsou definované pro jiné příkazy HTTP. Při konvenčnímsměrování je běžné, že akce používají stejný název akce, pokud jsou součástí formuláře pro zobrazení, a pracovní postup odeslání formuláře. Příklad najdete v tématu Prozkoumání dvou metod akce Upravit.
Pokud směrování nemůže zvolit nejlepšího kandidáta, vyvolá se objekt se seznamem AmbiguousMatchException několika shodných koncových bodů.
Názvy konvenčních tras
Řetězce a "blog" "default" v následujících příkladech jsou názvy konvenčních 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í trase logický název. Pojmenovanou trasu lze použít pro generování adres URL. Použití pojmenované trasy zjednodušuje vytváření adres URL, pokud by se při řazení tras mohlo generování adres URL komplikovat. Názvy tras musí být jedinečné pro celou aplikaci.
Názvy tras:
- Nemají žádný vliv na párování adres URL ani zpracování požadavků.
- Používají se pouze pro generování adres URL.
Koncept názvu trasy je ve směrování reprezentován jako IEndpointNameMetadata. Pojmy název trasy a název koncového bodu:
- Jsou zaměnitelné.
- To, které se používá v dokumentaci a kódu, závisí na popsaném rozhraní API.
Směrování atributů pro rozhraní REST API
Rozhraní REST API by měla používat směrování atributů k modelování funkcí aplikace jako sady prostředků, ve kterých jsou operace reprezentované 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 StartUp.Configure je typický pro REST 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 volá uvnitř pro mapování MapControllers UseEndpoints kontrolerů směrovaných podle atributů.
V následujícím příkladu:
HomeControllerodpovídá sadě adres URL, které odpovídají výchozí konvenční{controller=Home}/{action=Index}/{id?}trase.
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 libovolnou cestu URL , , nebo / /Home /Home/Index /Home/Index/3 .
Tento příklad zvýrazní 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 více vstupů pro určení trasy. Konvenční výchozí trasa zpracovává trasy výstižněji. Směrování atributů ale umožňuje a vyžaduje přesnou kontrolu nad tím, které šablony tras se u každé akce použijí.
Se směrováním atributů nehrají názvy kontroleru a akcí žádnou roli v tom, kdy se akce shoduje, pokud není použito nahrazení tokenu. Následující příklad se shoduje se stejnými adresami 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 a action 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();
}
}
Pro kontroler [Route("[controller]/[action]")] platí následující kód:
[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 musí šablony Index metod předcházet / nebo ~/ šablonám tras. Šablony tras 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.
Vyhrazené názvy směrování
Následující klíčová slova jsou názvy rezervovaných parametrů trasy při použití kontrolerů nebo Razor stránek:
actionareacontrollerhandlerpage
Běžnou chybou je použití parametru trasy page se směrováním atributů. Výsledkem je nekonzistentní a matoucí chování při generování adres URL.
public class MyDemo2Controller : Controller
{
[Route("/articles/{page}")]
public IActionResult ListArticles(int page)
{
return ControllerContext.MyDisplayRouteInfo(page);
}
}
Generování adresy URL používá speciální názvy parametrů k určení, jestli operace generování adresy URL odkazuje na Razor stránku nebo kontroler.
- Následující klíčová slova jsou vyhrazena v kontextu Razor zobrazení nebo Razor stránky:
pageusingnamespaceinjectsectioninheritsmodeladdTagHelperremoveTagHelper
Tato klíčová slova by se neměla používat pro generování propojení, parametry vázané na model ani vlastnosti nejvyšší úrovně.
Šablony sloves HTTP
ASP.NET Core má následující šablony sloves HTTP:
Šablony tras
ASP.NET Core má následující šablony tras:
- Všechny šablony operací HTTP jsou šablony směrování.
- [Trasa]
Směrování atributů s atributy operace HTTP
Zvažte použití následujícího kontroleru:
[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 atribut
[HttpGet], který omezuje párování pouze s požadavky HTTP GET. - Akce
GetProductzahrnuje"{id}"šablonu, protoidse připojí k"api/[controller]"šabloně na kontroleru. Šablona metod je"api/[controller]/"{id}"". Tato akce proto odpovídá pouze žádostem 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
GetIntProductobsahuje"int/{id:int}")šablonu. Část šablony omezuje hodnoty tras na řetězce,:intidkteré lze převést na celé číslo. Požadavek GET na/api/test2/int/abc:- Neodpovídá této akci.
- Vrátí chybu 404 Nenašl se.
[HttpGet("int/{id:int}")] // GET /api/test2/int/3 public IActionResult GetIntProduct(int id) { return ControllerContext.MyDisplayRouteInfo(id); }
- Akce obsahuje v šabloně, ale není omezena na hodnoty,
GetInt2Product{id}které lzeidpřevést na celé číslo. Požadavek GET na/api/test2/int2/abc:- Odpovídá této trase.
- Vazba modelu se nedaří
abcpřevést na celé číslo. Parametridmetody je celé číslo. - Vrátí chybu 400 Chybný požadavek, protože se nepodařilo převést vazbu modelu
abcna 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 HttpPostAttribute atributy, jako jsou , a HttpPutAttribute HttpDeleteAttribute . Všechny atributy operace 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 URL /products3 :
- Akce
MyProductsController.ListProductsse spustí, když je příkaz HTTPGET. - Akce
MyProductsController.CreateProductse spustí, když je příkaz HTTPPOST.
Při vytváření REST API je vzácné, že budete muset použít metodu akce, protože akce přijímá [Route(...)] všechny metody HTTP. Pro přesnější informace o tom, co vaše rozhraní API podporuje, je lepší použít konkrétnější atribut operace HTTP. Očekává se, že klienti rozhraní REST API budou vědět, jaké cesty a příkazy HTTP se mapovat na konkrétní logické operace.
Rozhraní REST API by měla používat směrování atributů k modelování funkcí aplikace jako sady prostředků, ve kterých jsou operace reprezentované příkazy HTTP. To znamená, že mnoho operací, například GET a POST u stejného logického prostředku, používá stejnou adresu URL. Směrování atributů poskytuje úroveň řízení, která je potřeba k pečlivé 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);
}
}
Products2ApiController.GetProduct(int)Akce:
- Je spuštěný s cestou URL, jako je
/products2/3 - Nespouštěl se s cestou URL
/products2.
Atribut [Consumes] umožňuje akci omezit podporované typy obsahu požadavků. Další informace najdete v tématu Definování podporovaných typů obsahu požadavků pomocí atributu Consumes.
Úplný popis šablon tras a souvisejících možností najdete v tématu Směrování.
Další informace o najdete [ApiController] v tématu Atribut ApiController.
Název trasy
Následující kód definuje název trasy Products_List :
[ApiController]
public class Products2ApiController : ControllerBase
{
[HttpGet("/products2/{id}", Name = "Products_List")]
public IActionResult GetProduct(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
}
Názvy tras lze použít k vygenerování adresy URL na základě konkrétní trasy. Názvy tras:
- Nemá žádný vliv na chování směrování při porovnávání adres URL.
- Používají se pouze 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?} ). Možnost přesně specifikovat rozhraní API má výhody, jako je povolení a odeslání do /products /products/5 různých akcí.
Kombinování tras atributů
Aby směrování atributů bylo méně opakující se, zkombinují se atributy směrování na kontroleru s atributy trasy pro jednotlivé akce. Všechny šablony tras definované v kontroleru jsou předdefinované tak, aby směrovali šablony pro akce. Při umístění atributu trasy na kontroler budou všechny akce v kontroleru používat směrování atributů.
[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 URL se
/productsmůže shodovat.ProductsApi.ListProducts - Cesta URL se
/products/5může shodovatProductsApi.GetProduct(int)s .
Obě tyto akce odpovídají pouze protokolu GET HTTP, protože jsou označené [HttpGet] atributem .
Šablony tras 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("")] |
Yes | "Home" |
[Route("Index")] |
Yes | "Home/Index" |
[Route("/")] |
Ne | "" |
[Route("About")] |
Yes | "Home/About" |
Pořadí tras atributů
Směrování sestaví strom a bude odpovídat všem koncovým bodům současně:
- Položky trasy se chovají, jako by byly umístěny v ideálním pořadí.
- Nejobecnější trasy mají možnost provést před obecnějšími trasami.
Například trasa atributu, jako je , blog/search/{topic} je konkrétnější než trasa atributu, jako je blog/{*article} . Trasa blog/search/{topic} má ve výchozím nastavení vyšší prioritu, protože je konkrétnější. Pomocí konvenčníhosměrování zodpovídá vývojář za umístění tras v požadovaném pořadí.
Trasy atributů mohou nakonfigurovat objednávku pomocí Order vlastnosti . Všechny atributy trasy poskytnuté architekturou zahrnují Order . Trasy se zpracovávají podle vzestupného druhu Order vlastnosti. Výchozí pořadí je 0 . Nastavení trasy pomocí se Order = -1 spustí před trasami, které nastavovat pořadí. Nastavení trasy pomocí se Order = 1 spustí po výchozím řazení tras.
Vyhněte se v závislosti na Order . Pokud adresní prostor adres URL aplikace vyžaduje správné směrování explicitních hodnot pořadí, může to být matoucí i 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í adres 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é oba 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);
}
}
Požadavek /home 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ím k jednomu z atributů trasy se vyřeší Order nejednoznačnost:
[Route("")]
[Route("Home", Order = 2)]
[Route("Home/MyIndex")]
public IActionResult MyIndex()
{
return ControllerContext.MyDisplayRouteInfo();
}
Pomocí předchozího kódu spustí /home koncový HomeController.Index bod. Pokud chcete získat přístup MyDemoController.MyIndex k , požádejte /home/MyIndex o . Poznámka:
- Předchozí kód je příkladem nebo špatným návrhem směrování. Byla použita k ilustraci
Ordervlastnosti . - Vlastnost
Orderpouze řeší nejednoznačnost, protože tato šablona se neshoduje. Bylo by lepší šablonu[Route("Home")]odebrat.
Informace Razor o objednávce tras se stránkami najdete v tématu Trasy stránek a konvence aplikací: Pořadí Razor tras.
V některých případech se vrátí chyba HTTP 500 s nejednoznačných tras. Pomocí protokolování můžete zobrazit, které koncové body způsobily AmbiguousMatchException .
Nahrazení tokenu v šablonách tras [controller], [action], [area]
Kvůli usnadnění trasy atributů podporují nahrazení tokenu uzavřením tokenu do hranatých závorek ( [ , ] ). Tokeny , a se nahradí hodnotami názvu akce, názvu oblasti a názvu kontroleru z akce, ve které [action] [area] je trasa [controller] definovaná:
[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();
}
- Odpovídá
/Products0/List
[HttpGet("{id}")]
public IActionResult Edit(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
- Odpovídá
/Products0/Edit/{id}
K nahrazení tokenu dochází jako poslední krok vytváření 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 tento kód čtete v jiném jazyce než angličtině, dejte nám vědět v tomto problému diskuze 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í. Tato funkce je výkonná v kombinaci s nahrazením tokenu. Nahrazení tokenu platí také pro názvy tras definované 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);
}
}
Pokud chcete použít oddělovač pro nahrazení literálového tokenu nebo , uvozte ho opakováním [ ] znaku ( [[ nebo ]] ).
Přizpůsobení nahrazení tokenů pomocí parameter transformeru
Nahrazení tokenu je možné přizpůsobit pomocí parameter transformeru. Transformace parametrů implementuje a IOutboundParameterTransformer transformuje hodnotu parametrů. Například transformátor vlastních SlugifyParameterTransformer parametrů změní hodnotu trasy na SubscriptionManagement 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();
}
}
RouteTokenTransformerConventionje konvence aplikačního modelu, která:
- Použije transformátor parametrů na všechny trasy atributů v aplikaci.
- Přizpůsobí hodnoty tokenu trasy atributu při jejich nahrazované trase.
public class SubscriptionManagementController : Controller
{
[HttpGet("[controller]/[action]")]
public IActionResult ListAll()
{
return ControllerContext.MyDisplayRouteInfo();
}
}
Předchozí metoda ListAll odpovídá /subscription-management/list-all .
Je RouteTokenTransformerConvention zaregistrovaný jako možnost v ConfigureServices .
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews(options =>
{
options.Conventions.Add(new RouteTokenTransformerConvention(
new SlugifyParameterTransformer()));
});
}
Definici Slug najdete v tématu Dokumentace k MDN pro Slug.
Upozornění
Při použití System.Text.RegularExpressions ke zpracování nedůvěryhodného vstupu předejte časový limit. Uživatel se zlými úmysly může poskytnout vstup pro RegularExpressions útok DoS (Denial-of-Service). Rozhraní API rozhraní ASP.NET Core Framework, která používají RegularExpressions předávat časový limit.
Trasy s více atributy
Směrování atributů podporuje definování více tras, které dosáhnou stejné akce. Nejběžnějším využitím je napodobování 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();
}
Vložení více atributů trasy do kontroleru znamená, že každý z nich se kombinuje s jednotlivými atributy trasy v metodách akcí:
[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();
}
}
Všechna omezení směrování operací HTTP implementují IActionConstraint .
Když se na akci umístí více IActionConstraint atributů trasy, které implementují :
- Každé omezení akce se kombinuje se šablonou 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í se může zdát 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 jenom tam, kde je to potřeba, například pro podporu stávajících klientů.
Zadání volitelných parametrů, výchozích hodnot a omezení směrování atributů
Trasy atributů podporují stejnou vnořenou syntaxi jako konvenč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 se [HttpPost("product14/{id:int}")] použije omezení trasy. Tato Products14Controller.ShowProduct akce se shoduje pouze s cestami URL, jako je /product14/3 . Část šablony trasy omezuje {id:int} tento segment pouze na celá čísla.
Podrobný popis syntaxe šablony trasy najdete v referenčních informacích k šabloně tras.
Vlastní atributy trasy pomocí objektu IRouteTemplateProvider
Všechny atributy trasy implementují IRouteTemplateProvider . Modul runtime ASP.NET Core:
- Při spuštění aplikace hledá atributy ve třídách kontroleru a metodách akcí.
- Používá atributy implementované
IRouteTemplateProviderk sestavení počáteční sady tras.
Implementujte IRouteTemplateProvider a definujte vlastní atributy trasy. Každá IRouteTemplateProvider z nich 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í metoda Get 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. Data z atributů trasy poskytuje IRouteTemplateProvider implementace . Úmluv:
- Lze napsat pro úpravu aplikačního modelu, aby bylo možné přizpůsobit chování směrování.
- Jsou přečtené 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 vytvoří trasy, které jsou zhruba za řádkové se strukturou 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 zabrání použití namespace konvence na kontrolery, které jsou směrovány atributy:
public void Apply(ControllerModel controller)
{
var hasRouteAttributes = controller.Selectors.Any(selector =>
selector.AttributeRouteModel != null);
if (hasRouteAttributes)
{
return;
}
Například následující kontroler nepodporuje 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 :
- Pokud je kontroler směrován atributem, nic neprodá.
- Nastaví šablonu kontrolerů na základě
namespaces odebranýmnamespacezákladem.
NamespaceRoutingConventionLze použít 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ákladem je
namespaceMy.Application. - Úplný název předchozího kontroleru je
My.Application.Admin.Controllers.UsersController. - Nastavuje
NamespaceRoutingConventionšablonu kontrolerů naAdmin/Controllers/Users/[action]/{id?.
Lze NamespaceRoutingConvention také použít jako atribut v 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 Core aplikace mohou kombinovat použití konvenčního směrování a směrování atributů. Obvykle se používají konvenční trasy pro kontrolery obsluhující stránky HTML pro prohlížeče a směrování atributů pro kontrolery obsluhující rozhraní REST API.
Akce se směruje buď konvenčně, nebo se směruje atribut. Umístění trasy do kontroleru nebo akce zajistí, že se atribut bude směrovat. Akce, které definují trasy atributů, není možné dosáhnout konvenčními trasami a naopak. Všechny atributy směrování na kontroleru provádí všechny akce v atributu kontroleru směrované.
Směrování atributů a konvenční směrování používají stejný směrovací modul.
Generování adres URL a ambientní hodnoty
Aplikace mohou používat funkce generování adres URL pro směrování k vygenerování odkazů na adresy URL na akce. Generování adres URL eliminuje pevné začátení adres URL, díky tomu je kód robustnější a udržovatelnější. Tato část se zaměřuje na funkce generování adres URL, které MVC poskytuje, a zaměřuje se pouze na základní informace o tom, jak generování adres URL funguje. Podrobný popis generování adres URL najdete v tématu Směrování.
Rozhraní IUrlHelper je základním prvkem infrastruktury mezi MVC a směrováním pro generování adres URL. Instance je IUrlHelper k dispozici prostřednictvím vlastnosti v Url kontrolerů, zobrazeních a komponentách zobrazení.
V následujícím příkladu se rozhraní používá prostřednictvím vlastnosti IUrlHelper Controller.Url k vygenerování adresy URL pro jinou akci.
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 proměnné je url řetězec cesty URL /UrlGeneration/Destination . Tato cesta URL se vytvoří směrováním, a to kombinací:
- Hodnoty tras z aktuálního požadavku, které se nazývají ambientní hodnoty.
- Hodnoty předané do šablony trasy a jejich nahrazování
Url.Actiondo š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á svou 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 volitelný, přeskočte ho. Například ze
idšablony trasy{controller}/{action}/{id?}.
Generování adresy URL selže, pokud některý povinný parametr trasy nemá odpovídající hodnotu. Pokud se generování adresy URL pro trasu nezdaří, bude se pokus o další trasu, dokud se nezkusí všechny trasy nebo dokud se nenajde shoda.
Předchozí příklad předpokládá Url.Action 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 se používají k rozbalení šablony.
- V této šabloně
controllerse obvykle zobrazují hodnoty tras pro aaction. To funguje, protože adresy URL odpovídající směrování 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 .
LinkGeneratorbyl přidán ASP.NET Core 3.0 jako alternativu k IUrlHelper . LinkGenerator nabízí podobné, ale flexibilnější funkce. Každá metoda na IUrlHelper má také odpovídající rodinu LinkGenerator metod.
Generování adres URL podle názvu akce
Url.Action, LinkGenerator.GetPathByActiona všechna související přetížení jsou navržená tak, aby generují cílový koncový bod zadáním názvu kontroleru a názvu akce.
Při použití poskytuje modul runtime hodnoty aktuální trasy pro Url.Action controller a action :
- Hodnota
controlleraactionje součástí obou okolních hodnot a hodnot. MetodaUrl.Actionvždy používá aktuální hodnotyactionacontrollera generuje cestu adresy URL, která směruje na aktuální akci.
Směrování se pokusí použít hodnoty v ambientních hodnotách k vyplnění informací, které nebyly poskytnuty při generování adresy URL. Vezměte v úvahu trasu jako {a}/{b}/{c}/{d} u okolních hodnot { a = Alice, b = Bob, c = Carol, d = David } :
- Směrování má dostatek informací pro vygenerování adresy URL bez dalších hodnot.
- Směrování má dostatek informací, protože všechny parametry tras mají hodnotu.
Pokud { d = Donovan } se přidá hodnota:
- Hodnota
{ d = David }se ignoruje. - Vygenerovaná cesta URL je
Alice/Bob/Carol/Donovan.
Upozornění: cesty URL jsou hierarchické. V předchozím příkladu, pokud { c = Cheryl } je přidána hodnota:
- Obě hodnoty
{ c = Carol, d = David }jsou ignorovány. - Již není hodnota
da generování adresy URL se nezdařilo. cdAby bylo možné vygenerovat adresu URL, je nutné zadat požadované hodnoty a.
Můžete očekávat, že se tento problém bude narazit u výchozí trasy {controller}/{action}/{id?} . Tento problém je v praxi zřídka, protože Url.Action vždy explicitně určuje controller action hodnotu a.
Několik přetížení URL. akce přebírají objekt hodnot směrování, aby poskytovala hodnoty pro parametry směrování jiné než controller a action . Objekt hodnoty trasy se často používá s id . Například, Url.Action("Buy", "Products", new { id = 17 }). Objekt hodnot směrování:
- Podle konvence je obvykle objekt anonymního typu.
- Může to být
IDictionary<>nebo POCO).
Všechny další hodnoty tras, které neodpovídají parametrům směrování, jsou vloženy 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 generuje /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);
}
Chcete-li 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.
Generovat adresy URL podle směrování
Předchozí kód ukázal generování adresy URL předáním do kontroleru a názvu akce. IUrlHelper také poskytuje adresu URL. RouteUrl řady metod. Tyto metody jsou podobné jako URL. Action, ale nekopírují aktuální hodnoty action a controller do hodnot tras. Nejběžnější využití Url.RouteUrl :
- Určuje název trasy pro vygenerování adresy URL.
- Obecně neurčuje kontrolér nebo název 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 generuje 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
IHtmlHelper poskytuje HtmlHelper metody HTML. BeginForm a HTML. ActionLink ke generování <form> a <a> prvkům v tomto pořadí. Tyto metody používají metodu URL. Action pro VYGENEROVÁNÍ adresy URL a přijímající podobné argumenty. Url.RouteUrlDoprovodníci pro HtmlHelper jsou Html.BeginRouteForm a Html.RouteLink mají podobné funkce.
TagHelpers generuje adresy URL prostřednictvím form taghelperu a <a> taghelperu. Oba tyto použití IUrlHelper při jejich implementaci. Další informace najdete v tématu věnovaném pomocníkům značek ve formulářích .
Uvnitř zobrazení IUrlHelper je k dispozici prostřednictvím Url vlastnosti pro jakoukoli generaci adres URL ad hoc, která není pokrytá výše.
Generování adresy URL ve výsledcích akce
Předchozí příklady ukázaly použití IUrlHelper v kontroleru. Nejběžnějším využitím v kontroleru je vygenerování adresy URL jako součást výsledku akce.
ControllerBase Controller Základní třídy a poskytují pohodlný způsob pro výsledky akcí, které odkazují na jinou akci. Jedním z typických použití je přesměrování po přijetí vstupu uživatele:
[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 pro metody vytváření výsledků, jako je například RedirectToAction a CreatedAtAction následují podobně jako metody v IUrlHelper .
Zvláštní případ pro vyhrazené konvenční trasy
Konvenční směrování může používat speciální druh definice trasy, která se označuje jako vyhrazená konvenční trasa. V následujícím příkladu je trasa s názvem blog 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?}");
});
Když použijete předchozí definice tras, Url.Action("Index", "Home") vygeneruje cestu URL / pomocí default trasy, ale proč? Můžete odhadnout, že hodnoty tras { controller = Home, action = Index } by byly dostatečné pro vygenerování adresy URL pomocí blog a výsledek by byl /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í tomu, aby byla trasa příliš hladkou při generování adresy URL. V tomto případě výchozí hodnoty jsou { controller = Blog, action = Article } a ani controller action se neobjeví jako parametr trasy. Když směrování provádí generování adresy URL, zadané hodnoty musí odpovídat výchozím hodnotám. Generování adresy URL pomocí blog neproběhne úspěšně, protože hodnoty se { controller = Home, action = Index } neshodují { controller = Blog, action = Article } . Směrování pak vrátí zpět k akci default , která bude úspěšná.
Oblasti
Oblasti představují funkci MVC, která slouží k uspořádání souvisejících funkcí do skupiny jako samostatného:
- Obor názvů směrování pro akce kontroleru.
- Struktura složek pro zobrazení.
Použití oblastí umožňuje aplikaci mít více řadičů 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 směrování area do controller a action . Tato část popisuje, jak směrování komunikuje s oblastmi. Podrobnosti o tom, jak se používají oblasti se zobrazeními, najdete v části oblasti .
Následující příklad nakonfiguruje MVC tak, aby používala výchozí konvenční trasu a area trasu pro area název 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 MapAreaControllerRoute je volána k vytvoření "blog_route" . Druhým parametrem "Blog" je název oblasti.
Při porovnání cesty URL jako /Manage/Users/AddUser se v "blog_route" trase vygeneruje hodnoty trasy { area = Blog, controller = Users, action = AddUser } . areaHodnota trasy je vytvořena výchozí hodnotou pro area . Trasa, kterou vytvořil, MapAreaControllerRoute 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 s použitím výchozí hodnoty a omezení pro area použití poskytnutého názvu oblasti v tomto případě Blog . Výchozí hodnota zajistí, ž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.
Pomocí předchozího příkladu se hodnoty tras { area = Blog, controller = Users, action = AddUser } shodují s touto 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] je tím, že označuje kontroler jako součást oblasti. Tento kontroler je v Blog oblasti. Řadiče bez [Area] atributu nejsou členy žádné oblasti a neodpovídají, pokud area je hodnota směrování poskytována směrováním. V následujícím příkladu se může shodovat jenom první kontroler, který bude odpovídat hodnotám tras { area = Blog, controller = Users, action = AddUser } .
using Microsoft.AspNetCore.Mvc;
namespace MyApp.Namespace1
{
[Area("Blog")]
public class UsersController : Controller
{
// GET /manage/users/adduser
public IActionResult AddUser()
{
var area = ControllerContext.ActionDescriptor.RouteValues["area"];
var actionName = ControllerContext.ActionDescriptor.ActionName;
var controllerName = ControllerContext.ActionDescriptor.ControllerName;
return Content($"area name:{area}" +
$" controller:{controllerName} action name: {actionName}");
}
}
}
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}");
}
}
}
Pro úplnost se zobrazí obor názvů každého kontroleru. Pokud předchozí řadiče používaly stejný obor názvů, vygeneruje se chyba kompilátoru. Obory názvů třídy nemají žádný vliv na směrování MVC.
První dva řadiče jsou členy oblastí a odpovídají pouze v případě, že je jejich název příslušné oblasti poskytovaný area hodnotou trasy. Třetí kontroler není členem žádné oblasti a může odpovídat jenom v případě, že area směrováním neposkytuje žádnou hodnotu.
V souvislosti s neshodnou hodnotou area je absence hodnoty stejná, jako kdyby hodnota area null nebo prázdný řetězec.
Při provádění akce uvnitř oblasti je hodnota trasy area dostupná jako ambientní hodnota pro směrování, která se má použít pro generování adresy URL. To znamená, že ve výchozím nastavení jsou tyto oblasti pro generování adresy URL rychlé , jak je znázorněno v následující ukázce.
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 na řadiči, s výjimkou atributu neaction , jsou akce.
Ukázka kódu
- MyDisplayRouteInfo poskytuje balíček NuGet Rick.Docs.Samples.RouteInfo a zobrazuje informace o trasách.
- Zobrazit nebo stáhnout ukázkový kód (Jak stáhnout)
Diagnostika ladění
Pro podrobný výstup diagnostiky směrování nastavte Logging:LogLevel:Microsoft na Debug . Ve vývojovém prostředí nastavte úroveň protokolu v appsettings.Development.jsna:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Debug",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}