Как обеспечить принудительную маршрутизацию в нижнем регистре в ASP.NET Core?

90

В ASP.NET 4 это было так же просто, как и routes.LowercaseUrls = true;в RegisterRoutesобработчике приложения.

Я не могу найти эквивалент в ASP.NET Core для этого. Думаю, это будет здесь:

app.UseMvc(configureRoutes =>
{
    configureRoutes.MapRoute("Default", "{controller=App}/{action=Index}/{id?}");
});

Но ничто во configureRoutesвнешности не позволяет это ... разве что где-то есть метод расширения, который я не могу найти в документации?

мариокач
источник

Ответы:

192

Для ASP.NET Core:

Добавьте следующую строку в ConfigureServicesметод Startupкласса.

services.AddRouting(options => options.LowercaseUrls = true);

Спасибо Скорунке за ответ в виде комментария. Я подумал, что стоит продвигать настоящий ответ.

ремесленные игры
источник
35
Стоит отметить, что вы должны указать это ДО того, как вы действительно вызовете AddMvc()свой Startup.ConfigureServices()метод. AddRouting()который также вызывается, AddMvc()использует Tryварианты методов для добавления зависимостей в вашу коллекцию сервисов. Поэтому, когда он увидит, что зависимости маршрутизации уже добавлены, он пропустит эти части AddMvc()логики настройки.
Ник Альбрехт
Переключение этого на правильный ответ, поскольку мой был во время перехода asp 4 на core.
mariocatch
32

Обновление в версии ASP.NET Core> = 2.2

Из ASP.NET Ядра 2.2 , наряду с строчными вы также можете сделать свой маршрут пунктирным , используя ConstraintMapкоторый сделает свой маршрут , /Employee/EmployeeDetails/1чтобы /employee/employee-details/1вместо /employee/employeedetails/1.

Для этого сначала SlugifyParameterTransformerнужно создать класс следующим образом:

public class SlugifyParameterTransformer : IOutboundParameterTransformer
{
    public string TransformOutbound(object value)
    {
        // Slugify value
        return value == null ? null : Regex.Replace(value.ToString(), "([a-z])([A-Z])", "$1-$2").ToLower();
    }
}

Для ASP.NET Core 2.2 MVC:

В ConfigureServicesметоде Startupкласса:

services.AddRouting(option =>
{
    option.ConstraintMap["slugify"] = typeof(SlugifyParameterTransformer);
});

А конфигурация маршрута должна быть следующей:

app.UseMvc(routes =>
{
     routes.MapRoute(
        name: "default",
        template: "{controller:slugify}/{action:slugify}/{id?}",
        defaults: new { controller = "Home", action = "Index" });
});

Для веб-API ASP.NET Core 2.2:

В ConfigureServicesметоде Startupкласса:

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc(options => 
    {
        options.Conventions.Add(new RouteTokenTransformerConvention(new SlugifyParameterTransformer()));
    }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
}

Для ASP.NET Core> = 3.0 MVC:

В ConfigureServicesметоде Startupкласса:

services.AddRouting(option =>
{
    option.ConstraintMap["slugify"] = typeof(SlugifyParameterTransformer);
});

А конфигурация маршрута должна быть следующей:

app.UseEndpoints(endpoints =>
{
      endpoints.MapAreaControllerRoute(
          name: "AdminAreaRoute",
          areaName: "Admin",
          pattern: "admin/{controller:slugify=Dashboard}/{action:slugify=Index}/{id:slugify?}");

      endpoints.MapControllerRoute(
          name: "default",
          pattern: "{controller:slugify}/{action:slugify}/{id:slugify?}",
          defaults: new { controller = "Home", action = "Index" });
});

Для веб-API ASP.NET Core> = 3.0:

В ConfigureServicesметоде Startupкласса:

services.AddControllers(options => 
{
    options.Conventions.Add(new RouteTokenTransformerConvention(new SlugifyParameterTransformer()));
});

Для ASP.NET Core> = 3.0 Razor Pages:

В ConfigureServicesметоде Startupкласса:

services.AddRazorPages(options => 
{
    options.Conventions.Add(new PageRouteTransformerConvention(new SlugifyParameterTransformer()));
})

Это проложит /Employee/EmployeeDetails/1путь к/employee/employee-details/1

ТанвирАрджел
источник
Я пробовал этот код и официальный код Microsoft, но преобразователь параметров "slugify" не действует. Он просто игнорируется системой маршрутизации (поэтому URL-адреса не заменяются пунктирными). Чтобы проверить себя, я поместил регистратор в метод TransformOutbound (), но никаких вызовов оттуда.
user3172616
Ладно! Дайте проверить, пожалуйста!
TanvirArjel
@ user3172616 Я проверил прямо сейчас! он работает, как ожидалось! как создание маршрута как employee-details. Не могли бы вы показать мне свою конфигурацию?
TanvirArjel
@ user3172616 используете ли вы маршрутизацию атрибутов на маршруте, который вы тестировали?
TanvirArjel
Я использую стандартный подход к маршрутизации (а не маршрутизацию атрибутов) в новом решении ядра v2.2 в Visual Studio. Есть два скриншота (код C # и код .cshtml). Пытался сгенерировать ссылки разными способами, но безуспешно. imgur.com/a/L8dCF6c
user3172616
20

Как указывают другие ответы, добавление:

services.Configure<RouteOptions>(options => options.LowercaseUrls = true);

перед

services.AddMvc(...)

отлично работает, но я также хочу добавить, что если вы используете Identity, вам также понадобятся:

services.AddIdentity<IdentityUser, IdentityRole>(options =>
{
    var appCookie = options.Cookies.ApplicationCookie;
    appCookie.LoginPath = appCookie.LoginPath.ToString().ToLowerInvariant();
    appCookie.LogoutPath = appCookie.LogoutPath.ToString().ToLowerInvariant();
    appCookie.ReturnUrlParameter = appCookie.ReturnUrlParameter.ToString().ToLowerInvariant();
});

И, очевидно, замените оба IdentityUser, и IdentityRoleсвоими собственными классами, если это необходимо.

Я только что протестировал это с помощью .NET Core SDK 1.0.4 и среды выполнения 1.0.5.

Хорхе Янес Диез
источник
Настроить <RouteOptions> () - лучший ответ imho: крошечный и сразу по
делу
12

Нашел решение.

В сборке: Microsoft.AspNet.Routingи Microsoft.Extensions.DependencyInjectionпространстве имен вы можете сделать это в своем ConfigureServices(IServiceCollection services)методе:

services.ConfigureRouting(setupAction =>
{
    setupAction.LowercaseUrls = true;
});
мариокач
источник
15
Для ASP NET MVC CORE: services.AddRouting (options => {options.LowercaseUrls = true;});
Скорунка Франтишек
Microsoft.Extensions.DependencyInjection в Microsoft.AspNetCore.Routing.dll
Скорунка Франтишек
3
Так было до RTM, теперь вы должны использовать .AddRouting вместо .ConfigureRouting
Ив Шелпе
1

Для идентичности ответ @Jorge Yanes Diez не работает ASP.NET Core 2.2( я думаю, 2.x ), поэтому, если вы используете Identity и ASP.NET Core 2.2 (2.x), вот решение:

services.ConfigureApplicationCookie(options =>
{
    options.LoginPath = "/account/login";
    options.ReturnUrlParameter = "returnurl";
    ...
});

Ссылка: Настройка удостоверения ASP.NET Core

Мехди Дехгани
источник
0

У меня было это в RegisterRoutes :: RouteConfig:

routes.LowercaseUrls = true;

пабургос
источник