¿Cómo se aplica el enrutamiento en minúsculas en ASP.NET Core?

90

En ASP.NET 4 esto era tan fácil como routes.LowercaseUrls = true;en el RegisterRoutescontrolador de la aplicación.

No puedo encontrar un equivalente en ASP.NET Core para lograr esto. Creo que estaría aquí:

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

Pero nada en configureRoutesapariencia lo permite ... a menos que haya un método de extensión en algún lugar que no pueda encontrar en los documentos, ¿quizás?

mariocatch
fuente

Respuestas:

192

Para ASP.NET Core:

Agregue la siguiente línea al ConfigureServicesmétodo de la Startupclase.

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

Gracias a Skorunka por la respuesta como comentario. Pensé que valía la pena promover una respuesta real.

juegos de manualidades
fuente
35
Vale la pena señalar que debe poner esto ANTES de llamar AddMvc()a su Startup.ConfigureServices()método. AddRouting()que también es llamado por AddMvc()usa las Tryvariantes de los métodos para agregar dependencias a su colección de servicios. Entonces, cuando vea que las dependencias de enrutamiento ya se agregaron, omitirá esas partes de AddMvc()la lógica de configuración.
Nick Albrecht
Cambiando esto a la respuesta correcta ya que la mía fue durante la transición de asp 4 al núcleo.
mariocatch
31

Actualización en ASP.NET Core Version> = 2.2

Desde ASP.NET Core 2.2 , junto con minúsculas , también puede hacer que su ruta sea discontinua usando lo ConstraintMapque hará que su ruta /Employee/EmployeeDetails/1a en /employee/employee-details/1lugar de /employee/employeedetails/1.

Para hacerlo, primero crear la SlugifyParameterTransformerclase debe ser la siguiente:

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

Para ASP.NET Core 2.2 MVC:

En el ConfigureServicesmétodo de la Startupclase:

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

Y la configuración de la ruta debe ser la siguiente:

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

Para ASP.NET Core 2.2 Web API:

En el ConfigureServicesmétodo de la Startupclase:

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

Para ASP.NET Core> = 3.0 MVC:

En el ConfigureServicesmétodo de la Startupclase:

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

Y la configuración de la ruta debe ser la siguiente:

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

Para ASP.NET Core> = 3.0 Web API:

En el ConfigureServicesmétodo de la Startupclase:

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

Para ASP.NET Core> = 3.0 Razor Pages:

En el ConfigureServicesmétodo de la Startupclase:

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

Esto hará /Employee/EmployeeDetails/1ruta a/employee/employee-details/1

TanvirArjel
fuente
Probé este código y el código oficial de Microsoft también, pero el transformador de parámetro "slugify" no tiene ningún efecto. El sistema de enrutamiento simplemente lo ignora (por lo que las URL no se reemplazan por las de guiones). Para comprobarme, puse logger en el método TransformOutbound (), pero no hay llamadas desde allí.
user3172616
¡Bueno! ¡Déjame revisar por favor!
TanvirArjel
@ user3172616 ¡Lo he comprobado ahora mismo! ¡Está funcionando como se esperaba! como generar ruta como employee-details. ¿Me podría mostrar su configuración por favor?
TanvirArjel
@ user3172616 ¿está utilizando el enrutamiento de atributos en la ruta que probó?
TanvirArjel
Utilizo el enfoque de enrutamiento estándar (no el enrutamiento de atributos) en la nueva solución core v2.2 en Visual Studio. Hay dos capturas de pantalla (código c # y código .cshtml). Intenté generar enlaces de diferentes formas sin ningún efecto. imgur.com/a/L8dCF6c
user3172616
20

Como indican otras respuestas, agregando:

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

antes de

services.AddMvc(...)

funciona muy bien, pero también quiero agregar que si usa Identity, también necesitará:

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

Y, obviamente, reemplace ambos IdentityUser, y IdentityRolecon sus propias clases si es necesario.

Acabo de probar esto con .NET Core SDK 1.0.4 y el tiempo de ejecución 1.0.5.

Jorge Yanes Diez
fuente
Configure <RouteOptions> () es la mejor respuesta en mi humilde opinión: diminuto y directo al grano (probado en mvc core 3.1)
T-moty
12

Encontré la solución.

En el ensamblado: Microsoft.AspNet.Routingy el Microsoft.Extensions.DependencyInjectionespacio de nombres, puede hacer esto en su ConfigureServices(IServiceCollection services)método:

services.ConfigureRouting(setupAction =>
{
    setupAction.LowercaseUrls = true;
});
mariocatch
fuente
15
Para ASP NET MVC CORE: services.AddRouting (options => {options.LowercaseUrls = true;});
Skorunka František
Microsoft.Extensions.DependencyInjection en Microsoft.AspNetCore.Routing.dll
Skorunka František
3
Esto era cierto antes de RTM, ahora debe usar .AddRouting en lugar de .ConfigureRouting
Yves Schelpe
1

Para la identidad, la respuesta de @Jorge Yanes Diez no funciona en ASP.NET Core 2.2( creo que 2.x ), por lo que si usa Identity y ASP.NET Core 2.2 (2.x) aquí está la solución:

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

Ref: Configurar la identidad de ASP.NET Core

Mehdi Dehghani
fuente
0

Tenía esto en RegisterRoutes :: RouteConfig:

route.LowercaseUrls = true;

paburgos
fuente