Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ryan Nowak, Kirk Larkin és Rick Anderson
Note
Ez nem a cikk legújabb verziója. Az aktuális kiadásról a cikk .NET 10-es verziójában olvashat.
Warning
A ASP.NET Core ezen verziója már nem támogatott. További információt a .NET és a .NET Core támogatási szabályzatában talál. A jelen cikk .NET 9-es verzióját lásd az aktuális kiadásért .
ASP.NET Core vezérlők az Útválasztás köztes szoftvert használják, hogy összepárosítsák a bejövő kérések URL-címeit, és műveletekhez rendeljék őket. Útvonalsablonok:
- Az indításkor
Program.csvagy attribútumokban vannak definiálva. - Írja le, hogyan illeszkednek az URL-útvonalak a műveletekhez.
- A hivatkozások URL-címeinek létrehozására szolgál. A létrehozott hivatkozások általában válaszokban jelennek meg.
A műveletek hagyományosan irányítottak vagy attribútumalapúak. Ha egy útvonalat helyez el a vezérlőn vagy a műveleten , az attribútumalapúvá válik. További információt a Vegyes útválasztás című témakörben talál.
Ez a dokumentum:
- Az MVC és az útválasztás közötti interakciókat ismerteti:
- Hogyan használják a tipikus MVC-alkalmazások az útválasztási funkciókat.
- Mindkettőt lefedi:
- A hagyományos útválasztást általában vezérlőkkel és nézetekkel használják.
- API-kkal használt REST. Ha elsősorban az API-k útválasztása REST érdekli, ugorjon az API-k attribútum-útválasztási szakaszáraREST.
- A speciális útválasztási részletekért tekintse meg az Útválasztás című témakört.
- Az alapértelmezett útválasztási rendszerre, az úgynevezett végpont-útválasztásra hivatkozik. Kompatibilitási okokból az útválasztás előző verziójával rendelkező vezérlőket is használhat. Útmutatásért tekintse meg a 2.2-3.0 migrálási útmutatót .
Hagyományos útvonal beállítása
A ASP.NET Core MVC-sablon a következőhöz hasonló hagyományos útválasztási kódot hoz létre:
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 egyetlen útvonal létrehozásához használható. Az egyetlen útvonal neve default útvonal. A vezérlőkkel és nézetekkel rendelkező alkalmazások többsége az default útvonalhoz hasonló útvonalsablont használ.
REST Az API-knak attribútum-útválasztást kell használniuk.
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Az útvonalsablon "{controller=Home}/{action=Index}/{id?}":
Megfelel egy URL-címnek, például:
/Products/Details/5Kinyeri az útvonal értékeit
{ controller = Products, action = Details, id = 5 }az elérési út tokenizálásával. Az útvonalértékek kinyerése akkor eredményez egyezést, ha az alkalmazásnak van egyProductsControllernevű vezérlője és egyDetailsnevű művelete.public class ProductsController : Controller { public IActionResult Details(int id) { return ControllerContext.MyDisplayRouteInfo(id); } }MyDisplayRouteInfo a Rick.Docs.Samples.RouteInfo NuGet-csomag biztosítja, és megjeleníti az útvonaladatokat.
/Products/Details/5modell a(z)id = 5értéket használja a(z)idparaméter5értékre való kötéséhez. További részletekért tekintse meg a modellkötést .{controller=Home}aHomealapértelmezettkéntcontrollerdefiniálja.{action=Index}aIndexalapértelmezettkéntactiondefiniálja.A
?karakter a{id?}területen opcionálisként határozza meg aid-t.- Az alapértelmezett és az opcionális útvonalparamétereknek nem kell szerepelnie az egyezés URL-címében. Az útvonalsablon szintaxisának részletes leírását az útvonalsablon-referencia című témakörben találja.
Megfelel az URL-cím elérési útvonalának
/.Létrehozza az útvonalértékeket
{ controller = Home, action = Index }.
A controller és action alapértelmezett értékeket használnak.
id nem hoz létre értéket, mivel az URL-elérési útnak nincs megfelelő szegmense.
/ csak akkor egyezik, ha létezik egy HomeController és Index művelet:
public class HomeController : Controller
{
public IActionResult Index() { ... }
}
Az előző vezérlődefiníció és útvonalsablon használatával a művelet a HomeController.Index következő URL-útvonalakon fut:
/Home/Index/17/Home/Index/Home/
Az URL-elérési út / az útvonalsablon alapértelmezett Home vezérlőit és Index műveleteit használja. Az URL-elérési út /Home az útvonalsablon alapértelmezett Index műveletét használja.
A kényelmi módszer MapDefaultControllerRoute:
app.MapDefaultControllerRoute();
Replaces:
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Important
Az útválasztás a UseRouting és a UseEndpoints köztes szoftverekkel van konfigurálva. Vezérlők használata:
- Az MapControllers vezérlők leképezésére irányuló hívás.
- Hívja meg a MapControllerRoute vagy MapAreaControllerRoute, hogy leképezze mind a hagyományosan irányított vezérlőket, mind az attribútumalapú vezérlőket.
Az alkalmazásoknak általában nem kell, hogy meghívják UseRouting vagy UseEndpoints.
WebApplicationBuilder olyan köztes szoftverfolyamatot állít be, amely az Program.cs-ben hozzáadott köztes szoftvereket a UseRouting és UseEndpoints segítségével burkolja. További információkért lásd: Útvonalkezelés az ASP.NET Core-ban.
Hagyományos útválasztás
A hagyományos útválasztás vezérlőkkel és nézetekkel használható. Az default útvonal:
app.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Az előző példa egy hagyományos útvonalra mutat. Ezt hagyományos útválasztásnak nevezik, mert konvenciót hoz létre az URL-útvonalakhoz:
- Az első útvonal szegmens
{controller=Home}a vezérlő nevére lesz leképezve. - A második szegmens a
{action=Index}művelet nevére képeződik le. - A harmadik szegmens
{id?}opcionálisid-ként használatos. A?a{id?}tegében választhatóvá teszi. Aida modellentitásra való leképezéshez használható.
Ezzel az default útvonallal az URL-cím útvonala:
-
/Products/Listleképez aProductsController.Listművelethez. -
/Blog/Article/17leképezBlogController.Articleés általában a modell leköti aidparamétert a 17-es értékhez.
Ez a leképezés:
- Csak a vezérlőn és a műveletnevekenalapul.
- Nem névtereken, forrásfájl-helyeken vagy metódusparamétereken alapul.
A hagyományos útválasztás alapértelmezett útvonallal való használata lehetővé teszi az alkalmazás létrehozását anélkül, hogy minden művelethez új URL-mintát kellene létrehoznia. CRUD stílusműveleteket tartalmazó alkalmazás esetén, amely konzisztenciával rendelkezik a vezérlők URL-címeivel kapcsolatban:
- Segít leegyszerűsíteni a kódot.
- A felhasználói felület kiszámíthatóbbá válik.
Warning
Az id előző kódban szereplő kódot az útvonalsablon nem kötelezőként határozza meg. A műveletek az URL-cím részeként megadott opcionális azonosító nélkül is végrehajthatók. Általában, ha id kihagyva van az URL-ből:
-
idmodellkötés szerint van beállítva0. - Az adatbázisban a
id == 0nem egyezik egyetlen entitással sem.
Az attribútum-útválasztás részletes vezérlést biztosít, amely lehetővé teszi, hogy az azonosító bizonyos műveletekhez szükséges legyen, nem pedig mások számára. A konvenció szerint a dokumentáció tartalmazza az olyan választható paramétereket, mint a id, amikor azok valószínűleg a helyes használat során jelennek meg.
A legtöbb alkalmazásnak alapszintű és leíró útválasztási sémát kell választania, hogy az URL-címek olvashatók és értelmezhetők legyenek. Az alapértelmezett hagyományos útvonal {controller=Home}/{action=Index}/{id?}:
- Alapszintű és leíró útválasztási sémát támogat.
- Hasznos kiindulópont a felhasználói felületalapú alkalmazásokhoz.
- Ez az egyetlen útválasztási sablon, amely sok webes felhasználói felületi alkalmazáshoz szükséges. A nagyobb webes felhasználói felületi alkalmazások esetében gyakran csak a Területeket használó másik útvonalra van szükség.
MapControllerRoute és MapAreaRoute :
- Automatikusan rendeljen hozzá sorrendi értéket a végpontokhoz a meghívás sorrendje alapján.
Végpont-útválasztás a ASP.NET Core-ban:
- Nincs fogalma az útvonalakról.
- Nem biztosít rendelési garanciákat a bővíthetőség végrehajtásához, az összes végpont egyszerre lesz feldolgozva.
Engedélyezze a naplózást, hogy megtekintse, hogyan illeszkednek a beépített útválasztási implementációk, mint például Route, a kérésekhez.
Az attribútumok útválasztását a dokumentum későbbi részében ismertetik.
Több hagyományos útvonal
Több hagyományos útvonal is konfigurálható további hívások MapControllerRoute hozzáadásával.MapAreaControllerRoute Ez lehetővé teszi több konvenció meghatározását, vagy egy adott művelethez dedikált hagyományos útvonalak hozzáadását, például:
app.MapControllerRoute(name: "blog",
pattern: "blog/{*article}",
defaults: new { controller = "Blog", action = "Article" });
app.MapControllerRoute(name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Az blog előző kódban szereplő útvonal egy dedikált hagyományos útvonal. Ez az úgynevezett dedikált hagyományos útvonal, mert:
- Hagyományos útválasztást használ.
- Egy adott műveletnek van szentelve.
Azért, mert a controller és action nem jelenik meg a "blog/{*article}" útvonalsablonban paraméterekként:
- Csak az alapértelmezett értékekkel
{ controller = "Blog", action = "Article" }rendelkezhetnek. - Ez az útvonal mindig a művelethez lesz megfeleltetve
BlogController.Article.
/Blog, /Blog/Articleés /Blog/{any-string} ezek az egyetlen URL-elérési utak, amelyek megfelelnek a blog útvonalának.
Az előző példa:
-
blogaz útvonal nagyobb prioritással rendelkezik az egyezésekhez, mint azdefaultútvonal, mert az elsőként van hozzáadva. - Példa a Slug-stílus útválasztására, ahol általában egy cikknév szerepel az URL-cím részeként.
Warning
A ASP.NET Core-ban az útválasztás nem:
- Definiáljon egy útvonalnak nevezett fogalmat.
UseRoutingA köztesszoftver-folyamatnak megfelelő útvonalat ad hozzá. AUseRoutingköztes szoftver megvizsgálja az alkalmazásban definiált végpontokat, és a kérés alapján kiválasztja a legjobb végpontegyezést. - Biztosítson garanciákat a bővíthetőség végrehajtási sorrendjére, például IRouteConstraint vagy IActionConstraint.
Az útválasztással kapcsolatos referenciaanyagokért tekintse meg az Útválasztás című témakört.
Hagyományos útválasztási sorrend
A hagyományos útválasztás csak az alkalmazás által meghatározott művelet és vezérlő kombinációjával egyezik meg. Ez leegyszerűsíti azokat az eseteket, amikor a hagyományos útvonalak átfedésben vannak.
Útvonalak hozzáadása a MapControllerRoute, MapDefaultControllerRoute és MapAreaControllerRoute használatával automatikusan rendelési értéket ad a végpontokhoz a meghívásuk sorrendje alapján. Az útvonal, amely korábban jelenik meg, egyezései magasabb prioritással rendelkeznek. A hagyományos útválasztás sorrendfüggő. Általánosságban elmondható, hogy a területekkel rendelkező útvonalakat korábban kell elhelyezni, mivel ezek pontosabbak, mint a terület nélküli útvonalak.
Az olyan hagyományos útvonalak, mint például {*article} a catch-all útvonalparaméterek, túl mohóvá tehetik az útvonalakat, ami azt jelenti, hogy megegyezik a más útvonalakkal egyeztetni kívánt URL-címekkel. A kapzsi útvonalakat később helyezze el az útvonaltáblában, hogy megakadályozza a kapzsi egyezéseket.
Warning
A catch-all paraméter helytelenül felelhet meg az útvonalaknak egy útválasztási hiba miatt. A hiba által érintett alkalmazások jellemzői a következők:
- Egy mindent megragadó útvonal, például:
{**slug}" - A catch-all útvonal nem egyezik meg azokkal a kérésekkel, amelyeket meg kellene egyeznie.
- Ha eltávolít más útvonalakat, az összeset megfogó útvonal elkezd működni.
Tekintse meg a GitHub 18677 és 16579 hibáit a példaesetekért, amelyekben ez a hiba felmerül.
A hiba jóváhagyási javítása a .NET Core 3.1.301-ben vagy újabb SDK-ban található. A következő kód beállít egy belső kapcsolót, amely megoldja ezt a hibát:
public static void Main(string[] args)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Routing.UseCorrectCatchAllBehavior",
true);
CreateHostBuilder(args).Build().Run();
}
// Remaining code removed for brevity.
Nem egyértelmű műveletek feloldása
Ha két végpont egyezik az útválasztással, az útválasztásnak az alábbiak egyikét kell elvégeznie:
- Válassza ki a legjobb jelöltet.
- Kivételt kell kivenni.
Például:
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);
}
}
Az előző vezérlő két, egyező műveletet határoz meg:
- Az URL-cím elérési útja
/Products33/Edit/17 - Útvonaladatok
{ controller = Products33, action = Edit, id = 17 }.
Ez az MVC-vezérlők tipikus mintája:
-
Edit(int)egy termék szerkesztéséhez használandó űrlapot jelenít meg. -
Edit(int, Product)feldolgozza a közzétett űrlapot.
Az útvonal helyes kijelölése:
-
Edit(int, Product)akkor van kiválasztva, ha a kérés HTTPPOST. -
Edit(int)akkor van kiválasztva, ha a HTTP-ige bármi más.Edit(int)-t általábanGEThasználatával hívjuk meg.
A HttpPostAttribute, [HttpPost]az útválasztáshoz van megadva, hogy a kérés HTTP-metódusa alapján válasszon. Az HttpPostAttribute jobban megteszi Edit(int, Product)-t megfelelőbbé, mint a Edit(int).
Fontos megérteni az olyan attribútumok szerepét, mint HttpPostAttributea . Más HTTP-parancsokhoz hasonló attribútumok vannak definiálva. A hagyományos útválasztásban gyakran előfordul, hogy a műveletek ugyanazt a műveletnevet használják, amikor egy megjelenítési űrlap részei, és űrlap-munkafolyamatot küldenek. Lásd például a két szerkesztési művelet módszerét.
Ha az útválasztás nem tudja kiválasztani a legjobb jelöltet, AmbiguousMatchException a több egyező végpontot listázó üzenet megjelenik.
Hagyományos útvonalnevek
A "blog" és "default" karakterláncok az alábbi példákban a hagyományos útvonalnevek:
app.MapControllerRoute(name: "blog",
pattern: "blog/{*article}",
defaults: new { controller = "Blog", action = "Article" });
app.MapControllerRoute(name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Az útvonalnevek logikai nevet adnak az útvonalnak. A névvel ellátott útvonal használható AZ URL-cím létrehozásához. A névvel ellátott útvonalak használata egyszerűbbé teszi az URL-címek létrehozását, ha az útvonalak sorrendje megnehezítheti az URL-címek létrehozását. Az útvonalneveknek egyedi alkalmazásszintűnek kell lenniük.
Útvonalnevek:
- Nincs hatással az URL-címek egyeztetésére vagy a kérések kezelésére.
- Csak AZ URL-cím generálásához használhatók.
Az útvonalnév fogalma az útválasztásban IEndpointNameMetadata néven jelenik meg. Az útvonalnév és a végpont neve:
- Felcserélhetők.
- Hogy melyik kerül felhasználásra a dokumentációban és a kódban, az a leírt API-tól függ.
API-k attribútum alapú útválasztása REST
REST Az API-knak attribútumalapú útválasztással kell modelleznie az alkalmazás funkcióit olyan erőforrások készleteként, ahol a műveleteket HTTP-parancsok jelölik.
Az attribútum-útválasztás egy sor attribútum segítségével közvetlenül hozzárendeli a műveleteket az útvonal sablonokhoz. Az API-k esetében REST a következő kód jellemző, és a következő mintában használatos:
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddControllers();
var app = builder.Build();
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.Run();
Az előző kódban MapControllers az attribútumalapú vezérlők leképezésére van meghívva.
Az alábbi példában:
-
HomeControlleregyezik az alapértelmezett hagyományos útvonalhoz{controller=Home}/{action=Index}/{id?}hasonló URL-címekkel.
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);
}
}
A HomeController.Index művelet az URL-címek //Homebármelyikén fut, /Home/Indexvagy /Home/Index/3.
Ez a példa kiemeli az attribútum-útválasztás és a hagyományos útválasztás közötti kulcsfontosságú programozási különbséget. Az attribútum-útválasztáshoz több bemenetre van szükség az útvonal megadásához. A hagyományos alapértelmezett útvonal tömörebben kezeli az útvonalakat. Az attribútumalapú útválasztás azonban lehetővé teszi és megköveteli annak pontos szabályozását, hogy mely útvonalsablonok vonatkozzanak az egyes műveletekre.
Attribútum alapú útválasztás esetén a vezérlő és az akciónevek nem játszanak szerepet az akció egyeztetésében, kivéve, ha kivonatcsere történik. Az alábbi példa megegyezik az előző példával megegyező URL-címekkel:
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);
}
}
Az alábbi kód token helyettesítést alkalmaz a action és a controller esetében:
public class HomeController : Controller
{
[Route("")]
[Route("Home")]
[Route("[controller]/[action]")]
public IActionResult Index()
{
return ControllerContext.MyDisplayRouteInfo();
}
[Route("[controller]/[action]")]
public IActionResult About()
{
return ControllerContext.MyDisplayRouteInfo();
}
}
A vezérlőre a következő kód vonatkozik [Route("[controller]/[action]")] :
[Route("[controller]/[action]")]
public class HomeController : Controller
{
[Route("~/")]
[Route("/Home")]
[Route("~/Home/Index")]
public IActionResult Index()
{
return ControllerContext.MyDisplayRouteInfo();
}
public IActionResult About()
{
return ControllerContext.MyDisplayRouteInfo();
}
}
Az előző kódban a Index metódussablonok előtt el kell helyezni a / vagy ~/ útvonalsablonokat. Olyan műveletre alkalmazott útvonalsablonok, amelyek a vezérlőre alkalmazott útvonalsablonokkal kezdődnek / vagy ~/ nem kombinálódnak.
Az útvonalsablon kiválasztásával kapcsolatos információkért tekintse meg az Útvonalsablon elsőbbsége című témakört.
Fenntartott útválasztási nevek
A következő kulcsszavak fenntartott útvonalparaméternevek a vezérlők vagy Razor lapok használatakor:
actionareacontrollerhandlerpage
Az attribútumalapú útválasztással rendelkező útvonalparaméter használata page gyakori hiba. Ez inkonzisztens és zavaró viselkedést eredményez az URL-generálással.
public class MyDemo2Controller : Controller
{
[Route("/articles/{page}")]
public IActionResult ListArticles(int page)
{
return ControllerContext.MyDisplayRouteInfo(page);
}
}
Az URL-generáció a speciális paraméterneveket használja annak megállapítására, hogy egy URL-létrehozási művelet egy lapra vagy egy Razor vezérlőre hivatkozik-e.
A következő kulcsszavak egy Razor nézet vagy egy Razor oldal kontextusában vannak fenntartva.
pageusingnamespaceinjectsectioninheritsmodeladdTagHelperremoveTagHelper
Ezeket a kulcsszavakat nem szabad hivatkozásgenerációkhoz, modellhez kötött paraméterekhez vagy legfelső szintű tulajdonságokhoz használni.
HTTP-parancssablonok
ASP.NET Core a következő HTTP-igesablonokkal rendelkezik:
Útvonalsablonok
ASP.NET Core a következő útvonalsablonokkal rendelkezik:
- Az összes HTTP-igesablon útvonalsablon.
- [Route]
Attribútum-útválasztás Http ige attribútumokkal
Vegye figyelembe a következő vezérlőt:
[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);
}
}
Az előző kódban:
- Minden művelet tartalmazza az
[HttpGet]attribútumot, amely csak a HTTP GET-kérelmeknek való megfelelést korlátozza. - A
GetProductművelet tartalmazza a"{id}"sablont, ezértidhozzá van fűzve a"api/[controller]"sablonhoz a vezérlőn. A metódussablon a következő"api/[controller]/{id}": . Ezért ez a művelet csak az űrlap/api/test2/xyzGET kéréseinek felel meg,/api/test2/123,/api/test2/{any string}, stb.[HttpGet("{id}")] // GET /api/test2/xyz public IActionResult GetProduct(string id) { return ControllerContext.MyDisplayRouteInfo(id); } - A
GetIntProductművelet tartalmazza a sablont"int/{id:int}". A:intsablon része azidútvonalértékeket egész számmá konvertálható sztringekre korlátozza. GET kérés a következőhöz/api/test2/int/abc:- Nem egyezik ezzel a művelettel.
-
404 Nem található hibát ad vissza.
[HttpGet("int/{id:int}")] // GET /api/test2/int/3 public IActionResult GetIntProduct(int id) { return ControllerContext.MyDisplayRouteInfo(id); }
- A
GetInt2Productművelet tartalmazza a sablonban{id}, de nem korlátozzaidazokra az értékekre, amelyeket egész számmá lehet konvertálni. GET kérés a következőhöz/api/test2/int2/abc:- Megfelel ennek az útvonalnak.
- A modellkötés nem konvertálható
abcegész számmá. Aidmetódus paramétere egész szám. -
400-os hibás kérést ad vissza, mert a modellkötést nem sikerült egész számmá alakítani
abc.[HttpGet("int2/{id}")] // GET /api/test2/int2/3 public IActionResult GetInt2Product(int id) { return ControllerContext.MyDisplayRouteInfo(id); }
Az attribútum-útválasztás olyan attribútumokat használhat, mint az HttpMethodAttribute, HttpPostAttribute, HttpPutAttribute és HttpDeleteAttribute. Az összes HTTP-igeattribútum elfogad egy útvonalsablont. Az alábbi példa két olyan műveletet mutat be, amelyek azonos útvonalsablonnak felelnek meg:
[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);
}
}
Az URL-elérési út /products3használata:
- A
MyProductsController.ListProductsművelet akkor fut, ha a HTTP-igeGET. - A
MyProductsController.CreateProductművelet akkor fut, ha a HTTP-igePOST.
API-k készítésekor ritka, hogy egy metóduson használnia kell REST, mert a metódus minden HTTP-metódust elfogad. Érdemes a pontosabb HTTP használati attribútumot használni, hogy egyértelműen jelezze, mit támogat az API. REST Az API-k ügyfeleinek várhatóan tudniuk kell, hogy milyen elérési utak és HTTP-igék vannak leképezve adott logikai műveletekre.
REST Az API-knak attribútumalapú útválasztással kell modelleznie az alkalmazás funkcióit olyan erőforrások készleteként, ahol a műveleteket HTTP-parancsok jelölik. Ez azt jelenti, hogy számos művelet, például a GET és a POST ugyanazon a logikai erőforráson ugyanazt az URL-címet használja. Az attribútum-útválasztás olyan szintű vezérlést biztosít, amely az API nyilvános végpontelrendezésének gondos tervezéséhez szükséges.
Mivel az attribútumútvonalak egy adott műveletre vonatkoznak, az útvonalsablon definíciójának részeként könnyen megkövetelhetőek a paraméterek. A következő példában id az URL-elérési út részeként szükséges:
[ApiController]
public class Products2ApiController : ControllerBase
{
[HttpGet("/products2/{id}", Name = "Products_List")]
public IActionResult GetProduct(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
}
A Products2ApiController.GetProduct(int) művelet:
- Olyan URL-címmel futtatható, mint
/products2/3 - Az URL-cím elérési útvonalával
/products2nincs futtatva.
A [Felhasználás] attribútum lehetővé teszi, hogy egy művelet korlátozza a támogatott kérelem tartalomtípusait. További információ: Támogatott kérések tartalomtípusainak definiálása az Consumes attribútummal.
Az útvonalsablonok és a kapcsolódó beállítások teljes leírását az Útválasztás című témakörben talál.
További információ: [ApiController]ApiController attribútum.
Útvonal neve
Az alábbi kód a következő útvonalnevet Products_Listhatározza meg:
[ApiController]
public class Products2ApiController : ControllerBase
{
[HttpGet("/products2/{id}", Name = "Products_List")]
public IActionResult GetProduct(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
}
Az útvonalnevek egy adott útvonalon alapuló URL-cím létrehozásához használhatók. Útvonalnevek:
- Nincs hatással az útválasztás URL-címmegfeleltetési viselkedésére.
- Csak URL-címek létrehozására használatos.
Az útvonalneveknek alkalmazásszintű egyedinek kell lenniük.
Határozd szembe az előző kódot a hagyományos alapértelmezett útvonallal, amely a id paramétert opcionálisként ({id?}) határozza meg. Az API-k pontos meghatározásának lehetősége előnyökkel jár, mint például az, hogy a /products és /products/5 különböző műveletekhez való továbbítását lehetővé teszi.
Attribútumútvonalak kombinálása
Az attribútum-útválasztás kevésbé ismétlődővé tétele érdekében a vezérlő útvonalattribútumait a rendszer az egyes műveletek útvonalattribútumaival kombinálja. A vezérlőben definiált útvonalsablonok előre fel vannak függve a műveletek útvonalsablonjaira. Ha egy útvonalattribútumot helyez el a vezérlőn, a vezérlőben lévő összes művelet attribútumalapú útválasztást használ.
[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);
}
}
Az előző példában:
- Az URL-cím megegyezhet
/productsProductsApi.ListProducts - Az URL-cím megegyezhet
/products/5ProductsApi.GetProduct(int).
Mindkét művelet csak a HTTP-nek GET felel meg, mert az [HttpGet] attribútummal vannak megjelölve.
Olyan műveletre alkalmazott útvonalsablonok, amelyek a vezérlőre alkalmazott útvonalsablonokkal kezdődnek / vagy ~/ nem kombinálódnak. Az alábbi példa az alapértelmezett útvonalhoz hasonló URL-útvonalakat tartalmaz.
[Route("Home")]
public class HomeController : Controller
{
[Route("")]
[Route("Index")]
[Route("/")]
public IActionResult Index()
{
return ControllerContext.MyDisplayRouteInfo();
}
[Route("About")]
public IActionResult About()
{
return ControllerContext.MyDisplayRouteInfo();
}
}
Az alábbi táblázat az [Route] előző kód attribútumait ismerteti:
| Attribute | Kombinálva [Route("Home")]-vel |
Útvonalsablon definiálása |
|---|---|---|
[Route("")] |
Yes | "Home" |
[Route("Index")] |
Yes | "Home/Index" |
[Route("/")] |
No | "" |
[Route("About")] |
Yes | "Home/About" |
Attribútumútvonal sorrendje
Az útválasztás létrehoz egy fát, és az összes végpontot egyidejűleg összekapcsolja.
- Az útvonalbejegyzések úgy viselkednek, mintha ideális sorrendbe helyezték volna.
- A legspecifikusabb útvonalak az általánosabb útvonalak előtt hajthatók végre.
Például egy attribútumútvonal blog/search/{topic} pontosabb, mint egy attribútumútvonal, például blog/{*article}. Az blog/search/{topic} útvonal alapértelmezés szerint magasabb prioritással rendelkezik, mert pontosabb. A hagyományos útválasztás használatával a fejlesztő felelős az útvonalak kívánt sorrendbe helyezéséért.
Az attribútumútvonalak konfigurálhatják a rendelést a Order tulajdonság használatával. Az összes keretrendszer által biztosított útvonalattribútum tartalmazza . Az útvonalak feldolgozása a Order tulajdonság növekvő sorrendje szerint történik. Az alapértelmezett sorrend a következő 0: . Az útvonal beállítása a Order = -1 használatával azok előtt történik meg, amelyek nem rendelkeznek sorrenddel. Az útvonal beállítása a(z) Order = 1 használatával az alapértelmezett útvonalrendezés után történik.
Kerülje a függést . Ha egy alkalmazás URL-címe explicit rendelési értékeket igényel a helyes útválasztáshoz, az valószínűleg az ügyfelek számára is zavaró. Az attribútum-útválasztás általában a megfelelő útvonalat választja ki URL-egyezéssel. Ha az URL-létrehozáshoz használt alapértelmezett sorrend nem működik, az útvonalnév felülbírálásként való használata általában egyszerűbb, mint a Order tulajdonság alkalmazása.
Vegye figyelembe az alábbi két vezérlőt, amelyek mindkettő az útvonalegyezést /homehatározzák meg:
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);
}
}
Az előző kóddal való kérés /home a következőhöz hasonló kivételt eredményez:
AmbiguousMatchException: The request matched multiple endpoints. Matches:
WebMvcRouting.Controllers.HomeController.Index
WebMvcRouting.Controllers.MyDemoController.MyIndex
Az útvonalattribútumok egyikének hozzáadása Order feloldja a kétértelműséget:
[Route("")]
[Route("Home", Order = 2)]
[Route("Home/MyIndex")]
public IActionResult MyIndex()
{
return ControllerContext.MyDisplayRouteInfo();
}
Az előző kóddal /home futtatja a végpontot HomeController.Index . Az MyDemoController.MyIndex eléréséhez kérje /home/MyIndex.
Note:
- Az előző kód egy példa vagy rossz útválasztási terv. A
Ordera tulajdonság szemléltetésére szolgált. - A
Ordertulajdonság csak a kétértelműséget oldja fel, a sablon nem feleltethető meg. Jobb lenne eltávolítani a sablont[Route("Home")].
Lásd aRazor Oldalak útvonal- és alkalmazáskonvencióit: Útvonal sorrend a Pages alkalmazással Razor kapcsolatos útvonal sorrend információkért.
Bizonyos esetekben egy HTTP 500-as hibát ad vissza, amikor útvonalak nem egyértelműek. A naplózás használatával megtekintheti, hogy mely végpontok okozták a AmbiguousMatchException.
Jogkivonat cseréje útvonalsablonokban [vezérlő], [művelet], [terület]
A kényelem érdekében az attribútumútvonalak támogatják a jogkivonatok cseréjét úgy, hogy szögletes zárójelekbe ([, ]) foglalnak egy jogkivonatot. A jogkivonatok [action], [area] és [controller] a műveletnév, a területnév és a vezérlő nevének értékeire cserélődnek a műveletből, ahol az útvonal definiálva van.
[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);
}
}
Az előző kódban:
[HttpGet]
public IActionResult List()
{
return ControllerContext.MyDisplayRouteInfo();
}
- Mérkőzések
/Products0/List
[HttpGet("{id}")]
public IActionResult Edit(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
- Mérkőzések
/Products0/Edit/{id}
A token cseréje az attribute útvonalak építésének utolsó lépése. Az előző példa ugyanúgy viselkedik, mint a következő 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);
}
}
Ha ezt nem angol nyelven olvassa, ebben a GitHub-vitafórumban tudassa velünk, ha meg szeretné tekinteni a kód megjegyzéseit az anyanyelvén.
Az attribútumútvonalak örökléssel is kombinálhatók. Ez a tokencserével kombinálva erős. A jelölő cseréje az attribútum útvonalak által definiált útvonalnevekre is vonatkozik.
[Route("[controller]/[action]", Name="[controller]_[action]")]minden művelethez létrehoz egy egyedi útvonalnevet:
[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);
}
}
A [ vagy ] literális token helyettesítő elválasztójának megadásához ismételje meg a karaktert ([[ vagy ]]) a kilépéshez.
Paraméterátalakító használata a tokenek cseréjének testreszabásához
A tokencsere paraméterátalakítóval testre szabható. A paraméterátalakító implementálja IOutboundParameterTransformer és átalakítja a paraméterek értékét. Egy egyéni SlugifyParameterTransformer paraméterátalakító például a következőre módosítja az SubscriptionManagement útvonal értékét 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();
}
}
A RouteTokenTransformerConvention egy olyan alkalmazásmodell-konvenció, amely:
- Paraméterátalakítót alkalmaz az alkalmazás összes attribútumútvonalára.
- A csere során testre szabja az attribútumútvonal-jogkivonat értékeit.
public class SubscriptionManagementController : Controller
{
[HttpGet("[controller]/[action]")]
public IActionResult ListAll()
{
return ControllerContext.MyDisplayRouteInfo();
}
}
Az előző ListAll metódus egyezik /subscription-management/list-all.
A RouteTokenTransformerConvention beállítás a következőként van regisztrálva:
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();
A Slug definícióját a Slug MDN webes dokumentációja tartalmazza.
Warning
Amikor a System.Text.RegularExpressions-t használja nem megbízható bemenetek feldolgozására, meg kell adnia egy időtúllépési értéket. Egy rosszindulatú felhasználó adhat RegularExpressions bemenetet, ami szolgáltatásmegtagadásos támadást okozhat. ASP.NET Core keretrendszer API-k, amelyek RegularExpressions időtúllépést használnak.
Több attribútumútvonal
Az attribútumalapú útválasztás támogatja az azonos műveletet elérő útvonalak meghatározását. Ennek leggyakrabban az alapértelmezett hagyományos útvonal viselkedését kell utánoznia az alábbi példában látható módon:
[Route("[controller]")]
public class Products13Controller : Controller
{
[Route("")] // Matches 'Products13'
[Route("Index")] // Matches 'Products13/Index'
public IActionResult Index()
{
return ControllerContext.MyDisplayRouteInfo();
}
Ha több útvonalattribútumot helyez el a vezérlőn, az azt jelenti, hogy mindegyik egyesül a műveleti módszerek útvonalattribútumaival:
[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();
}
}
Az összes HTTP-igeútvonal-korlátozás implementálva IActionConstraintvan.
Ha több útvonalattribútum, amely implementálja IActionConstraint-t, kerül egy akcióra:
- Minden műveletkényszer kombinálva van a vezérlőre alkalmazott útvonalsablonnal.
[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();
}
}
Ha több útvonalat használ a műveletekhez, hasznosnak és hatékonynak tűnhet, jobb, ha az alkalmazás URL-címterét alapszintűen és jól definiálva tartja. Csak akkor használjon több útvonalat a műveleteken, ha szükséges, például a meglévő ügyfelek támogatására.
Attribútumútvonal opcionális paramétereinek, alapértelmezett értékeinek és kényszereinek megadása
Az attribútumútvonalak ugyanazt a beágyazott szintaxist támogatják, mint a hagyományos útvonalak, hogy opcionális paramétereket, alapértelmezett értékeket és korlátozásokat adjanak meg.
public class Products14Controller : Controller
{
[HttpPost("product14/{id:int}")]
public IActionResult ShowProduct(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
}
Az előző kódban [HttpPost("product14/{id:int}")] alkalmaz egy útvonalkorlátozást. A Products14Controller.ShowProduct művelet csak azokkal az URL-címekkel egyezik meg, mint például /product14/3. Az útvonalsablon része {id:int} csak egész számokra korlátozza a szegmenst.
Az útvonalsablon szintaxisának részletes leírását az útvonalsablon-referencia című témakörben találja.
Egyéni útvonalattribútumok az IRouteTemplateProvider használatával
Az összes útvonalattribútumIRouteTemplateProvider-t implementál. A ASP.NET Core-futtatókörnyezet:
- Attribútumokat keres a vezérlőosztályokon és a műveleti módszereken az alkalmazás indításakor.
- A implementálandó
IRouteTemplateProviderattribútumokkal hozza létre a kezdeti útvonalakat.
Egyéni útvonalattribútumok definiálásához implementálható IRouteTemplateProvider . Mindegyik IRouteTemplateProvider lehetővé teszi egyetlen útvonal egyéni útvonalsablon, sorrend és név megadását:
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();
}
}
Az előző Get metódus ad vissza Order = 2, Template = api/MyTestApi.
Attribútumútvonalak testreszabása alkalmazásmodell használatával
Az alkalmazásmodell:
- Az
Program.csindításakor létrejön egy objektum modell. - Az ASP.NET Core által az alkalmazásokban végzett műveletek irányításához és végrehajtásához használt összes metaadatot tartalmazza.
Az alkalmazásmodell tartalmazza az útvonalattribútumokból összegyűjtött összes adatot. Az útvonalattribútumokból származó adatokat a IRouteTemplateProvider megvalósítás biztosítja. Conventions:
- Meg lehet írni az alkalmazás modelljét úgy, hogy az útválasztás viselkedése testreszabható legyen.
- Az alkalmazás indításakor kerülnek beolvasásra.
Ez a szakasz egy egyszerű példát mutat be az útválasztás alkalmazásmodell használatával történő testreszabására. Az alábbi kód hozzávetőlegesen igazodik a projekt mappastruktúrájához.
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()
};
}
}
}
Az alábbi kód megakadályozza, hogy a namespace konvenció az attribútummal ellátott vezérlőkre vonatkozzon.
public void Apply(ControllerModel controller)
{
var hasRouteAttributes = controller.Selectors.Any(selector =>
selector.AttributeRouteModel != null);
if (hasRouteAttributes)
{
return;
}
A következő vezérlő például nem használja a NamespaceRoutingConvention jelet:
[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}");
}
}
A NamespaceRoutingConvention.Apply módszer:
- Nem tesz semmit, ha a vezérlő attribútum-alapú útvonalakat használ.
- Beállítja a vezérlősablont az
namespacealapján, aznamespacealap eltávolításával.
A NamespaceRoutingConvention következő helyen Program.csalkalmazható:
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();
Vegyük például a következő vezérlőt:
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}");
}
}
}
Az előző kódban:
- Az alap
namespacea .My.Application - Az előző vezérlő teljes neve .
My.Application.Admin.Controllers.UsersController - A
NamespaceRoutingConventiona vezérlősablontAdmin/Controllers/Users/[action]/{id?-ra állítja be.
A NamespaceRoutingConvention vezérlők attribútumaként is alkalmazhatók:
[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}");
}
}
Vegyes útválasztás: Attribútum-útválasztás és hagyományos útválasztás
ASP.NET Core-alkalmazások vegyesen használhatják a hagyományos útválasztást és az attribútumalapú útválasztást. Általában hagyományos útvonalakat használnak a böngészők html lapjait kiszolgáló vezérlőkhöz, az API-kat kiszolgáló REST vezérlők attribútum-útválasztásához.
A műveletek vagy hagyományos útvonalra vannak állítva, vagy attribútumok alapján vannak irányítva. Ha egy útvonalat helyez el a vezérlőn vagy a műveleten, az attribútum átirányítva lesz. Az attribútumútvonalakat meghatározó műveletek nem érhetőek el a hagyományos útvonalakon keresztül, és fordítva. A vezérlő bármely útvonalattribútuma a vezérlő attribútumában található összes műveletet átirányítja.
Az attribútum-útválasztás és a hagyományos útválasztás ugyanazt az útválasztási motort használja.
Útválasztás speciális karakterekkel
A speciális karaktereket tartalmazó útválasztás váratlan eredményekhez vezethet. Vegyük például az alábbi műveletmetódusú vezérlőt:
[HttpGet("{id?}/name")]
public async Task<ActionResult<string>> GetName(string id)
{
var todoItem = await _context.TodoItems.FindAsync(id);
if (todoItem == null || todoItem.Name == null)
{
return NotFound();
}
return todoItem.Name;
}
Ha string id a következő kódolt értékeket tartalmazza, váratlan eredmények léphetnek fel:
| ASCII | Encoded |
|---|---|
/ |
%2F |
|
+ |
Az útvonalparaméterek nem mindig vannak dekódolva az URL-ből. Ez a probléma a jövőben megoldható. További információkért tekintse meg ezt a GitHub-problémát;
URL-létrehozási és környezeti értékek
Az alkalmazások útválasztási URL-címgenerálási funkciókkal hozhatnak létre URL-hivatkozásokat a műveletekhez. Az URL-címek létrehozása megszünteti a szigorú kódolású URL-címeket , így a kód robusztusabb és karbantarthatóbb lesz. Ez a szakasz az MVC által biztosított URL-létrehozási funkciókra összpontosít, és csak az URL-létrehozás működésének alapjait ismerteti. Az URL-cím generálásának részletes leírását az Útválasztás című témakörben találja.
Az IUrlHelper interfész az MVC és az URL-generálás útválasztása közötti infrastruktúra mögöttes eleme. A IUrlHelper példány elérhető a Url tulajdonságon keresztül a vezérlőkben, nézetekben és nézetösszetevőkben.
Az alábbi példában a rendszer a tulajdonságon keresztül használja az IUrlHelperController.Url interfészt egy URL-cím létrehozásához egy másik művelethez.
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();
}
}
Ha az alkalmazás az alapértelmezett hagyományos útvonalat használja, a url változó értéke az URL-elérési út sztringje /UrlGeneration/Destination. Ez az URL-elérési út útválasztással van létrehozva az alábbiak kombinálásával:
- Az aktuális kérés útvonalértékei, amelyeket környezeti értékeknek neveznek.
- Az értékek átadása a
Url.Actionrészére és azoknak az értékeknek a helyettesítése az útvonalsablonban:
ambient values: { controller = "UrlGeneration", action = "Source" }
values passed to Url.Action: { controller = "UrlGeneration", action = "Destination" }
route template: {controller}/{action}/{id?}
result: /UrlGeneration/Destination
Az útvonalsablonban minden útvonalparaméter értéke lecserélődik oly módon, hogy a nevek össze vannak párosítva a paraméterértékekkel és a környezeti értékekkel. Egy olyan útvonalparaméter, amely nem rendelkezik értékkel, a következőt teheti:
- Használjon alapértelmezett értéket, ha rendelkezik ilyen értékkel.
- Kihagyható, ha nem kötelező. Például az
idútvonalsablonból{controller}/{action}/{id?}.
Az URL-cím létrehozása meghiúsul, ha a szükséges útvonalparaméter nem rendelkezik megfelelő értékkel. Ha egy útvonal URL-generálása sikertelen, a következő útvonal mindaddig próbálkozik, amíg az összes útvonal ki nem próbálva, vagy nem talál egyezést.
Az előző példa Url.Action a hagyományos útválasztást feltételezi. Az URL-generálás hasonlóan működik az attribútum-útválasztással, bár a fogalmak eltérnek. Hagyományos útválasztással:
- Az útvonalértékek egy sablon kibontására szolgálnak.
- A
controllerésactionútvonalértékei általában megjelennek ebben a sablonban. Ez azért működik, mert az útválasztással egyező URL-címek megfelelnek egy konvenciónak.
Az alábbi példa attribútum-útválasztást használ:
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();
}
}
Az Source előző kódban szereplő művelet generálja a következőt custom/url/to/destination: .
LinkGenerator ASP.NET Core 3.0-ban lett hozzáadva IUrlHelper alternatívájaként.
LinkGenerator hasonló, de rugalmasabb funkciókat kínál. Minden metódushoz IUrlHelper tartozik egy megfelelő metóduscsalád LinkGenerator is.
URL-címek létrehozása műveletnév alapján
Az URL.Action, a LinkGenerator.GetPathByAction és a kapcsolódó túlterhelések mindegyike úgy van kialakítva, hogy létrehozhassa a célvégpontot egy vezérlőnév és műveletnév megadásával.
Használat Url.Action esetén a futtatókörnyezet biztosítja a controller és action aktuális útvonalértékeit.
-
controllerésactionértéke mind a környezeti értékek, mind pedig az általános értékek része. A metódusUrl.Actionmindig az aktuális értékeketactionhasználja, éscontrollerlétrehoz egy URL-útvonalat, amely az aktuális művelethez vezet.
Az útválasztás a környezeti értékek értékeit használja az URL-cím létrehozásakor nem megadott információk kitöltésére. Fontoljon meg egy útvonalat, mint például {a}/{b}/{c}/{d}, a környezeti értékekkel { a = Alice, b = Bob, c = Carol, d = David }.
- Az útválasztás elegendő információval rendelkezik ahhoz, hogy további értékek nélkül hozzon létre URL-címet.
- Az útválasztás elegendő információval rendelkezik, mert minden útvonalparaméternek van értéke.
Ha az érték { d = Donovan } hozzáadva van:
- Az érték
{ d = David }figyelmen kívül lesz hagyva. - A létrehozott URL-elérési út a következő
Alice/Bob/Carol/Donovan: .
Figyelmeztetés: Az URL-elérési utak hierarchikusak. Az előző példában, ha az érték { c = Cheryl } hozzá van adva:
- A rendszer mindkét értéket
{ c = Carol, d = David }figyelmen kívül hagyja. - A
dszámára már nincs érték, ezért az URL-cím létrehozása meghiúsul. - Az URL-cím létrehozásához meg kell adni a kívánt értékeket
césd.
Előfordulhat, hogy az alapértelmezett útvonallal {controller}/{action}/{id?}kapcsolatos problémát tapasztalja. Ez a probléma a gyakorlatban ritkán fordul elő, mert Url.Action mindig explicit módon meghatározza a controller és action értéket.
Az Url.Action számos túlterhelése elfogad egy útvonali értékek objektumot, hogy más útvonalparaméterek értékeit adja meg, mint controller és action. A rendszer gyakran használja az útvonalérték-objektumot id. Például: Url.Action("Buy", "Products", new { id = 17 }). Az útvonalértékek objektuma:
- Konvenció szerint általában névtelen típusú objektum.
- Lehet egy
IDictionary<>vagy POCO).
Az útvonalparamétereknek nem megfelelő további útvonalértékek a lekérdezési sztringbe kerülnek.
public IActionResult Index()
{
var url = Url.Action("Buy", "Products", new { id = 17, color = "red" });
return Content(url!);
}
Az előző kód generálja a következőt /Products/Buy/17?color=red: .
A következő kód abszolút URL-címet hoz létre:
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!);
}
Abszolút URL-cím létrehozásához használja az alábbiak egyikét:
- Egy túlterhelés, amely elfogadja a
protocol. Például az előző kód. - LinkGenerator.GetUriByAction, amely alapértelmezés szerint abszolút URI-kat hoz létre.
URL-címek létrehozása útvonal szerint
Az előző kód bemutatta egy URL-cím létrehozását a vezérlő és a művelet név megadásával.
IUrlHelper Az Url.RouteUrl metóduscsaládot is tartalmazza. Ezek a metódusok hasonlóak az Url.Action metódushoz, de nem másolja az aktuális értékeket a action és controller az útvonalértékekhez. A leggyakoribb használat a Url.RouteUrl a következő:
- Megadja az URL-cím létrehozásához tartozó útvonalnevet.
- Általában nem ad meg vezérlőt vagy műveletnevet.
public class UrlGeneration2Controller : Controller
{
[HttpGet("")]
public IActionResult Source()
{
var url = Url.RouteUrl("Destination_Route");
return ControllerContext.MyDisplayRouteInfo("", $" URL = {url}");
}
[HttpGet("custom/url/to/destination2", Name = "Destination_Route")]
public IActionResult Destination()
{
return ControllerContext.MyDisplayRouteInfo();
}
A következő Razor fájl létrehoz egy HTML-hivatkozást a Destination_Routekövetkezőre:
<h1>Test Links</h1>
<ul>
<li><a href="@Url.RouteUrl("Destination_Route")">Test Destination_Route</a></li>
</ul>
URL-címek létrehozása HTML-ben és Razor
IHtmlHelper a HtmlHelper módszereket, a Html.BeginForm és a Html.ActionLink használja a megfelelő <form> és <a> elemek generálásához. Ezek a metódusok az URL.Action metódussal hoznak létre URL-címet, és hasonló argumentumokat fogadnak el. Az Url.RouteUrl társai HtmlHelper és Html.BeginRouteForm, amelyek hasonló funkciókkal rendelkeznek.
A TagHelpers URL-címeket hoz létre a form TagHelper és a <a> TagHelper használatával. Mindkét megvalósítás során IUrlHelper-et használnak. További információkért tekintse meg az űrlapok címkesegítőit .
A belső nézetekben a IUrlHelper tulajdonság révén érhető el minden olyan ad-hoc URL-generálás, amelyre a fentiek nem vonatkoznak.
URL-generálás a műveleteredményekben
Az előző példák bemutatták a IUrlHelper használatát a vezérlőben. A vezérlők leggyakoribb használata egy URL-cím létrehozása egy művelet eredményének részeként.
Az ControllerBase és Controller az alaposztályok kényelmi módszereket biztosítanak egy másik műveletre hivatkozó műveleti eredményekhez. Az egyik jellemző használat az átirányítás a felhasználói bemenet elfogadása után:
[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);
}
Az olyan akció-eredmény gyári metódusok, mint a RedirectToAction és a CreatedAtAction, hasonló mintát követnek, mint a IUrlHelper metódusok.
Speciális eset dedikált hagyományos útvonalakhoz
A hagyományos útválasztás egy speciális útvonaldefiníciót, az úgynevezett dedikált hagyományos útvonalat használhat. A következő példában a névvel ellátott blog útvonal egy dedikált hagyományos útvonal:
app.MapControllerRoute(name: "blog",
pattern: "blog/{*article}",
defaults: new { controller = "Blog", action = "Article" });
app.MapControllerRoute(name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Az előző útvonaldefiníciók Url.Action("Index", "Home") használatával hozza létre az URL-címet / az default útvonal használatával, de miért? Előfordulhat, hogy az útvonalértékek { controller = Home, action = Index } elegendőek egy URL generálásához blog használatával, és az eredmény az lesz /blog?action=Index&controller=Home.
A dedikált hagyományos útvonalak az alapértelmezett értékek speciális viselkedésére támaszkodnak, amelyek nem rendelkeznek megfelelő útvonalparaméterrel, amely megakadályozza, hogy az útvonal túlságosan mohó legyen az URL-cím generálása során. Ebben az esetben az alapértelmezett értékek a következők { controller = Blog, action = Article }, és sem controller sem action nem jelenik meg útvonalparaméterként. Ha az útválasztás URL-címet generál, a megadott értékeknek meg kell egyeznie az alapértelmezett értékekkel. Az URL-cím létrehozása blog sikertelen, mert az értékek { controller = Home, action = Index } nem egyeznek { controller = Blog, action = Article }. Az útválasztás ezután visszatér default próbálkozásra, ami sikerrel jár.
Areas
A területek egy MVC-funkció, amellyel a kapcsolódó funkciók külön csoportba rendezhetőek:
- Útválasztási névtér vezérlőműveletekhez.
- A nézetek mappastruktúrája.
A területek használata lehetővé teszi, hogy az alkalmazások több, azonos nevű vezérlővel rendelkezzenek, feltéve, hogy különböző területekkel rendelkeznek. A területek használata hierarchiát hoz létre az útválasztás céljából egy másik útvonalparaméter hozzáadásával a area és controller elemekhez. Ez a szakasz azt ismerteti, hogyan lép kölcsönhatásba az útválasztás a területekkel. Részletekért lásd a Területek című témakört, ahol a területek nézetekkel való használatáról olvashat.
Az alábbi példa úgy konfigurálja az MVC-t, hogy az alapértelmezett hagyományos útvonalat és egy areaarea elnevezett Blogútvonalat használja:
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();
Az előző kódban a MapAreaControllerRoute meghívásával létrehozzák a "blog_route". A második paraméter a "Blog"terület neve.
Ha egy URL-útvonalhoz hasonlót /Manage/Users/AddUser illeszt, az "blog_route" útvonal létrehozza az útvonalértékeket { area = Blog, controller = Users, action = AddUser }. Az area útvonal értékét a rendszer a következő alapértelmezett értékével areahozza létre: . A létrehozott MapAreaControllerRoute útvonal egyenértékű a következővel:
app.MapControllerRoute("blog_route", "Manage/{controller}/{action}/{id?}",
defaults: new { area = "Blog" }, constraints: new { area = "Blog" });
app.MapControllerRoute("default_route", "{controller}/{action}/{id?}");
MapAreaControllerRoute létrehoz egy útvonalat, amely az alapértelmezett értéket és a megadott területnév használatára vonatkozó area korlátozást is használja, ebben az esetben Blog. Az alapértelmezett érték biztosítja, hogy az útvonal mindig { area = Blog, ... }-t hoz létre, a kényszer megköveteli a { area = Blog, ... } értéket az URL generálásához.
A hagyományos útválasztás sorrendfüggő. Általánosságban elmondható, hogy a területekkel rendelkező útvonalakat korábban kell elhelyezni, mivel ezek pontosabbak, mint a terület nélküli útvonalak.
Az előző példában szereplő útvonalértékek { area = Blog, controller = Users, action = AddUser } a következő műveletnek felelnek meg:
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}");
}
}
}
A [Terület] attribútum az, amely egy vezérlőt egy terület részeként jelöl. Ez a vezérlő a Blog környéken található. Az attribútummal nem rendelkező [Area] vezérlők nem tagjai egyik területnek sem, és nem egyeznek meg, ha az útvonal értékét útválasztás area biztosítja. Az alábbi példában csak az első vezérlő felelhet meg az útvonalértéknek { 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}");
}
}
}
Az egyes vezérlők névtere itt látható a teljesség érdekében. Ha az előző vezérlők ugyanazt a névteret használták, fordítóhiba jön létre. Az osztálynévterek nincsenek hatással az MVC útválasztására.
Az első két vezérlő a területek tagjai, és csak akkor egyeznek meg, ha a megfelelő terület nevét az area útvonal értéke adja meg. A harmadik vezérlő nem tartozik egyetlen területhez sem, és csak akkor felel meg, ha az útválasztás nem ad meg értéket a area számára.
A nincs érték egyezés szempontjából az area érték hiánya ugyanaz, mintha a area érték null vagy üres sztring lenne.
Ha egy műveletet egy területen hajt végre, az útvonal értéke areakörnyezeti értékként érhető el az URL-generáláshoz használandó útválasztáshoz. Ez azt jelenti, hogy alapértelmezés szerint a területek ragadósak az URL-generáláshoz, ahogy azt az alábbi minta is mutatja.
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);
}
}
}
Az alábbi kód egy URL-címet hoz létre a következő címre /Zebra/Users/AddUser:
public class HomeController : Controller
{
public IActionResult About()
{
var url = Url.Action("AddUser", "Users", new { Area = "Zebra" });
return Content($"URL: {url}");
}
Műveletdefiníció
A vezérlő nyilvános metódusai a NonAction attribútummal rendelkezők kivételével műveletek.
Mintakód
- MyDisplayRouteInfo a Rick.Docs.Samples.RouteInfo NuGet-csomag biztosítja, és megjeleníti az útvonaladatokat.
- Mintakód megtekintése vagy letöltése (hogyan töltsd le)
Hibakeresési diagnosztika
A részletes útválasztási diagnosztikai kimenethez állítsa be a Logging:LogLevel:Microsoft értékét Debug-re. A fejlesztési környezetben állítsa be a naplószintet: appsettings.Development.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Debug",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}
ASP.NET Core vezérlők az Útválasztás köztes szoftvert használják, hogy összepárosítsák a bejövő kérések URL-címeit, és műveletekhez rendeljék őket. Útvonalsablonok:
- Az indítási kódban vagy attribútumokban vannak definiálva.
- Írja le, hogyan illeszkednek az URL-útvonalak a műveletekhez.
- A hivatkozások URL-címeinek létrehozására szolgál. A létrehozott hivatkozások általában válaszokban jelennek meg.
A műveletek hagyományosan irányítottak vagy attribútumalapúak. Ha egy útvonalat helyez el a vezérlőn vagy a műveleten , az attribútumalapúvá válik. További információt a Vegyes útválasztás című témakörben talál.
Ez a dokumentum:
- Az MVC és az útválasztás közötti interakciókat ismerteti:
- Hogyan használják a tipikus MVC-alkalmazások az útválasztási funkciókat.
- Mindkettőt lefedi:
- A hagyományos útválasztást általában vezérlőkkel és nézetekkel használják.
- API-kkal használt REST. Ha elsősorban az API-k útválasztása REST érdekli, ugorjon az API-k attribútum-útválasztási szakaszáraREST.
- A speciális útválasztási részletekért tekintse meg az Útválasztás című témakört.
- A ASP.NET Core 3.0-ban hozzáadott alapértelmezett útválasztási rendszerre, az úgynevezett végpont-útválasztásra hivatkozik. Kompatibilitási okokból az útválasztás előző verziójával rendelkező vezérlőket is használhat. Útmutatásért tekintse meg a 2.2-3.0 migrálási útmutatót . Tekintse meg a dokumentum 2.2-es verzióját a korábbi útválasztási rendszerrel kapcsolatos referenciaanyagokért.
Hagyományos útvonal beállítása
Startup.Configure a hagyományos útválasztás használatakor általában a következőhöz hasonló kóddal rendelkezik:
app.UseEndpoints(endpoints =>
{
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
});
A UseEndpoints hívásakor a MapControllerRoute egyetlen útvonalat hoz létre. Az egyetlen útvonal neve default útvonal. A vezérlőkkel és nézetekkel rendelkező alkalmazások többsége az default útvonalhoz hasonló útvonalsablont használ.
REST Az API-knak attribútum-útválasztást kell használniuk.
Az útvonalsablon "{controller=Home}/{action=Index}/{id?}":
Megfelel egy URL-címnek, például:
/Products/Details/5Kinyeri az útvonal értékeit
{ controller = Products, action = Details, id = 5 }az elérési út tokenizálásával. Az útvonalértékek kinyerése akkor eredményez egyezést, ha az alkalmazásnak van egyProductsControllernevű vezérlője és egyDetailsnevű művelete.public class ProductsController : Controller { public IActionResult Details(int id) { return ControllerContext.MyDisplayRouteInfo(id); } }MyDisplayRouteInfo a Rick.Docs.Samples.RouteInfo NuGet-csomag biztosítja, és megjeleníti az útvonaladatokat.
/Products/Details/5modell a(z)id = 5értéket használja a(z)idparaméter5értékre való kötéséhez. További részletekért tekintse meg a modellkötést .{controller=Home}aHomealapértelmezettkéntcontrollerdefiniálja.{action=Index}aIndexalapértelmezettkéntactiondefiniálja.A
?karakter a{id?}területen opcionálisként határozza meg aid-t.Az alapértelmezett és az opcionális útvonalparamétereknek nem kell szerepelnie az egyezés URL-címében. Az útvonalsablon szintaxisának részletes leírását az útvonalsablon-referencia című témakörben találja.
Megfelel az URL-cím elérési útvonalának
/.Létrehozza az útvonalértékeket
{ controller = Home, action = Index }.
A controller és action alapértelmezett értékeket használnak.
id nem hoz létre értéket, mivel az URL-elérési útnak nincs megfelelő szegmense.
/ csak akkor egyezik, ha létezik egy HomeController és Index művelet:
public class HomeController : Controller
{
public IActionResult Index() { ... }
}
Az előző vezérlődefiníció és útvonalsablon használatával a művelet a HomeController.Index következő URL-útvonalakon fut:
/Home/Index/17/Home/Index/Home/
Az URL-elérési út / az útvonalsablon alapértelmezett Home vezérlőit és Index műveleteit használja. Az URL-elérési út /Home az útvonalsablon alapértelmezett Index műveletét használja.
A kényelmi módszer MapDefaultControllerRoute:
endpoints.MapDefaultControllerRoute();
Replaces:
endpoints.MapControllerRoute("default", "{controller=Home}/{action=Index}/{id?}");
Important
Az útválasztás a UseRouting, MapControllerRoute és MapAreaControllerRoute köztes szoftver használatával konfigurálható. Vezérlők használata:
- Hívja meg MapControllers belül
UseEndpointsaz attribútumok alapján irányított vezérlők leképezéséhez. - Hívja meg a MapControllerRoute vagy MapAreaControllerRoute, hogy leképezze mind a hagyományosan irányított vezérlőket, mind az attribútumalapú vezérlőket.
Hagyományos útválasztás
A hagyományos útválasztás vezérlőkkel és nézetekkel használható. Az default útvonal:
endpoints.MapControllerRoute(
name: "default",
pattern: "{controller=Home}/{action=Index}/{id?}");
Az előző példa egy hagyományos útvonalra mutat. Ezt hagyományos útválasztásnak nevezik, mert konvenciót hoz létre az URL-útvonalakhoz:
- Az első útvonal szegmens
{controller=Home}a vezérlő nevére lesz leképezve. - A második szegmens a
{action=Index}művelet nevére képeződik le. - A harmadik szegmens
{id?}opcionálisid-ként használatos. A?a{id?}tegében választhatóvá teszi. Aida modellentitásra való leképezéshez használható.
Ezzel az default útvonallal az URL-cím útvonala:
-
/Products/Listleképez aProductsController.Listművelethez. -
/Blog/Article/17leképezBlogController.Articleés általában a modell leköti aidparamétert a 17-es értékhez.
Ez a leképezés:
- Csak a vezérlőn és a műveletnevekenalapul.
- Nem névtereken, forrásfájl-helyeken vagy metódusparamétereken alapul.
A hagyományos útválasztás alapértelmezett útvonallal való használata lehetővé teszi az alkalmazás létrehozását anélkül, hogy minden művelethez új URL-mintát kellene létrehoznia. CRUD stílusműveleteket tartalmazó alkalmazás esetén, amely konzisztenciával rendelkezik a vezérlők URL-címeivel kapcsolatban:
- Segít leegyszerűsíteni a kódot.
- A felhasználói felület kiszámíthatóbbá válik.
Warning
Az id előző kódban szereplő kódot az útvonalsablon nem kötelezőként határozza meg. A műveletek az URL-cím részeként megadott opcionális azonosító nélkül is végrehajthatók. Általában, ha id kihagyva van az URL-ből:
-
idmodellkötés szerint van beállítva0. - Az adatbázisban a
id == 0nem egyezik egyetlen entitással sem.
Az attribútum-útválasztás részletes vezérlést biztosít, amely lehetővé teszi, hogy az azonosító bizonyos műveletekhez szükséges legyen, nem pedig mások számára. A konvenció szerint a dokumentáció tartalmazza az olyan választható paramétereket, mint a id, amikor azok valószínűleg a helyes használat során jelennek meg.
A legtöbb alkalmazásnak alapszintű és leíró útválasztási sémát kell választania, hogy az URL-címek olvashatók és értelmezhetők legyenek. Az alapértelmezett hagyományos útvonal {controller=Home}/{action=Index}/{id?}:
- Alapszintű és leíró útválasztási sémát támogat.
- Hasznos kiindulópont a felhasználói felületalapú alkalmazásokhoz.
- Ez az egyetlen útválasztási sablon, amely sok webes felhasználói felületi alkalmazáshoz szükséges. A nagyobb webes felhasználói felületi alkalmazások esetében gyakran csak a Területeket használó másik útvonalra van szükség.
MapControllerRoute és MapAreaRoute :
- Automatikusan rendeljen hozzá sorrendi értéket a végpontokhoz a meghívás sorrendje alapján.
Végpont-útválasztás a ASP.NET Core 3.0-s vagy újabb verziójában:
- Nincs fogalma az útvonalakról.
- Nem biztosít rendelési garanciákat a bővíthetőség végrehajtásához, az összes végpont egyszerre lesz feldolgozva.
Engedélyezze a naplózást, hogy megtekintse, hogyan illeszkednek a beépített útválasztási implementációk, mint például Route, a kérésekhez.
Az attribútumok útválasztását a dokumentum későbbi részében ismertetik.
Több hagyományos útvonal
Több hagyományos útvonal is hozzáadható, UseEndpoints ha további hívásokat ad hozzá.MapControllerRouteMapAreaControllerRoute Ez lehetővé teszi több konvenció meghatározását, vagy egy adott művelethez dedikált hagyományos útvonalak hozzáadását, például:
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?}");
});
Az blog előző kódban szereplő útvonal egy dedikált hagyományos útvonal. Ez az úgynevezett dedikált hagyományos útvonal, mert:
- Hagyományos útválasztást használ.
- Egy adott műveletnek van szentelve.
Azért, mert a controller és action nem jelenik meg a "blog/{*article}" útvonalsablonban paraméterekként:
- Csak az alapértelmezett értékekkel
{ controller = "Blog", action = "Article" }rendelkezhetnek. - Ez az útvonal mindig a művelethez lesz megfeleltetve
BlogController.Article.
/Blog, /Blog/Articleés /Blog/{any-string} ezek az egyetlen URL-elérési utak, amelyek megfelelnek a blog útvonalának.
Az előző példa:
-
blogaz útvonal nagyobb prioritással rendelkezik az egyezésekhez, mint azdefaultútvonal, mert az elsőként van hozzáadva. - Példa a Slug-stílus útválasztására, ahol általában egy cikknév szerepel az URL-cím részeként.
Warning
A ASP.NET Core 3.0-s vagy újabb verziójában az útválasztás nem:
- Definiáljon egy útvonalnak nevezett fogalmat.
UseRoutingA köztesszoftver-folyamatnak megfelelő útvonalat ad hozzá. AUseRoutingköztes szoftver megvizsgálja az alkalmazásban definiált végpontokat, és a kérés alapján kiválasztja a legjobb végpontegyezést. - Biztosítson garanciákat a bővíthetőség végrehajtási sorrendjére, például IRouteConstraint vagy IActionConstraint.
Az útválasztással kapcsolatos referenciaanyagokért tekintse meg az Útválasztás című témakört.
Hagyományos útválasztási sorrend
A hagyományos útválasztás csak az alkalmazás által meghatározott művelet és vezérlő kombinációjával egyezik meg. Ez leegyszerűsíti azokat az eseteket, amikor a hagyományos útvonalak átfedésben vannak.
Útvonalak hozzáadása a MapControllerRoute, MapDefaultControllerRoute és MapAreaControllerRoute használatával automatikusan rendelési értéket ad a végpontokhoz a meghívásuk sorrendje alapján. Az útvonal, amely korábban jelenik meg, egyezései magasabb prioritással rendelkeznek. A hagyományos útválasztás sorrendfüggő. Általánosságban elmondható, hogy a területekkel rendelkező útvonalakat korábban kell elhelyezni, mivel ezek pontosabbak, mint a terület nélküli útvonalak.
Az olyan hagyományos útvonalak, mint például {*article} a catch-all útvonalparaméterek, túl mohóvá tehetik az útvonalakat, ami azt jelenti, hogy megegyezik a más útvonalakkal egyeztetni kívánt URL-címekkel. A kapzsi útvonalakat később helyezze el az útvonaltáblában, hogy megakadályozza a kapzsi egyezéseket.
Warning
A catch-all paraméter helytelenül felelhet meg az útvonalaknak egy útválasztási hiba miatt. A hiba által érintett alkalmazások jellemzői a következők:
- Egy mindent megragadó útvonal, például:
{**slug}" - A catch-all útvonal nem egyezik meg azokkal a kérésekkel, amelyeket meg kellene egyeznie.
- Ha eltávolít más útvonalakat, az összeset megfogó útvonal elkezd működni.
Tekintse meg a GitHub 18677 és 16579 hibáit a példaesetekért, amelyekben ez a hiba felmerül.
A hiba jóváhagyási javítása a .NET Core 3.1.301-ben vagy újabb SDK-ban található. A következő kód beállít egy belső kapcsolót, amely megoldja ezt a hibát:
public static void Main(string[] args)
{
AppContext.SetSwitch("Microsoft.AspNetCore.Routing.UseCorrectCatchAllBehavior",
true);
CreateHostBuilder(args).Build().Run();
}
// Remaining code removed for brevity.
Nem egyértelmű műveletek feloldása
Ha két végpont egyezik az útválasztással, az útválasztásnak az alábbiak egyikét kell elvégeznie:
- Válassza ki a legjobb jelöltet.
- Kivételt kell kivenni.
Például:
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);
}
}
}
Az előző vezérlő két, egyező műveletet határoz meg:
- Az URL-cím elérési útja
/Products33/Edit/17 - Útvonaladatok
{ controller = Products33, action = Edit, id = 17 }.
Ez az MVC-vezérlők tipikus mintája:
-
Edit(int)egy termék szerkesztéséhez használandó űrlapot jelenít meg. -
Edit(int, Product)feldolgozza a közzétett űrlapot.
Az útvonal helyes kijelölése:
-
Edit(int, Product)akkor van kiválasztva, ha a kérés HTTPPOST. -
Edit(int)akkor van kiválasztva, ha a HTTP-ige bármi más.Edit(int)-t általábanGEThasználatával hívjuk meg.
A HttpPostAttribute, [HttpPost]az útválasztáshoz van megadva, hogy a kérés HTTP-metódusa alapján válasszon. Az HttpPostAttribute jobban megteszi Edit(int, Product)-t megfelelőbbé, mint a Edit(int).
Fontos megérteni az olyan attribútumok szerepét, mint HttpPostAttributea . Más HTTP-parancsokhoz hasonló attribútumok vannak definiálva. A hagyományos útválasztásban gyakran előfordul, hogy a műveletek ugyanazt a műveletnevet használják, amikor egy megjelenítési űrlap részei, és űrlap-munkafolyamatot küldenek. Lásd például a két szerkesztési művelet módszerét.
Ha az útválasztás nem tudja kiválasztani a legjobb jelöltet, AmbiguousMatchException a több egyező végpontot listázó üzenet megjelenik.
Hagyományos útvonalnevek
A "blog" és "default" karakterláncok az alábbi példákban a hagyományos útvonalnevek:
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?}");
});
Az útvonalnevek logikai nevet adnak az útvonalnak. A névvel ellátott útvonal használható AZ URL-cím létrehozásához. A névvel ellátott útvonalak használata egyszerűbbé teszi az URL-címek létrehozását, ha az útvonalak sorrendje megnehezítheti az URL-címek létrehozását. Az útvonalneveknek egyedi alkalmazásszintűnek kell lenniük.
Útvonalnevek:
- Nincs hatással az URL-címek egyeztetésére vagy a kérések kezelésére.
- Csak AZ URL-cím generálásához használhatók.
Az útvonalnév fogalma az útválasztásban IEndpointNameMetadata néven jelenik meg. Az útvonalnév és a végpont neve:
- Felcserélhetők.
- Hogy melyik kerül felhasználásra a dokumentációban és a kódban, az a leírt API-tól függ.
API-k attribútum alapú útválasztása REST
REST Az API-knak attribútumalapú útválasztással kell modelleznie az alkalmazás funkcióit olyan erőforrások készleteként, ahol a műveleteket HTTP-parancsok jelölik.
Az attribútum-útválasztás egy sor attribútum segítségével közvetlenül hozzárendeli a műveleteket az útvonal sablonokhoz. A következő StartUp.Configure kód jellemző egy REST API-ra, és a következő példában kerül felhasználásra:
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();
});
}
Az előző kódban az MapControllers hívódik meg a UseEndpoints belsejében az attribútumalapú vezérlők leképezéséhez.
Az alábbi példában:
-
HomeControlleregyezik az alapértelmezett hagyományos útvonalhoz{controller=Home}/{action=Index}/{id?}hasonló URL-címekkel.
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);
}
}
A HomeController.Index művelet az URL-címek //Homebármelyikén fut, /Home/Indexvagy /Home/Index/3.
Ez a példa kiemeli az attribútum-útválasztás és a hagyományos útválasztás közötti kulcsfontosságú programozási különbséget. Az attribútum-útválasztáshoz több bemenetre van szükség az útvonal megadásához. A hagyományos alapértelmezett útvonal tömörebben kezeli az útvonalakat. Az attribútumalapú útválasztás azonban lehetővé teszi és megköveteli annak pontos szabályozását, hogy mely útvonalsablonok vonatkozzanak az egyes műveletekre.
Attribútum alapú útválasztás esetén a vezérlő és az akciónevek nem játszanak szerepet az akció egyeztetésében, kivéve, ha kivonatcsere történik. Az alábbi példa megegyezik az előző példával megegyező URL-címekkel:
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);
}
}
Az alábbi kód token helyettesítést alkalmaz a action és a controller esetében:
public class HomeController : Controller
{
[Route("")]
[Route("Home")]
[Route("[controller]/[action]")]
public IActionResult Index()
{
return ControllerContext.MyDisplayRouteInfo();
}
[Route("[controller]/[action]")]
public IActionResult About()
{
return ControllerContext.MyDisplayRouteInfo();
}
}
A vezérlőre a következő kód vonatkozik [Route("[controller]/[action]")] :
[Route("[controller]/[action]")]
public class HomeController : Controller
{
[Route("~/")]
[Route("/Home")]
[Route("~/Home/Index")]
public IActionResult Index()
{
return ControllerContext.MyDisplayRouteInfo();
}
public IActionResult About()
{
return ControllerContext.MyDisplayRouteInfo();
}
}
Az előző kódban a Index metódussablonok előtt el kell helyezni a / vagy ~/ útvonalsablonokat. Olyan műveletre alkalmazott útvonalsablonok, amelyek a vezérlőre alkalmazott útvonalsablonokkal kezdődnek / vagy ~/ nem kombinálódnak.
Az útvonalsablon kiválasztásával kapcsolatos információkért tekintse meg az Útvonalsablon elsőbbsége című témakört.
Fenntartott útválasztási nevek
A következő kulcsszavak fenntartott útvonalparaméternevek a vezérlők vagy Razor lapok használatakor:
actionareacontrollerhandlerpage
Az attribútumalapú útválasztással rendelkező útvonalparaméter használata page gyakori hiba. Ez inkonzisztens és zavaró viselkedést eredményez az URL-generálással.
public class MyDemo2Controller : Controller
{
[Route("/articles/{page}")]
public IActionResult ListArticles(int page)
{
return ControllerContext.MyDisplayRouteInfo(page);
}
}
Az URL-generáció a speciális paraméterneveket használja annak megállapítására, hogy egy URL-létrehozási művelet egy lapra vagy egy Razor vezérlőre hivatkozik-e.
A következő kulcsszavak egy Razor nézet vagy egy Razor oldal kontextusában vannak fenntartva.
pageusingnamespaceinjectsectioninheritsmodeladdTagHelperremoveTagHelper
Ezeket a kulcsszavakat nem szabad hivatkozásgenerációkhoz, modellhez kötött paraméterekhez vagy legfelső szintű tulajdonságokhoz használni.
HTTP-parancssablonok
ASP.NET Core a következő HTTP-igesablonokkal rendelkezik:
Útvonalsablonok
ASP.NET Core a következő útvonalsablonokkal rendelkezik:
- Az összes HTTP-igesablon útvonalsablon.
- [Route]
Attribútum-útválasztás Http ige attribútumokkal
Vegye figyelembe a következő vezérlőt:
[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);
}
}
Az előző kódban:
- Minden művelet tartalmazza az
[HttpGet]attribútumot, amely csak a HTTP GET-kérelmeknek való megfelelést korlátozza. - A
GetProductművelet tartalmazza a"{id}"sablont, ezértidhozzá van fűzve a"api/[controller]"sablonhoz a vezérlőn. A metódussablon a következő"api/[controller]/{id}": . Ezért ez a művelet csak az űrlap/api/test2/xyzGET kéréseinek felel meg,/api/test2/123,/api/test2/{any string}, stb.[HttpGet("{id}")] // GET /api/test2/xyz public IActionResult GetProduct(string id) { return ControllerContext.MyDisplayRouteInfo(id); } - A
GetIntProductművelet tartalmazza a sablont"int/{id:int}". A:intsablon része azidútvonalértékeket egész számmá konvertálható sztringekre korlátozza. GET kérés a következőhöz/api/test2/int/abc:- Nem egyezik ezzel a művelettel.
-
404 Nem található hibát ad vissza.
[HttpGet("int/{id:int}")] // GET /api/test2/int/3 public IActionResult GetIntProduct(int id) { return ControllerContext.MyDisplayRouteInfo(id); }
- A
GetInt2Productművelet tartalmazza a sablonban{id}, de nem korlátozzaidazokra az értékekre, amelyeket egész számmá lehet konvertálni. GET kérés a következőhöz/api/test2/int2/abc:- Megfelel ennek az útvonalnak.
- A modellkötés nem konvertálható
abcegész számmá. Aidmetódus paramétere egész szám. -
400-os hibás kérést ad vissza, mert a modellkötést nem sikerült egész számmá alakítani
abc.[HttpGet("int2/{id}")] // GET /api/test2/int2/3 public IActionResult GetInt2Product(int id) { return ControllerContext.MyDisplayRouteInfo(id); }
Az attribútum-útválasztás olyan attribútumokat használhat, mint az HttpMethodAttribute, HttpPostAttribute, HttpPutAttribute és HttpDeleteAttribute. Az összes HTTP-igeattribútum elfogad egy útvonalsablont. Az alábbi példa két olyan műveletet mutat be, amelyek azonos útvonalsablonnak felelnek meg:
[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);
}
}
Az URL-elérési út /products3használata:
- A
MyProductsController.ListProductsművelet akkor fut, ha a HTTP-igeGET. - A
MyProductsController.CreateProductművelet akkor fut, ha a HTTP-igePOST.
API-k készítésekor ritka, hogy egy metóduson használnia kell REST, mert a metódus minden HTTP-metódust elfogad. Érdemes a pontosabb HTTP használati attribútumot használni, hogy egyértelműen jelezze, mit támogat az API. REST Az API-k ügyfeleinek várhatóan tudniuk kell, hogy milyen elérési utak és HTTP-igék vannak leképezve adott logikai műveletekre.
REST Az API-knak attribútumalapú útválasztással kell modelleznie az alkalmazás funkcióit olyan erőforrások készleteként, ahol a műveleteket HTTP-parancsok jelölik. Ez azt jelenti, hogy számos művelet, például a GET és a POST ugyanazon a logikai erőforráson ugyanazt az URL-címet használja. Az attribútum-útválasztás olyan szintű vezérlést biztosít, amely az API nyilvános végpontelrendezésének gondos tervezéséhez szükséges.
Mivel az attribútumútvonalak egy adott műveletre vonatkoznak, az útvonalsablon definíciójának részeként könnyen megkövetelhetőek a paraméterek. A következő példában id az URL-elérési út részeként szükséges:
[ApiController]
public class Products2ApiController : ControllerBase
{
[HttpGet("/products2/{id}", Name = "Products_List")]
public IActionResult GetProduct(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
}
A Products2ApiController.GetProduct(int) művelet:
- Olyan URL-címmel futtatható, mint
/products2/3 - Az URL-cím elérési útvonalával
/products2nincs futtatva.
A [Felhasználás] attribútum lehetővé teszi, hogy egy művelet korlátozza a támogatott kérelem tartalomtípusait. További információ: Támogatott kérések tartalomtípusainak definiálása az Consumes attribútummal.
Az útvonalsablonok és a kapcsolódó beállítások teljes leírását az Útválasztás című témakörben talál.
További információ: [ApiController]ApiController attribútum.
Útvonal neve
Az alábbi kód a következő útvonalnevet Products_Listhatározza meg:
[ApiController]
public class Products2ApiController : ControllerBase
{
[HttpGet("/products2/{id}", Name = "Products_List")]
public IActionResult GetProduct(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
}
Az útvonalnevek egy adott útvonalon alapuló URL-cím létrehozásához használhatók. Útvonalnevek:
- Nincs hatással az útválasztás URL-címmegfeleltetési viselkedésére.
- Csak URL-címek létrehozására használatos.
Az útvonalneveknek alkalmazásszintű egyedinek kell lenniük.
Határozd szembe az előző kódot a hagyományos alapértelmezett útvonallal, amely a id paramétert opcionálisként ({id?}) határozza meg. Az API-k pontos meghatározásának lehetősége előnyökkel jár, mint például az, hogy a /products és /products/5 különböző műveletekhez való továbbítását lehetővé teszi.
Attribútumútvonalak kombinálása
Az attribútum-útválasztás kevésbé ismétlődővé tétele érdekében a vezérlő útvonalattribútumait a rendszer az egyes műveletek útvonalattribútumaival kombinálja. A vezérlőben definiált útvonalsablonok előre fel vannak függve a műveletek útvonalsablonjaira. Ha egy útvonalattribútumot helyez el a vezérlőn, a vezérlőben lévő összes művelet attribútumalapú útválasztást használ.
[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);
}
}
Az előző példában:
- Az URL-cím megegyezhet
/productsProductsApi.ListProducts - Az URL-cím megegyezhet
/products/5ProductsApi.GetProduct(int).
Mindkét művelet csak a HTTP-nek GET felel meg, mert az [HttpGet] attribútummal vannak megjelölve.
Olyan műveletre alkalmazott útvonalsablonok, amelyek a vezérlőre alkalmazott útvonalsablonokkal kezdődnek / vagy ~/ nem kombinálódnak. Az alábbi példa az alapértelmezett útvonalhoz hasonló URL-útvonalakat tartalmaz.
[Route("Home")]
public class HomeController : Controller
{
[Route("")]
[Route("Index")]
[Route("/")]
public IActionResult Index()
{
return ControllerContext.MyDisplayRouteInfo();
}
[Route("About")]
public IActionResult About()
{
return ControllerContext.MyDisplayRouteInfo();
}
}
Az alábbi táblázat az [Route] előző kód attribútumait ismerteti:
| Attribute | Kombinálva [Route("Home")]-vel |
Útvonalsablon definiálása |
|---|---|---|
[Route("")] |
Yes | "Home" |
[Route("Index")] |
Yes | "Home/Index" |
[Route("/")] |
No | "" |
[Route("About")] |
Yes | "Home/About" |
Attribútumútvonal sorrendje
Az útválasztás létrehoz egy fát, és az összes végpontot egyidejűleg összekapcsolja.
- Az útvonalbejegyzések úgy viselkednek, mintha ideális sorrendbe helyezték volna.
- A legspecifikusabb útvonalak az általánosabb útvonalak előtt hajthatók végre.
Például egy attribútumútvonal blog/search/{topic} pontosabb, mint egy attribútumútvonal, például blog/{*article}. Az blog/search/{topic} útvonal alapértelmezés szerint magasabb prioritással rendelkezik, mert pontosabb. A hagyományos útválasztás használatával a fejlesztő felelős az útvonalak kívánt sorrendbe helyezéséért.
Az attribútumútvonalak konfigurálhatják a rendelést a Order tulajdonság használatával. Az összes keretrendszer által biztosított útvonalattribútum tartalmazza . Az útvonalak feldolgozása a Order tulajdonság növekvő sorrendje szerint történik. Az alapértelmezett sorrend a következő 0: . Az útvonal beállítása a Order = -1 használatával azok előtt történik meg, amelyek nem rendelkeznek sorrenddel. Az útvonal beállítása a(z) Order = 1 használatával az alapértelmezett útvonalrendezés után történik.
Kerülje a függést . Ha egy alkalmazás URL-címe explicit rendelési értékeket igényel a helyes útválasztáshoz, az valószínűleg az ügyfelek számára is zavaró. Az attribútum-útválasztás általában a megfelelő útvonalat választja ki URL-egyezéssel. Ha az URL-létrehozáshoz használt alapértelmezett sorrend nem működik, az útvonalnév felülbírálásként való használata általában egyszerűbb, mint a Order tulajdonság alkalmazása.
Vegye figyelembe az alábbi két vezérlőt, amelyek mindkettő az útvonalegyezést /homehatározzák meg:
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);
}
}
Az előző kóddal való kérés /home a következőhöz hasonló kivételt eredményez:
AmbiguousMatchException: The request matched multiple endpoints. Matches:
WebMvcRouting.Controllers.HomeController.Index
WebMvcRouting.Controllers.MyDemoController.MyIndex
Az útvonalattribútumok egyikének hozzáadása Order feloldja a kétértelműséget:
[Route("")]
[Route("Home", Order = 2)]
[Route("Home/MyIndex")]
public IActionResult MyIndex()
{
return ControllerContext.MyDisplayRouteInfo();
}
Az előző kóddal /home futtatja a végpontot HomeController.Index . Az MyDemoController.MyIndex eléréséhez kérje /home/MyIndex.
Note:
- Az előző kód egy példa vagy rossz útválasztási terv. A
Ordera tulajdonság szemléltetésére szolgált. - A
Ordertulajdonság csak a kétértelműséget oldja fel, a sablon nem feleltethető meg. Jobb lenne eltávolítani a sablont[Route("Home")].
Lásd aRazor Oldalak útvonal- és alkalmazáskonvencióit: Útvonal sorrend a Pages alkalmazással Razor kapcsolatos útvonal sorrend információkért.
Bizonyos esetekben egy HTTP 500-as hibát ad vissza, amikor útvonalak nem egyértelműek. A naplózás használatával megtekintheti, hogy mely végpontok okozták a AmbiguousMatchException.
Jogkivonat cseréje útvonalsablonokban [vezérlő], [művelet], [terület]
A kényelem érdekében az attribútumútvonalak támogatják a jogkivonatok cseréjét úgy, hogy szögletes zárójelekbe ([, ]) foglalnak egy jogkivonatot. A jogkivonatok [action], [area] és [controller] a műveletnév, a területnév és a vezérlő nevének értékeire cserélődnek a műveletből, ahol az útvonal definiálva van.
[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);
}
}
Az előző kódban:
[HttpGet]
public IActionResult List()
{
return ControllerContext.MyDisplayRouteInfo();
}
- Mérkőzések
/Products0/List
[HttpGet("{id}")]
public IActionResult Edit(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
- Mérkőzések
/Products0/Edit/{id}
A token cseréje az attribute útvonalak építésének utolsó lépése. Az előző példa ugyanúgy viselkedik, mint a következő 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);
}
}
Ha ezt nem angol nyelven olvassa, ebben a GitHub-vitafórumban tudassa velünk, ha meg szeretné tekinteni a kód megjegyzéseit az anyanyelvén.
Az attribútumútvonalak örökléssel is kombinálhatók. Ez a tokencserével kombinálva erős. A jelölő cseréje az attribútum útvonalak által definiált útvonalnevekre is vonatkozik.
[Route("[controller]/[action]", Name="[controller]_[action]")]minden művelethez létrehoz egy egyedi útvonalnevet:
[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);
}
}
A [ vagy ] literális token helyettesítő elválasztójának megadásához ismételje meg a karaktert ([[ vagy ]]) a kilépéshez.
Paraméterátalakító használata a tokenek cseréjének testreszabásához
A tokencsere paraméterátalakítóval testre szabható. A paraméterátalakító implementálja IOutboundParameterTransformer és átalakítja a paraméterek értékét. Egy egyéni SlugifyParameterTransformer paraméterátalakító például a következőre módosítja az SubscriptionManagement útvonal értékét 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();
}
}
A RouteTokenTransformerConvention egy olyan alkalmazásmodell-konvenció, amely:
- Paraméterátalakítót alkalmaz az alkalmazás összes attribútumútvonalára.
- A csere során testre szabja az attribútumútvonal-jogkivonat értékeit.
public class SubscriptionManagementController : Controller
{
[HttpGet("[controller]/[action]")]
public IActionResult ListAll()
{
return ControllerContext.MyDisplayRouteInfo();
}
}
Az előző ListAll metódus egyezik /subscription-management/list-all.
A RouteTokenTransformerConvention lehetőségként van regisztrálva a ConfigureServices rendszerben.
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews(options =>
{
options.Conventions.Add(new RouteTokenTransformerConvention(
new SlugifyParameterTransformer()));
});
}
A Slug definícióját a Slug MDN webes dokumentációja tartalmazza.
Warning
Amikor a System.Text.RegularExpressions-t használja nem megbízható bemenetek feldolgozására, meg kell adnia egy időtúllépési értéket. Egy rosszindulatú felhasználó adhat RegularExpressions bemenetet, ami szolgáltatásmegtagadásos támadást okozhat. ASP.NET Core keretrendszer API-k, amelyek RegularExpressions időtúllépést használnak.
Több attribútumútvonal
Az attribútumalapú útválasztás támogatja az azonos műveletet elérő útvonalak meghatározását. Ennek leggyakrabban az alapértelmezett hagyományos útvonal viselkedését kell utánoznia az alábbi példában látható módon:
[Route("[controller]")]
public class Products13Controller : Controller
{
[Route("")] // Matches 'Products13'
[Route("Index")] // Matches 'Products13/Index'
public IActionResult Index()
{
return ControllerContext.MyDisplayRouteInfo();
}
Ha több útvonalattribútumot helyez el a vezérlőn, az azt jelenti, hogy mindegyik egyesül a műveleti módszerek útvonalattribútumaival:
[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();
}
}
Az összes HTTP-igeútvonal-korlátozás implementálva IActionConstraintvan.
Ha több útvonalattribútum, amely implementálja IActionConstraint-t, kerül egy akcióra:
- Minden műveletkényszer kombinálva van a vezérlőre alkalmazott útvonalsablonnal.
[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();
}
}
Ha több útvonalat használ a műveletekhez, hasznosnak és hatékonynak tűnhet, jobb, ha az alkalmazás URL-címterét alapszintűen és jól definiálva tartja. Csak akkor használjon több útvonalat a műveleteken, ha szükséges, például a meglévő ügyfelek támogatására.
Attribútumútvonal opcionális paramétereinek, alapértelmezett értékeinek és kényszereinek megadása
Az attribútumútvonalak ugyanazt a beágyazott szintaxist támogatják, mint a hagyományos útvonalak, hogy opcionális paramétereket, alapértelmezett értékeket és korlátozásokat adjanak meg.
public class Products14Controller : Controller
{
[HttpPost("product14/{id:int}")]
public IActionResult ShowProduct(int id)
{
return ControllerContext.MyDisplayRouteInfo(id);
}
}
Az előző kódban [HttpPost("product14/{id:int}")] alkalmaz egy útvonalkorlátozást. A Products14Controller.ShowProduct művelet csak azokkal az URL-címekkel egyezik meg, mint például /product14/3. Az útvonalsablon része {id:int} csak egész számokra korlátozza a szegmenst.
Az útvonalsablon szintaxisának részletes leírását az útvonalsablon-referencia című témakörben találja.
Egyéni útvonalattribútumok az IRouteTemplateProvider használatával
Az összes útvonalattribútumIRouteTemplateProvider-t implementál. A ASP.NET Core-futtatókörnyezet:
- Attribútumokat keres a vezérlőosztályokon és a műveleti módszereken az alkalmazás indításakor.
- A implementálandó
IRouteTemplateProviderattribútumokkal hozza létre a kezdeti útvonalakat.
Egyéni útvonalattribútumok definiálásához implementálható IRouteTemplateProvider . Mindegyik IRouteTemplateProvider lehetővé teszi egyetlen útvonal egyéni útvonalsablon, sorrend és név megadását:
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();
}
}
Az előző Get metódus ad vissza Order = 2, Template = api/MyTestApi.
Attribútumútvonalak testreszabása alkalmazásmodell használatával
Az alkalmazásmodell:
- Az indításkor létrehozott objektummodell.
- Az ASP.NET Core által az alkalmazásokban végzett műveletek irányításához és végrehajtásához használt összes metaadatot tartalmazza.
Az alkalmazásmodell tartalmazza az útvonalattribútumokból összegyűjtött összes adatot. Az útvonalattribútumokból származó adatokat a IRouteTemplateProvider megvalósítás biztosítja. Conventions:
- Meg lehet írni az alkalmazás modelljét úgy, hogy az útválasztás viselkedése testreszabható legyen.
- Az alkalmazás indításakor kerülnek beolvasásra.
Ez a szakasz egy egyszerű példát mutat be az útválasztás alkalmazásmodell használatával történő testreszabására. Az alábbi kód hozzávetőlegesen igazodik a projekt mappastruktúrájához.
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()
};
}
}
}
Az alábbi kód megakadályozza, hogy a namespace konvenció az attribútummal ellátott vezérlőkre vonatkozzon.
public void Apply(ControllerModel controller)
{
var hasRouteAttributes = controller.Selectors.Any(selector =>
selector.AttributeRouteModel != null);
if (hasRouteAttributes)
{
return;
}
A következő vezérlő például nem használja a NamespaceRoutingConvention jelet:
[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}");
}
}
A NamespaceRoutingConvention.Apply módszer:
- Nem tesz semmit, ha a vezérlő attribútum-alapú útvonalakat használ.
- Beállítja a vezérlősablont az
namespacealapján, aznamespacealap eltávolításával.
A NamespaceRoutingConvention következő helyen Startup.ConfigureServicesalkalmazható:
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.
Vegyük például a következő vezérlőt:
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}");
}
}
}
Az előző kódban:
- Az alap
namespacea .My.Application - Az előző vezérlő teljes neve .
My.Application.Admin.Controllers.UsersController - A
NamespaceRoutingConventiona vezérlősablontAdmin/Controllers/Users/[action]/{id?-ra állítja be.
A NamespaceRoutingConvention vezérlők attribútumaként is alkalmazhatók:
[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}");
}
}
Vegyes útválasztás: Attribútum-útválasztás és hagyományos útválasztás
ASP.NET Core-alkalmazások vegyesen használhatják a hagyományos útválasztást és az attribútumalapú útválasztást. Általában hagyományos útvonalakat használnak a böngészők html lapjait kiszolgáló vezérlőkhöz, az API-kat kiszolgáló REST vezérlők attribútum-útválasztásához.
A műveletek vagy hagyományos útvonalra vannak állítva, vagy attribútumok alapján vannak irányítva. Ha egy útvonalat helyez el a vezérlőn vagy a műveleten, az attribútum átirányítva lesz. Az attribútumútvonalakat meghatározó műveletek nem érhetőek el a hagyományos útvonalakon keresztül, és fordítva. A vezérlő bármely útvonalattribútuma a vezérlő attribútumában található összes műveletet átirányítja.
Az attribútum-útválasztás és a hagyományos útválasztás ugyanazt az útválasztási motort használja.
URL-létrehozási és környezeti értékek
Az alkalmazások útválasztási URL-címgenerálási funkciókkal hozhatnak létre URL-hivatkozásokat a műveletekhez. Az URL-címek létrehozása kiküszöböli a keménykódolási URL-címeket, így a kód robusztusabbá és karbantarthatóbbá válik. Ez a szakasz az MVC által biztosított URL-létrehozási funkciókra összpontosít, és csak az URL-létrehozás működésének alapjait ismerteti. Az URL-cím generálásának részletes leírását az Útválasztás című témakörben találja.
Az IUrlHelper interfész az MVC és az URL-generálás útválasztása közötti infrastruktúra mögöttes eleme. A IUrlHelper példány elérhető a Url tulajdonságon keresztül a vezérlőkben, nézetekben és nézetösszetevőkben.
Az alábbi példában a rendszer a tulajdonságon keresztül használja az IUrlHelperController.Url interfészt egy URL-cím létrehozásához egy másik művelethez.
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();
}
}
Ha az alkalmazás az alapértelmezett hagyományos útvonalat használja, a url változó értéke az URL-elérési út sztringje /UrlGeneration/Destination. Ez az URL-elérési út útválasztással van létrehozva az alábbiak kombinálásával:
- Az aktuális kérés útvonalértékei, amelyeket környezeti értékeknek neveznek.
- Az értékek átadása a
Url.Actionrészére és azoknak az értékeknek a helyettesítése az útvonalsablonban:
ambient values: { controller = "UrlGeneration", action = "Source" }
values passed to Url.Action: { controller = "UrlGeneration", action = "Destination" }
route template: {controller}/{action}/{id?}
result: /UrlGeneration/Destination
Az útvonalsablonban minden útvonalparaméter értéke lecserélődik oly módon, hogy a nevek össze vannak párosítva a paraméterértékekkel és a környezeti értékekkel. Egy olyan útvonalparaméter, amely nem rendelkezik értékkel, a következőt teheti:
- Használjon alapértelmezett értéket, ha rendelkezik ilyen értékkel.
- Kihagyható, ha nem kötelező. Például az
idútvonalsablonból{controller}/{action}/{id?}.
Az URL-cím létrehozása meghiúsul, ha a szükséges útvonalparaméter nem rendelkezik megfelelő értékkel. Ha egy útvonal URL-generálása sikertelen, a következő útvonal mindaddig próbálkozik, amíg az összes útvonal ki nem próbálva, vagy nem talál egyezést.
Az előző példa Url.Action a hagyományos útválasztást feltételezi. Az URL-generálás hasonlóan működik az attribútum-útválasztással, bár a fogalmak eltérnek. Hagyományos útválasztással:
- Az útvonalértékek egy sablon kibontására szolgálnak.
- A
controllerésactionútvonalértékei általában megjelennek ebben a sablonban. Ez azért működik, mert az útválasztással egyező URL-címek megfelelnek egy konvenciónak.
Az alábbi példa attribútum-útválasztást használ:
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();
}
}
Az Source előző kódban szereplő művelet generálja a következőt custom/url/to/destination: .
LinkGenerator ASP.NET Core 3.0-ban lett hozzáadva IUrlHelper alternatívájaként.
LinkGenerator hasonló, de rugalmasabb funkciókat kínál. Minden metódushoz IUrlHelper tartozik egy megfelelő metóduscsalád LinkGenerator is.
URL-címek létrehozása műveletnév alapján
Az URL.Action, a LinkGenerator.GetPathByAction és a kapcsolódó túlterhelések mindegyike úgy van kialakítva, hogy létrehozhassa a célvégpontot egy vezérlőnév és műveletnév megadásával.
Használat Url.Action esetén a futtatókörnyezet biztosítja a controller és action aktuális útvonalértékeit.
-
controllerésactionértéke mind a környezeti értékek, mind pedig az általános értékek része. A metódusUrl.Actionmindig az aktuális értékeketactionhasználja, éscontrollerlétrehoz egy URL-útvonalat, amely az aktuális művelethez vezet.
Az útválasztás a környezeti értékek értékeit használja az URL-cím létrehozásakor nem megadott információk kitöltésére. Fontoljon meg egy útvonalat, mint például {a}/{b}/{c}/{d}, a környezeti értékekkel { a = Alice, b = Bob, c = Carol, d = David }.
- Az útválasztás elegendő információval rendelkezik ahhoz, hogy további értékek nélkül hozzon létre URL-címet.
- Az útválasztás elegendő információval rendelkezik, mert minden útvonalparaméternek van értéke.
Ha az érték { d = Donovan } hozzáadva van:
- Az érték
{ d = David }figyelmen kívül lesz hagyva. - A létrehozott URL-elérési út a következő
Alice/Bob/Carol/Donovan: .
Figyelmeztetés: Az URL-elérési utak hierarchikusak. Az előző példában, ha az érték { c = Cheryl } hozzá van adva:
- A rendszer mindkét értéket
{ c = Carol, d = David }figyelmen kívül hagyja. - A
dszámára már nincs érték, ezért az URL-cím létrehozása meghiúsul. - Az URL-cím létrehozásához meg kell adni a kívánt értékeket
césd.
Előfordulhat, hogy az alapértelmezett útvonallal {controller}/{action}/{id?}kapcsolatos problémát tapasztalja. Ez a probléma a gyakorlatban ritkán fordul elő, mert Url.Action mindig explicit módon meghatározza a controller és action értéket.
Az Url.Action számos túlterhelése elfogad egy útvonali értékek objektumot, hogy más útvonalparaméterek értékeit adja meg, mint controller és action. A rendszer gyakran használja az útvonalérték-objektumot id. Például: Url.Action("Buy", "Products", new { id = 17 }). Az útvonalértékek objektuma:
- Konvenció szerint általában névtelen típusú objektum.
- Lehet egy
IDictionary<>vagy POCO).
Az útvonalparamétereknek nem megfelelő további útvonalértékek a lekérdezési sztringbe kerülnek.
public IActionResult Index()
{
var url = Url.Action("Buy", "Products", new { id = 17, color = "red" });
return Content(url);
}
Az előző kód generálja a következőt /Products/Buy/17?color=red: .
A következő kód abszolút URL-címet hoz létre:
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);
}
Abszolút URL-cím létrehozásához használja az alábbiak egyikét:
- Egy túlterhelés, amely elfogadja a
protocol. Például az előző kód. - LinkGenerator.GetUriByAction, amely alapértelmezés szerint abszolút URI-kat hoz létre.
URL-címek létrehozása útvonal szerint
Az előző kód bemutatta egy URL-cím létrehozását a vezérlő és a művelet név megadásával.
IUrlHelper Az Url.RouteUrl metóduscsaládot is tartalmazza. Ezek a metódusok hasonlóak az Url.Action metódushoz, de nem másolja az aktuális értékeket a action és controller az útvonalértékekhez. A leggyakoribb használat a Url.RouteUrl a következő:
- Megadja az URL-cím létrehozásához tartozó útvonalnevet.
- Általában nem ad meg vezérlőt vagy műveletnevet.
public class UrlGeneration2Controller : Controller
{
[HttpGet("")]
public IActionResult Source()
{
var url = Url.RouteUrl("Destination_Route");
return ControllerContext.MyDisplayRouteInfo("", $" URL = {url}");
}
[HttpGet("custom/url/to/destination2", Name = "Destination_Route")]
public IActionResult Destination()
{
return ControllerContext.MyDisplayRouteInfo();
}
A következő Razor fájl létrehoz egy HTML-hivatkozást a Destination_Routekövetkezőre:
<h1>Test Links</h1>
<ul>
<li><a href="@Url.RouteUrl("Destination_Route")">Test Destination_Route</a></li>
</ul>
URL-címek létrehozása HTML-ben és Razor
IHtmlHelper a HtmlHelper módszereket, a Html.BeginForm és a Html.ActionLink használja a megfelelő <form> és <a> elemek generálásához. Ezek a metódusok az URL.Action metódussal hoznak létre URL-címet, és hasonló argumentumokat fogadnak el. Az Url.RouteUrl társai HtmlHelper és Html.BeginRouteForm, amelyek hasonló funkciókkal rendelkeznek.
A TagHelpers URL-címeket hoz létre a form TagHelper és a <a> TagHelper használatával. Mindkét megvalósítás során IUrlHelper-et használnak. További információkért tekintse meg az űrlapok címkesegítőit .
A belső nézetekben a IUrlHelper tulajdonság révén érhető el minden olyan ad-hoc URL-generálás, amelyre a fentiek nem vonatkoznak.
URL-generálás a műveleteredményekben
Az előző példák bemutatták a IUrlHelper használatát a vezérlőben. A vezérlők leggyakoribb használata egy URL-cím létrehozása egy művelet eredményének részeként.
Az ControllerBase és Controller az alaposztályok kényelmi módszereket biztosítanak egy másik műveletre hivatkozó műveleti eredményekhez. Az egyik jellemző használat az átirányítás a felhasználói bemenet elfogadása után:
[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);
}
Az olyan akció-eredmény gyári metódusok, mint a RedirectToAction és a CreatedAtAction, hasonló mintát követnek, mint a IUrlHelper metódusok.
Speciális eset dedikált hagyományos útvonalakhoz
A hagyományos útválasztás egy speciális útvonaldefiníciót, az úgynevezett dedikált hagyományos útvonalat használhat. A következő példában a névvel ellátott blog útvonal egy dedikált hagyományos útvonal:
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?}");
});
Az előző útvonaldefiníciók Url.Action("Index", "Home") használatával hozza létre az URL-címet / az default útvonal használatával, de miért? Előfordulhat, hogy az útvonalértékek { controller = Home, action = Index } elegendőek egy URL generálásához blog használatával, és az eredmény az lesz /blog?action=Index&controller=Home.
A dedikált hagyományos útvonalak az alapértelmezett értékek speciális viselkedésére támaszkodnak, amelyek nem rendelkeznek megfelelő útvonalparaméterrel, amely megakadályozza, hogy az útvonal túlságosan mohó legyen az URL-cím generálása során. Ebben az esetben az alapértelmezett értékek a következők { controller = Blog, action = Article }, és sem controller sem action nem jelenik meg útvonalparaméterként. Ha az útválasztás URL-címet generál, a megadott értékeknek meg kell egyeznie az alapértelmezett értékekkel. Az URL-cím létrehozása blog sikertelen, mert az értékek { controller = Home, action = Index } nem egyeznek { controller = Blog, action = Article }. Az útválasztás ezután visszatér default próbálkozásra, ami sikerrel jár.
Areas
A területek egy MVC-funkció, amellyel a kapcsolódó funkciók külön csoportba rendezhetőek:
- Útválasztási névtér vezérlőműveletekhez.
- A nézetek mappastruktúrája.
A területek használata lehetővé teszi, hogy az alkalmazások több, azonos nevű vezérlővel rendelkezzenek, feltéve, hogy különböző területekkel rendelkeznek. A területek használata hierarchiát hoz létre az útválasztás céljából egy másik útvonalparaméter hozzáadásával a area és controller elemekhez. Ez a szakasz azt ismerteti, hogyan lép kölcsönhatásba az útválasztás a területekkel. Részletekért lásd a Területek című témakört, ahol a területek nézetekkel való használatáról olvashat.
Az alábbi példa úgy konfigurálja az MVC-t, hogy az alapértelmezett hagyományos útvonalat és egy areaarea elnevezett Blogútvonalat használja:
app.UseEndpoints(endpoints =>
{
endpoints.MapAreaControllerRoute("blog_route", "Blog",
"Manage/{controller}/{action}/{id?}");
endpoints.MapControllerRoute("default_route", "{controller}/{action}/{id?}");
});
Az előző kódban a MapAreaControllerRoute meghívásával létrehozzák a "blog_route". A második paraméter a "Blog"terület neve.
Ha egy URL-útvonalhoz hasonlót /Manage/Users/AddUser illeszt, az "blog_route" útvonal létrehozza az útvonalértékeket { area = Blog, controller = Users, action = AddUser }. Az area útvonal értékét a rendszer a következő alapértelmezett értékével areahozza létre: . A létrehozott MapAreaControllerRoute útvonal egyenértékű a következővel:
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 létrehoz egy útvonalat, amely az alapértelmezett értéket és a megadott területnév használatára vonatkozó area korlátozást is használja, ebben az esetben Blog. Az alapértelmezett érték biztosítja, hogy az útvonal mindig { area = Blog, ... }-t hoz létre, a kényszer megköveteli a { area = Blog, ... } értéket az URL generálásához.
A hagyományos útválasztás sorrendfüggő. Általánosságban elmondható, hogy a területekkel rendelkező útvonalakat korábban kell elhelyezni, mivel ezek pontosabbak, mint a terület nélküli útvonalak.
Az előző példában szereplő útvonalértékek { area = Blog, controller = Users, action = AddUser } a következő műveletnek felelnek meg:
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}");
}
}
}
A [Terület] attribútum az, amely egy vezérlőt egy terület részeként jelöl. Ez a vezérlő a Blog környéken található. Az attribútummal nem rendelkező [Area] vezérlők nem tagjai egyik területnek sem, és nem egyeznek meg, ha az útvonal értékét útválasztás area biztosítja. Az alábbi példában csak az első vezérlő felelhet meg az útvonalértéknek { 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}");
}
}
}
Az egyes vezérlők névtere itt látható a teljesség érdekében. Ha az előző vezérlők ugyanazt a névteret használták, fordítóhiba jön létre. Az osztálynévterek nincsenek hatással az MVC útválasztására.
Az első két vezérlő a területek tagjai, és csak akkor egyeznek meg, ha a megfelelő terület nevét az area útvonal értéke adja meg. A harmadik vezérlő nem tartozik egyetlen területhez sem, és csak akkor felel meg, ha az útválasztás nem ad meg értéket a area számára.
A nincs érték egyezés szempontjából az area érték hiánya ugyanaz, mintha a area érték null vagy üres sztring lenne.
Ha egy műveletet egy területen hajt végre, az útvonal értéke areakörnyezeti értékként érhető el az URL-generáláshoz használandó útválasztáshoz. Ez azt jelenti, hogy alapértelmezés szerint a területek ragadósak az URL-generáláshoz, ahogy azt az alábbi minta is mutatja.
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);
}
}
}
Az alábbi kód egy URL-címet hoz létre a következő címre /Zebra/Users/AddUser:
public class HomeController : Controller
{
public IActionResult About()
{
var url = Url.Action("AddUser", "Users", new { Area = "Zebra" });
return Content($"URL: {url}");
}
Műveletdefiníció
A vezérlő nyilvános metódusai a NonAction attribútummal rendelkezők kivételével műveletek.
Mintakód
- MyDisplayRouteInfo a Rick.Docs.Samples.RouteInfo NuGet-csomag biztosítja, és megjeleníti az útvonaladatokat.
- Mintakód megtekintése vagy letöltése (hogyan töltsd le)
Hibakeresési diagnosztika
A részletes útválasztási diagnosztikai kimenethez állítsa be a Logging:LogLevel:Microsoft értékét Debug-re. A fejlesztési környezetben állítsa be a naplószintet: appsettings.Development.json
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Debug",
"Microsoft.Hosting.Lifetime": "Information"
}
}
}