asp.net-mvc
routing
Sök…
Introduktion
Routing är hur ASP.NET MVC matchar en URI till en åtgärd. Routing-modulen är ansvarig för att kartlägga inkommande webbläsarförfrågningar till specifika MVC-controlleråtgärder.
MVC 5 stöder en ny typ av routing, kallad attribut routing. Som namnet antyder använder attributruting attribut för att definiera rutter. Attributruting ger dig mer kontroll över URI: erna i din webbapplikation.
Anpassad routing
Anpassad routing ger specialiserat behov av routing för att hantera specifika inkommande förfrågningar.
För att definiera anpassade rutter, kom ihåg att ordningen på rutter som du lägger till i ruttabellen är viktig.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// this is an advanced custom route
// you can define custom URL with custom parameter(s) point to certain action method
routes.MapRoute(
"CustomEntry", // Route name
"Custom/{entryId}", // Route pattern
new { controller = "Custom", action = "Entry" } // Default values for defined parameters above
);
// this is a basic custom route
// any custom routes take place on top before default route
routes.MapRoute(
"CustomRoute", // Route name
"Custom/{controller}/{action}/{id}", // Route pattern
new { controller = "Custom", action = "Index", id = UrlParameter.Optional } // Default values for defined parameters above
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // Route pattern
new { controller = "Home", action = "Index", id = UrlParameter.Optional } // Default values for defined parameters above
);
}
controller
och action
är reserverade. Som standard kartlägger MVC {controller}
del av URL: n till klassen <controller>Controller
och letar sedan efter en metod med namnet <action>
utan att lägga till några suffix.
Även om det kan vara frestande att skapa en familj av rutter med hjälp av {controller}/{action}/{parameter}
-mall, anser du att genom att göra detta avslöjar du strukturen i din applikation och gör webbadresser något spröda eftersom att ändra namnet på kontrollern ändrar rutt och bryter länkarna som sparats av användaren.
Föredrar uttrycklig ruttinställning:
routes.MapRoute(
"CustomRoute", // Route name
"Custom/Index/{id}", // Route pattern
new { controller = "Custom", action = nameof(CustomController.Index), id = UrlParameter.Optional }
);
(du kan inte använda nameof
operatör för controller namn som det kommer att ha ytterligare suffix Controller
) som måste utelämnas vid inställning controller namn på rutten.
Lägga till anpassad rutt i Mvc
Användaren kan lägga till anpassad rutt, kartlägga en URL till en specifik åtgärd i en kontroller. Detta används för sökmotoroptimeringsändamål och gör webbadresser läsbara.
routes.MapRoute(
name: "AboutUsAspx", // Route name
url: "AboutUs.aspx", // URL with parameters
defaults: new { controller = "Home", action = "AboutUs", id = UrlParameter.Optional } // Parameter defaults
);
Attribut routing i MVC
Tillsammans med det klassiska sättet att definiera rutten definierade MVC WEB API 2 och sedan MVC 5-ramverk Attribute routing
:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// This enables attribute routing and must go before other routes are added to the routing table.
// This makes attribute routes have higher priority
routes.MapMvcAttributeRoutes();
}
}
För rutter med samma prefix inuti en styrenhet kan du ställa in ett gemensamt prefix för hela handlingsmetoder inuti styrenheten med attributet RoutePrefix
.
[RoutePrefix("Custom")]
public class CustomController : Controller
{
[Route("Index")]
public ActionResult Index()
{
...
}
}
RoutePrefix
är valfritt och definierar den del av webbadressen som är förinställd för alla kontrollerens åtgärder.
Om du har flera rutter kan du ställa in en standardrutt genom att fånga åtgärd som parameter och sedan använda den för hela kontrollen såvida inte specifikt Route
definierat i vissa handlingsmetoder som åsidosätter standardrutten.
[RoutePrefix("Custom")]
[Route("{action=index}")]
public class CustomController : Controller
{
public ActionResult Index()
{
...
}
public ActionResult Detail()
{
...
}
}
Grunderna för routing
När du begär url yourSite/Home/Index
via en webbläsare, kommer routingmodulen rikta begäran till Index
action metoden HomeController
klass. Hur vet det att skicka begäran till den här klassens specifika metod? där kommer RouteTable.
Varje applikation har en ruttabell där den lagrar ruttmönstret och information om var du ska rikta begäran till. Så när du skapar din mvc-applikation finns det en standardrutt som redan är registrerad i routingtabellen. Det kan du se i klassen RouteConfig.cs
.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoute("Default", "{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}
Du kan se att posten har ett namn och en mall. Mallen är ruttmönstret som ska kontrolleras när en förfrågan kommer in. Standardmallen har Home
som värdet för kontrollens url-segment och Index
som värdet för actionsegmentet. Det innebär att om du inte uttryckligen skickar en kontrollernamn och åtgärd i din begäran, kommer den att använda dessa standardvärden. Detta är anledningen till att du får samma resultat när du går in på yourSite/Home/Index
och yourSite
Du kanske har lagt märke till att vi har en parameter som heter id som det sista segmentet i vårt ruttmönster. Men i standardinställningarna anger vi att det är valfritt. Det är anledningen till att vi inte behövde ange ID-värdet i den url vi försökte.
Gå tillbaka till indexmetoden i HomeController och lägg till en parameter till det
public ActionResult Index(int id)
{
return View();
}
Nu sätter en Visual Studio brytpunkt i denna metod. Kör ditt projekt och få åtkomst till yourSite/Home/Index/999
i din webbläsare. Brytpunkten träffas och du bör kunna se att värdet 999 nu är tillgängligt i id
parametern.
Skapa ett andra ruttmönster
Låt oss säga att vi vill ha en uppsättning så att samma handlingsmetod kallas för ett annat ruttmönster. Vi kan göra det genom att lägga till en ny ruttdefinition till ruttabellen.
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
// New custom route definition added
routes.MapRoute("MySpecificRoute",
"Important/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
//Default catch all normal route definition
routes.MapRoute("Default", "{controller}/{action}/{id}",
new { controller = "Home", action = "Index", id = UrlParameter.Optional });
}
Den nya definitionen som jag lade till har ett mönster Important/{id}
där id igen är valfritt. Det betyder att när du begär yourSiteName\Important
eller yourSiteName\Important\888
kommer det att skickas till indexåtgärden för HomeController.
Order för registrering av ruttdefinition
Ruttregistreringens ordning är viktig. Du bör alltid registrera de specifika ruttmönstren innan generisk standardrutt.
Fånga alla rutter
Anta att vi vill ha en rutt som tillåter ett obundet antal segment som så:
- http://example.com/Products/ (visa alla produkter)
- http://example.com/Products/IT
- http://example.com/Products/IT/Laptops
- http://example.com/Products/IT/Laptops/Ultrabook
- http://example.com/Products/IT/Laptops/Ultrabook/Asus
- etc.
Vi måste lägga till en rutt, normalt i slutet av ruttabellen eftersom det troligtvis skulle fånga alla förfrågningar, så:
routes.MapRoute("Final", "Route/{*segments}",
new { controller = "Product", action = "View" });
I regulatorn kan en åtgärd som kan hantera detta vara:
public void ActionResult View(string[] segments /* <- the name of the parameter must match the name of the route parameter */)
{
// use the segments to obtain information about the product or category and produce data to the user
// ...
}
Fånga alla rutter för att möjliggöra routing på klientsidan
Det är en bra praxis att koda tillståndet för enkel sida-applikation (SPA) i url:
my-app.com/admin-spa/users/edit/id123
Detta gör det möjligt att spara och dela applikationstillstånd.
När användaren sätter url i webbläsarens adressfält och träffar anges servern måste ignorera klientsidan av den begärda url. Om du betjänar ditt SPA som en visad rakknivvy (resultat av samtalskontrollens handling) snarare än en statisk html-fil kan du använda en fångst-rutt:
public class AdminSpaController
{
[Route("~/admin-spa/{clienSidePart*}")]
ActionResult AdminSpa()
{
...
}
}
I detta fall returnerar servern bara SPA, och den initialiserar sig sedan enligt rutten. Detta tillvägagångssätt är mer flexibelt eftersom det inte beror på url-omskriva modulen.
Attribut routing i områden
För att använda Attribut Routing i områden krävs registrering av områden och [RouteArea(...)]
definitioner.
I RouteConfig.cs
:
public class RouteConfig
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapMvcAttributeRoutes();
AreaRegistration.RegisterAllAreas();
}
}
I en provområdesregleringsdefinition för attributruting:
[RouteArea("AreaName", AreaPrefix = "AreaName")]
[RoutePrefix("SampleAreaController")]
public class SampleAreaController : Controller
{
[Route("Index")]
public ActionResult Index()
{
return View();
}
}
För att använda Url.Action
länkar i områden:
@Url.Action("Index", "SampleAreaController", new { area = "AreaName" })