Asp.Net MVC: Як увімкнути тире в моїх URL-адресах?


75

Я хотів би, щоб у моїх URL-адресах були тире, окремі слова. Отже, замість:

/MyController/MyAction

Я хотів б:

/My-Controller/My-Action

Чи можливо це?


можливий дублікат підтримки ASP.net MVC для URL-адрес із дефісами
Джон

2
@ John, запитання, яке ви зв'язали, можливо, повторюється не цим, див. Дати, це питання задається приблизно на 2 роки пізніше цього
Абхішек Сіддху

Відповіді:


155

Ви можете використовувати атрибут ActionName так:

[ActionName("My-Action")]
public ActionResult MyAction() {
    return View();
}

Зверніть увагу, що тоді вам потрібно буде зателефонувати до свого файлу перегляду "My-Action.cshtml" (або відповідного розширення). Вам також потрібно буде вказати "my-action" у будь-яких методах Html.ActionLink.

Не існує такого простого рішення для контролерів.

Редагувати: оновлення для MVC5

Увімкніть маршрути глобально:

public static void RegisterRoutes(RouteCollection routes)
{
    routes.MapMvcAttributeRoutes();
    // routes.MapRoute...
}

Тепер з MVC5 в проект включено маршрутизацію атрибутів. Тепер ви можете використовувати:

[Route("My-Action")]

Про методи дій.

Для контролерів ви можете застосувати RoutePrefixатрибут, який застосовуватиметься до всіх методів дій у цьому контролері:

[RoutePrefix("my-controller")]

Однією з переваг використання RoutePrefixє параметри URL-адреси, які також передаватимуться будь-яким методам дій.

[RoutePrefix("clients/{clientId:int}")]
public class ClientsController : Controller .....

Сніп ..

[Route("edit-client")]
public ActionResult Edit(int clientId) // will match /clients/123/edit-client

1
Це справжня відповідь. Не впевнений, чому Філ не додав цю інформацію
Едуардо Молтені

2
Приємна порада. Просто додамо: коли ви робите це за допомогою виклику за замовчуванням View (), MVC буде шукати "My-Action.aspx" десь у папці Views, а не "MyAction.aspx", якщо ви прямо не вказали оригінальне ім'я.
Ніколас Пясецький

@Eduardo Я думаю, що атрибут ActionName був доданий до Preview 5, який з’явився відразу після публікації Філа.
Девід Колар,

Як явно вказати ім'я файлу подання? Чи потрібно змінювати ім'я файлу подань на My-Action.aspx?
Олексій

4
@LordofScripts - переконайтесь, що ви правильно налаштували маршрутизацію за допомогою: routes.MapMvcAttributeRoutes ();
ChadT

16

Ви можете створити власний обробник маршруту, як показано в цьому блозі:

http://blog.didsburydesign.com/2010/02/how-to-allow-hyphens-in-urls-using-asp-net-mvc-2/

public class HyphenatedRouteHandler : MvcRouteHandler{
        protected override IHttpHandler  GetHttpHandler(RequestContext requestContext)
        {
            requestContext.RouteData.Values["controller"] = requestContext.RouteData.Values["controller"].ToString().Replace("-", "_");
            requestContext.RouteData.Values["action"] = requestContext.RouteData.Values["action"].ToString().Replace("-", "_");
            return base.GetHttpHandler(requestContext);
        }
    }

... і новий маршрут:

routes.Add(
            new Route("{controller}/{action}/{id}", 
                new RouteValueDictionary(
                    new { controller = "Default", action = "Index", id = "" }),
                    new HyphenatedRouteHandler())
        );

Тут було задано дуже подібне запитання: підтримка ASP.net MVC для URL-адрес із дефісами


11

Я розробив бібліотеку NuGet з відкритим кодом для цієї проблеми, яка неявно перетворює EveryMvc / Url у every-mvc / url.

Великі URL-адреси є проблематичними, оскільки шляхи до файлів cookie чутливі до регістру, більшість Інтернету насправді чутливі до регістру, тоді як технології Microsoft розглядають URL-адреси як чутливі до регістру. ( Більше на моєму дописі в блозі )

Пакет NuGet: https://www.nuget.org/packages/LowercaseDashedRoute/

Щоб встановити його, просто відкрийте вікно NuGet у Visual Studio, клацнувши правою кнопкою миші на проекті та вибравши NuGet Package Manager, а на вкладці «Інтернет» введіть «Штриховий штриховий маршрут», і воно повинно з’явитися.

Крім того, ви можете запустити цей код у консолі диспетчера пакетів:

Install-Package LowercaseDashedRoute

Після цього слід відкрити App_Start / RouteConfig.cs і прокоментувати існуючий маршрут. Виклик MapRoute (...) і додати замість цього:

routes.Add(new LowercaseDashedRoute("{controller}/{action}/{id}",
  new RouteValueDictionary(
    new { controller = "Home", action = "Index", id = UrlParameter.Optional }),
    new DashedRouteHandler()
  )
);

Це воно. Усі URL-адреси є малими, пунктирними та неявно перетворені, не роблячи нічого більше.

URL-адреса проекту з відкритим кодом: https://github.com/AtaS/lowercase-dashed-route


Спробувавши близько дюжини інших рішень, які я знайшов в Інтернеті, це було перше, що насправді працювало для мене з MVC5. Дякую
Barryman9000

Дуже дякую.
Девід

8

Ось те, що я робив, використовуючи області в ASP.NET MVC 5, і це працювало сподобалось. Мені також не довелося перейменовувати свої погляди.

У RouteConfig.cs зробіть так:

 public static void RegisterRoutes(RouteCollection routes)
    {
        // add these to enable attribute routing and lowercase urls, if desired
        routes.MapMvcAttributeRoutes();
        routes.LowercaseUrls = true;

        // routes.MapRoute...
    }

У своєму контролері додайте це перед визначенням класу:

[RouteArea("SampleArea", AreaPrefix = "sample-area")]
[Route("{action}")]
public class SampleAreaController: Controller
{
    // ...

    [Route("my-action")]
    public ViewResult MyAction()
    {
        // do something useful
    }
}

URL-адреса, яка відображається в браузері, якщо тестування на локальній машині: localhost / sample-area / my-action . Вам не потрібно перейменовувати файли перегляду або щось інше. Я був цілком задоволений кінцевим результатом.

Після ввімкнення атрибутів маршрутизації ви можете видалити будь-які наявні у вас файли реєстрації областей, такі як SampleAreaRegistration.cs.

Ця стаття допомогла мені дійти такого висновку. Сподіваюся, це вам стане в нагоді.


3

Asp.Net MVC 5 буде підтримувати маршрутизацію атрибутів, дозволяючи більш чіткий контроль над назвами маршрутів. Зразок використання буде виглядати так:

[RoutePrefix("dogs-and-cats")]
public class DogsAndCatsController : Controller
{
    [HttpGet("living-together")]
    public ViewResult LivingTogether() { ... }

    [HttpPost("mass-hysteria")]
    public ViewResult MassHysteria() { }
}

Щоб отримати таку поведінку для проектів, що використовують Asp.Net MVC до v5, подібну функціональність можна знайти у проекті AttributeRouting (також доступний як самородок ). Насправді Microsoft звернулася до автора AttributeRouting, щоб допомогти їм у їх реалізації для MVC 5.


1
Нічого собі, ніхто не згадував посилання на Ghostbusters?
Ерік Філіпс,

1

Ви можете написати власний маршрут, який походить від класу Route GetRouteData, щоб видалити тире, але коли ви викликаєте API для створення URL-адреси, вам доведеться пам’ятати про те, що слід включати тире для імені дії та імені контролера.

Це не повинно бути занадто складно.


Філ має рацію (як завжди). Є чудовий приклад, за який я не можу взяти кредит, але я вдячний, що знайшов. Це MVP, і ви можете знайти його тут .
Даніель Кокс,

Ось мій пакет NuGet для цієї реалізації: nuget.org/packages/LowercaseDashedRoute Не забудьте прочитати README на GitHub (за посиланням Інформація про проект на сторінці NuGet)
Ata S.

1

Ви можете визначити конкретний маршрут, наприклад:

routes.MapRoute(
    "TandC", // Route controllerName
    "CommonPath/{controller}/Terms-and-Conditions", // URL with parameters
    new {
        controller = "Home",
        action = "Terms_and_Conditions"
    } // Parameter defaults
);

Але цей маршрут потрібно зареєструвати ДО вашого маршруту за замовчуванням.


Подібним чином використання AttributeRouting дозволяє вказати будь-яку назву маршруту, яку ви хочете, з додатковою перевагою, точно знаючи, з яким маршрутом пов’язана ваша дія.
Jim Geurts,

0

Якщо у вас є доступ до модуля перезапису URL-адрес IIS ( http://blogs.iis.net/ruslany/archive/2009/04/08/10-url-rewriting-tips-and-tricks.aspx ), ви можете просто переписати URL-адреси.

Запити до / my-controller / my-action можна переписати на / mycontroller / myaction, і тоді немає потреби писати власні обробники або щось інше. Відвідувачі отримують гарні URL-адреси, а ви отримуєте ті, які MVC може зрозуміти.

Ось приклад для одного контролера та дії, але ви можете змінити це як більш загальне рішення:

<rewrite>
  <rules>
    <rule name="Dashes, damnit">
      <match url="^my-controller(.*)" />
      <action type="Rewrite" url="MyController/Index{R:1}" />
    </rule>
  </rules>
</rewrite>

Можливим недоліком цього є те, що вам доведеться переключити свій проект на використання IIS Express або IIS для перезапису, щоб він працював під час розробки.


0

Я все ще досить новачок у MVC, тож сприйміть це з достатньою кількістю солі. Це не елегантне, загальноприйняте рішення, але в MVC4 мені вдалося:

routes.MapRoute(
    name: "ControllerName",
    url: "Controller-Name/{action}/{id}",
    defaults: new { controller = "ControllerName", action = "Index", id = UrlParameter.Optional }
);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.