ASP.NET маршрутизация MVC через атрибуты метода [закрыто]



на Подкаст StackOverflow #54, Джефф упоминает, что они регистрируют свои маршруты URL в кодовой базе StackOverflow через атрибут над методом, который обрабатывает маршрут. Звучит как хорошая концепция (с оговоркой, что Фил Хаак поднял вопрос о приоритетах маршрута).



может ли кто-нибудь предоставить образец, чтобы это произошло?



кроме того, любые "лучшие практики" для использования этого стиля маршрутизации?

535   6  

6 ответов:

обновление: это было опубликовано на codeplex. Полный исходный код, а также предварительно скомпилированная сборка доступны для загрузки. У меня еще не было времени разместить документацию на сайте, поэтому этого сообщения SO будет достаточно на данный момент.

обновление: я добавил некоторые новые атрибуты для обработки 1) упорядочение маршрута, 2) ограничения параметров маршрута и 3) Значения параметров маршрута по умолчанию. Текст ниже отражено это обновление.

Я на самом деле сделал что-то подобное для моих проектов MVC (я понятия не имею, как Джефф делает это с stackoverflow). Я определил набор пользовательских атрибутов: UrlRoute, UrlRouteParameterConstraint, UrlRouteParameterDefault. Они могут быть присоединены к методам действий контроллера MVC, чтобы автоматически привязывать к ним маршруты, ограничения и значения по умолчанию.

пример использования:

(обратите внимание, что этот пример несколько надуманный, но он демонстрирует эту особенность)

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();
    }

определение атрибута 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; }
}

определение атрибута 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; }
}

определение 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; }
}

изменения в глобальном.асакс.cs:

замените вызовы MapRoute, с помощью одного вызова маршруту служебная программа.RegisterUrlRoutesFromAttributes функция:

    public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        RouteUtility.RegisterUrlRoutesFromAttributes(routes);
    }

определение Маршрутности.RegisterUrlRoutesFromAttributes:

полный источник на codeplex. Пожалуйста, зайдите на сайт если у вас есть какие-либо отзывы или отчеты об ошибках.

вы также можете попробовать AttributeRouting, который доступен github или через nuget.

это бесстыдная вилка, так как я автор проекта. Но черт возьми, если я не очень счастлив, используя его. Возможно, и ты тоже. В репозитории github есть много документации и примеров кода wiki.

с этой библиотекой, вы можете сделать много:

  • украсьте свои действия с GET, POST, PUT и Удалите атрибуты.
  • сопоставьте несколько маршрутов с одним действием, упорядочив их с помощью свойства Order.
  • укажите маршрут по умолчанию и ограничения с помощью атрибутов.
  • укажите необязательные параметры с помощью простого ? знак перед именем параметра.
  • Укажите имя маршрута для поддержки именованных маршрутов.
  • определите области MVC на контроллере или базовом контроллере.
  • сгруппируйте или вложите свои маршруты вместе, используя префиксы маршрутов применяется к контроллеру или базовому контроллеру.
  • поддержка устаревших ссылках.
  • установите приоритет маршрутов среди маршрутов, определенных для действия, внутри контроллера, а также между контроллерами и базовыми контроллерами.
  • автоматически создавать исходящие URL-адреса в нижнем регистре.
  • определите свои собственные пользовательские соглашения о маршруте и примените их на контроллере для создания маршрутов для действий внутри контроллера без стандартных атрибутов (подумайте RESTful стиль.)
  • отладка маршрутов с помощью прилагаемого HttpHandler.

Я уверен, что есть некоторые другие вещи я забыл. Проверить его. Это безболезненно установить через nuget.

примечание: с 4/16/12 AttributeRouting также поддерживает новую инфраструктуру Web API. на всякий случай вы ищете что-то, что может справиться с этим. спасибо subkamran!

1. Скачать RiaLibrary.Сеть.dll и ссылаться на него в вашем ASP.NET проект сайта MVC

2. Методы контроллера Decoreate с атрибутами [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();
    }
}

кстати, '?'войдите' {?параметр category} ' означает, что он необязателен. Вам не нужно будет указывать это явно в Route defaults, что равно этому:

routes.MapRoute("Store", "store/{category}",
new { controller = "Store", action = "Home", category = UrlParameter.Optional });

3. Обновление Глобальное.асакс.цезий файл

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);
    }
}

Как установить значения по умолчанию и ограничения? Пример:

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();
    }
}

Как установить заказ? Пример:

[Url("forums/{?category}", Order = 2)]
public ActionResult Threads(string category)
{
    return View();
}

[Url("forums/new", Order = 1)]
public ActionResult NewThread()
{
    return View();
}

этот пост предназначен только для расширения ответа DSO.

при преобразовании моих маршрутов в атрибуты мне нужно было обработать атрибут ActionName. Так что в 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),
});

также я нашел название маршрута не подходит. Имя строится динамически с controllerName.RouteName. Но мои имена маршрутов-это строки const в классе контроллера, и я использую эти const для вызова Url.RouteUrl. Вот почему мне действительно нужно имя маршрута в атрибуте чтобы быть фактическим названием маршрута.

еще одна вещь, которую я сделаю, это преобразовать атрибуты по умолчанию и ограничения в AttributeTargets.Параметр, чтобы я мог вставить их в params.

Я объединил эти два подхода в Франкенштейновскую версию для всех, кто этого хочет. (Мне понравилась необязательная нотация param, но также подумал, что они должны быть отдельными атрибутами от default/constraints, а не все смешанные в один).

http://github.com/djMax/AlienForce/tree/master/Utilities/Web/

мне нужно, чтобы получить ITCloud маршрутизации, работающие в asp.net в MVC 2 с помощью AsyncController -- для этого просто измените маршруту служебная программа.класс cs в исходнике и перекомпилировать. Вы должны удалить "завершено" из имени действия в строке 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,
});

затем, в AsyncController, украсьте XXXXCompleted ActionResult знакомым UrlRoute и UrlRouteParameterDefault атрибуты:

[UrlRoute(Path = "ActionName/{title}")]
[UrlRouteParameterDefault(Name = "title", Value = "latest-post")]
public ActionResult ActionNameCompleted(string title)
{
    ...
}

надеюсь, что это поможет кому-то с той же проблемой.

Comments

    Ничего не найдено.