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?

Author: Leniel Maccaferri, 2009-05-21

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.

 62
Author: DSO,
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 !

 44
Author: spot,
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();
}
 9
Author: Konstantin Tarkus,
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.

 3
Author: Nicolas Cadilhac,
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/

 0
Author: Max Metral,
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.
 0
Author: TimDog,
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