ASP.NET Routing MVC poprzez atrybuty metody [zamknięty]
WStackOverflow Podcast #54 Jeff wspomina, że rejestrują swoje trasy URL w bazie kodowej StackOverflow poprzez atrybut powyżej metody obsługującej trasę. Brzmi jak dobry pomysł(z zastrzeżeniem, że Phil Haack wspomniał o priorytetach trasy).
Czy ktoś mógłby podać jakąś próbkę, aby to się stało?
Również, jakieś "najlepsze praktyki" dla korzystania z tego stylu routingu?
6 answers
Aktualizacja: to zostało opublikowane na codeplex . Kompletny kod źródłowy, jak również wstępnie skompilowany assembly są tam do pobrania. Nie miałem jeszcze czasu na zamieszczenie dokumentacji na stronie, więc ten post na razie będzie musiał wystarczyć.
Aktualizacja: dodałem kilka nowych atrybutów do obsługi 1) kolejność tras, 2) ograniczenia parametrów trasy i 3) domyślne wartości parametrów trasy. Poniższy tekst odzwierciedla to aktualizacja.
Zrobiłem coś takiego dla moich projektów MVC (nie mam pojęcia, jak Jeff robi to ze stackoverflow). Zdefiniowałem zestaw własnych atrybutów: UrlRoute, UrlRouteParameterConstraint, UrlRouteParameterDefault. Mogą być dołączone do metod działania kontrolera MVC, aby automatycznie wiązać z nimi trasy, ograniczenia i wartości domyślne.
Przykład użycia:
(zauważ, że ten przykład jest nieco wymyślony, ale pokazuje funkcja)
public class UsersController : Controller
{
// Simple path.
// Note you can have multiple UrlRoute attributes affixed to same method.
[UrlRoute(Path = "users")]
public ActionResult Index()
{
return View();
}
// Path with parameter plus constraint on parameter.
// You can have multiple constraints.
[UrlRoute(Path = "users/{userId}")]
[UrlRouteParameterConstraint(Name = "userId", Regex = @"\d+")]
public ActionResult UserProfile(int userId)
{
// ...code omitted
return View();
}
// Path with Order specified, to ensure it is added before the previous
// route. Without this, the "users/admin" URL may match the previous
// route before this route is even evaluated.
[UrlRoute(Path = "users/admin", Order = -10)]
public ActionResult AdminProfile()
{
// ...code omitted
return View();
}
// Path with multiple parameters and default value for the last
// parameter if its not specified.
[UrlRoute(Path = "users/{userId}/posts/{dateRange}")]
[UrlRouteParameterConstraint(Name = "userId", Regex = @"\d+")]
[UrlRouteParameterDefault(Name = "dateRange", Value = "all")]
public ActionResult UserPostsByTag(int userId, string dateRange)
{
// ...code omitted
return View();
}
Definicja UrlRouteAttribute:
/// <summary>
/// Assigns a URL route to an MVC Controller class method.
/// </summary>
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class UrlRouteAttribute : Attribute
{
/// <summary>
/// Optional name of the route. If not specified, the route name will
/// be set to [controller name].[action name].
/// </summary>
public string Name { get; set; }
/// <summary>
/// Path of the URL route. This is relative to the root of the web site.
/// Do not append a "/" prefix. Specify empty string for the root page.
/// </summary>
public string Path { get; set; }
/// <summary>
/// Optional order in which to add the route (default is 0). Routes
/// with lower order values will be added before those with higher.
/// Routes that have the same order value will be added in undefined
/// order with respect to each other.
/// </summary>
public int Order { get; set; }
}
Definicja UrlRouteParameterConstraintAttribute:
/// <summary>
/// Assigns a constraint to a route parameter in a UrlRouteAttribute.
/// </summary>
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class UrlRouteParameterConstraintAttribute : Attribute
{
/// <summary>
/// Name of the route parameter on which to apply the constraint.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Regular expression constraint to test on the route parameter value
/// in the URL.
/// </summary>
public string Regex { get; set; }
}
Definicja UrlRouteParameterDefaultAttribute:
/// <summary>
/// Assigns a default value to a route parameter in a UrlRouteAttribute
/// if not specified in the URL.
/// </summary>
[AttributeUsage(AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class UrlRouteParameterDefaultAttribute : Attribute
{
/// <summary>
/// Name of the route parameter for which to supply the default value.
/// </summary>
public string Name { get; set; }
/// <summary>
/// Default value to set on the route parameter if not specified in the URL.
/// </summary>
public object Value { get; set; }
}
Zmiany na globalne.asax.cs:
Zastąp wywołania do MapRoute, pojedynczym wywołaniem do RouteUtility.Funkcja RegisterUrlRoutesFromAttributes:
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
RouteUtility.RegisterUrlRoutesFromAttributes(routes);
}
Definicja / Align = "left" / RegisterUrlRoutesFromAttributes:
Pełne źródło znajduje się na codeplex. Proszę przejść do strony, jeśli masz jakieś opinie lub raporty o błędach.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-03 05:38:10
Możesz również spróbować AttributeRouting , który jest dostępny z github lub przez nuget.
To jest bezwstydna wtyczka, ponieważ jestem autorem projektu. Ale cholera, jeśli nie jestem zadowolony z jego używania. Ty też możesz. Istnieje wiele dokumentacji i przykładowego kodu w repozytorium github wiki .
Z tą biblioteką możesz wiele zrobić:
- Udekoruj swoje działania atrybutami GET, POST, PUT i DELETE.
- Mapa wielu tras do pojedynczego działania, zamawiając je z właściwości zamówienia.
- Określ domyślne trasy i ograniczenia za pomocą atrybutów.
- Określ opcjonalne paramy za pomocą prostego ? token przed nazwą parametru.
- Określ nazwę trasy dla obsługi nazwanych tras.
- Definiowanie obszarów MVC na kontrolerze lub kontrolerze bazowym.
- Grupuj lub zagnieżdżaj swoje trasy razem za pomocą prefiksów tras stosowanych do kontrolera lub kontrolera bazowego.
- Wsparcie URL.
- Ustawia pierwszeństwo tras pomiędzy trasami zdefiniowanymi dla akcji, w kontrolerze oraz pomiędzy kontrolerami i kontrolerami bazowymi.
- automatycznie Generuj wychodzące adresy URL z małymi literami.
- Zdefiniuj własne konwencje tras i zastosuj je na kontrolerze, aby wygenerować trasy dla akcji wewnątrz kontrolera bez atrybutów boilerplate (think RESTful style).
- Debuguj trasy za pomocą dostarczonego Httphandlera.
I ' m sure jest jeszcze coś, o czym zapominam. Zobacz też Instalacja przez nuget jest bezbolesna.
Uwaga: od 16/4/12 AttributeRouting obsługuje również nową infrastrukturę Web API.Na wypadek, gdybyś szukał czegoś, co sobie z tym poradzi. Dzięki subkamran !
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:47:12
1. Pobierz RiaLibrary.Www.dll i odwołaj się do niego w swoim ASP.NET Projekt strony MVC
2. Decoreate metody kontrolera z atrybutami [Url]:
public SiteController : Controller
{
[Url("")]
public ActionResult Home()
{
return View();
}
[Url("about")]
public ActionResult AboutUs()
{
return View();
}
[Url("store/{?category}")]
public ActionResult Products(string category = null)
{
return View();
}
}
BTW,'?"sign in" {?category} ' parametr oznacza, że jest opcjonalny. Nie musisz tego jawnie określać w ustawieniach domyślnych trasy, co jest równe temu:
routes.MapRoute("Store", "store/{category}",
new { controller = "Store", action = "Home", category = UrlParameter.Optional });
3. Aktualizacja Globalna.asax.plik cs
public class MvcApplication : System.Web.HttpApplication
{
public static void RegisterRoutes(RouteCollection routes)
{
routes.IgnoreRoute("{resource}.axd/{*pathInfo}");
routes.MapRoutes(); // This does the trick
}
protected void Application_Start()
{
RegisterRoutes(RouteTable.Routes);
}
}
Jak ustawić domyślne i ograniczenia? Przykład:
public SiteController : Controller
{
[Url("admin/articles/edit/{id}", Constraints = @"id=\d+")]
public ActionResult ArticlesEdit(int id)
{
return View();
}
[Url("articles/{category}/{date}_{title}", Constraints =
"date=(19|20)\d\d-(0[1-9]|1[012])-(0[1-9]|[12][0-9]|3[01])")]
public ActionResult Article(string category, DateTime date, string title)
{
return View();
}
}
Jak ustawić kolejność? Przykład:
[Url("forums/{?category}", Order = 2)]
public ActionResult Threads(string category)
{
return View();
}
[Url("forums/new", Order = 1)]
public ActionResult NewThread()
{
return View();
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-03-07 08:02:38
Ten post jest tylko po to, aby rozszerzyć odpowiedź DSO.
Konwertując trasy na atrybuty, musiałem obsługiwać atrybut ActionName. Więc w GetRouteParamsFromAttribute:
ActionNameAttribute anAttr = methodInfo.GetCustomAttributes(typeof(ActionNameAttribute), false)
.Cast<ActionNameAttribute>()
.SingleOrDefault();
// Add to list of routes.
routeParams.Add(new MapRouteParams()
{
RouteName = routeAttrib.Name,
Path = routeAttrib.Path,
ControllerName = controllerName,
ActionName = (anAttr != null ? anAttr.Name : methodInfo.Name),
Order = routeAttrib.Order,
Constraints = GetConstraints(methodInfo),
Defaults = GetDefaults(methodInfo),
});
Również uznałem, że nazewnictwo trasy nie jest odpowiednie. Nazwa jest budowana dynamicznie za pomocą controllerName.RouteName. Ale moje nazwy tras są ciągami const w klasie kontrolera i używam ich do wywoływania Url.RouteUrl. Dlatego naprawdę potrzebuję nazwy trasy w atrybutie, aby była aktualna nazwa trasy.
Kolejną rzeczą, którą zrobię, jest konwersja domyślnych i ograniczających atrybutów Na AttributeTargets.Parametr tak, że mogę przykleić je do params.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-05-25 15:56:58
Połączyłem te dwa podejścia w Frankensteinowską wersję dla każdego, kto chce. (Podobała mi się opcjonalna notacja param, ale uważałem, że powinny one być oddzielnymi atrybutami od domyślnych/ograniczeń, a nie wszystkie mieszane w jeden).
Http://github.com/djMax/AlienForce/tree/master/Utilities/Web/
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-04-29 15:41:42
Musiałem uruchomić routing ITCloud w asp.net mvc 2 używając Asynccontrollera -- aby to zrobić, wystarczy edytować RouteUtility.klasy cs w źródle i przekompilować. Musisz usunąć "ukończone" z nazwy akcji na linii 98
// Add to list of routes.
routeParams.Add(new MapRouteParams()
{
RouteName = String.IsNullOrEmpty(routeAttrib.Name) ? null : routeAttrib.Name,
Path = routeAttrib.Path,
ControllerName = controllerName,
ActionName = methodInfo.Name.Replace("Completed", ""),
Order = routeAttrib.Order,
Constraints = GetConstraints(methodInfo),
Defaults = GetDefaults(methodInfo),
ControllerNamespace = controllerClass.Namespace,
});
Następnie, w AsyncController, udekoruj Xxxxcompleted ActionResult znanymi atrybutami UrlRoute
i UrlRouteParameterDefault
:
[UrlRoute(Path = "ActionName/{title}")]
[UrlRouteParameterDefault(Name = "title", Value = "latest-post")]
public ActionResult ActionNameCompleted(string title)
{
...
}
Mam nadzieję, że to pomoże komuś z tym samym problemem.Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-07-22 14:28:16