W świecie ASP.NET URL odpowiadał namacalnemu plikowi.
W świecie MVC w którym posługujemy się pojęciami akcji i routingu URL nie ma nic wspólnego z plikiem, za to oczywiście ma wiele wspólnego z akcjami i kontrolerami.
A oto droga jaką pokonuje URL
Routing URL zapewnia nam niezależność adresów od plików jest bardziej powiązany z logiką aplikacji, dobrze jest więc go prawidłowo zaprojektować. Warto zwrócić uwagę na takie zagadanienia:
- utrzymywanie prostych i krótkich adresów URL - łatwiejsze korzystanie z witryny dla użytkownika końcowego
- wprowadzenie wzorców umożliwiających pomijanie parametrów no events/< rok>/< miesiac>/< data>
- unikanie ujawniania ID z bazy a jeśli to jest konieczne - dodawanie zbędnych informacji w celu zwiększenia czytelności adresu
| Wzorc Routingu | Przykładowy URL |
|
{controller}/{action}/{id} |
/Products/Show/All |
| {controller}/{action}/{id}.aspx | /Products/Show/All.aspx |
| archive/{year}-{month}/{title}.aspx | /archive/2008-07/BlogPost.aspx |
| {language}-{country}/{controller}/ {action}/{id} | /en-us/Products/Show/All |
| {department}/{title}.aspx | /Sales/Overview.aspx |
Definiowanie Routingu
Routes są definiowane na starcie aplikacji czyli w Global.asax w metodzie Application_Start
Używany jest zawsze pierwszy pasujący routing!
Jeśli nie pasuje - brany(sprawdzany) jest kolejny
Oprócz mapowania możemy użyć też Ignore aby pewne wzorce były pomijane - co przydaje się przy wykorzystywaniu równocześnie klasycznych stron ASP.NET.
Mapowanie przyjmuje do 4 parametrów (opisane w przykładowym kodzie).
Oto przykład pliku Global.asax
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
namespace MvcApplication1
{
public class GlobalApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
/* ==
routes.Add(
new Route("{resource}.axd/{*pathInfo}",
new StopRouteHandler())
);*/
/*Force routing handler to process all of the .aspx requests
for the directory /Classsic int the regular ASP.NET way */
routes.Add(
new Route("Classic/{resource}.aspx?{*requestUrl}",
new StopRoutingHandler())
);
routes.Add(
new Route("Classic/{resource}.aspx",
new StopRoutingHandler())
);
//---------- add route
routes.MapRoute(
"ProductShow", // Route name
"Product/{id}-{title}.asp", // URL with parameters
new
{ // Parameter defaults
controller = "Product",
action = "Show",
id = "",
title = ""
},
new { id = @"[\d.*]" } // Parameter constraints
);
routes.MapRoute(
"Default", // Route name
"{controller}/{action}/{id}", // URL with parameters
new
{ // Parameter defaults
controller = "Home",
action = "Index",
id = ""
}
);
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
}
Jeśli mamy określony parametr id w routingu w funkcji będącej akcją musi nazywać się on tak samo.
public ActionResult Index()
{
//widok generowany z automatu
return View(edul.Risks.ToList());
}
public ActionResult IndexPaged(int? id) //parametr musi sie nazywac tak jak w routingu!!
{
int pageSize = 10;
return View(edul.Risks.Skip(pageSize * (id.HasValue ? id.Value : 0)).Take(pageSize).ToList());
}
Ostatni z parametrów wymusza restrykcje parametrów. Możliwe jest napisanie własnej funkcji definiujące takie restrykcje. Funkcja taka musi implementować interface IRouteConstraint:
public class AuthenticatedRouteConstraint : IRouteConstraint
{
#region IRouteConstraint Members
public bool Match(HttpContextBase httpContext, Route route,
string parameterName, RouteValueDictionary values,
RouteDirection routeDirection)
{
// Match only when user is authenticated
return httpContext.Request.IsAuthenticated;
}
#endregion
}
Odpowiedni kawałek kodu w Global.asax
routes.MapRoute(
"Secret",
"Secret/{action}",
new { controller = "Secret", action = "Index" },
new { authenticated = new AuthenticatedRouteConstraint() }
);
0 komentarze:
Prześlij komentarz