Como você impõe o roteamento em minúsculas no ASP.NET Core?


94

No ASP.NET 4, isso era tão fácil quanto routes.LowercaseUrls = true;noRegisterRoutes manipulador do aplicativo.

Não consigo encontrar um equivalente no ASP.NET Core para conseguir isso. Eu acho que seria aqui:

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

Mas nada configureRoutesparece permitir isso ... a menos que haja um método de extensão em algum lugar que eu não consigo encontrar nos documentos, talvez?

Respostas:


202

Para ASP.NET Core:

Adicione a seguinte linha ao ConfigureServicesmétodo da Startupclasse.

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

Obrigado a Skorunka pela resposta como um comentário. Achei que valia a pena promover para uma resposta real.


35
É importante notar que você deve colocar isso ANTES de realmente chamar AddMvc()seu Startup.ConfigureServices()método. AddRouting()que também é chamado de AddMvc()usa as Tryvariantes dos métodos para adicionar dependências à coleção de serviços. Portanto, quando ele vir que as dependências de roteamento já foram adicionadas, ele ignorará essas partes da AddMvc()lógica de configuração.
— Nick Albrecht

Mudar para uma resposta correta, já que a minha foi durante a transição do asp 4 para o core.
— mariocatch de

@NickAlbrecht não parece fazer diferença se for chamado antes ou depois (pelo menos a partir do ASP.NET Core 5.0). AddRouting () será chamado duas vezes de qualquer maneira, então não importa em que ordem.
— Thomas Levesque

Acredito que isso tenha sido feito em torno do .NET Core 3.x. Eles mudaram para que o roteamento fosse um recurso autônomo em vez de empacotado com o MVC. Eu não acredito que o roteamento seja chamado do AddMvc(ou AddControllersWithViewsse você não precisar do RazorPages) mais. Portanto, a ordem só importa realmente se você estiver usando AspNetCore 2. (Não me lembro se essa era uma opção em 1.x). No entanto, eles fizeram dividir o comportamento minúsculas em duas configurações, então se você quiser endereços de caso totalmente inferiores, você precisa configurar tanto LowercaseUrlse LowercaseQueryStringspara true.
— Nick Albrecht

37

Atualização na versão ASP.NET Core> = 2.2

No ASP.NET Core 2.2 , junto com letras minúsculas, você também pode fazer sua rota tracejada usando ConstraintMapque fará sua rota /Employee/EmployeeDetails/1para em /employee/employee-details/1vez de /employee/employeedetails/1.

Para fazer isso, primeiro crie a SlugifyParameterTransformerclasse deve ser da seguinte forma:

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:

No ConfigureServicesmétodo da Startupaula:

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

E a configuração da rota deve ser a seguinte:

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:

No ConfigureServicesmétodo da Startupaula:

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:

No ConfigureServicesmétodo da Startupaula:

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

E a configuração da rota deve ser a seguinte:

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 API da Web:

No ConfigureServicesmétodo da Startupaula:

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

Para ASP.NET Core> = 3.0 Páginas Razor:

No ConfigureServicesmétodo da Startupaula:

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

Isto fará o /Employee/EmployeeDetails/1caminho para/employee/employee-details/1


Tentei este código e também o código oficial da Microsoft, mas o transformador de parâmetro "slugify" não surtiu efeito. É apenas ignorado pelo sistema de roteamento (para que os URLs não sejam substituídos por tracejados). Para verificar a mim mesmo, coloquei o logger no método TransformOutbound (), mas nenhuma chamada de lá.
— user3172616

OK! Deixa eu verificar, por favor!
— TanvirArjel

@ user3172616 Eu verifiquei agora mesmo! está funcionando como esperado! como gerar rota como employee-details. Você poderia me mostrar sua configuração, por favor?
— TanvirArjel

@ user3172616 você está usando o roteamento de atributo na rota que testou?
— TanvirArjel de

Eu uso a abordagem de roteamento padrão (não o roteamento de atributo) em uma nova solução v2.2 principal no Visual Studio. Existem duas capturas de tela (código c # e código .cshtml). Tentei gerar links de maneiras diferentes sem nenhum efeito. imgur.com/a/L8dCF6c
— user3172616

21

Como outras respostas indicam, acrescentando:

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

antes

services.AddMvc(...)

funciona muito bem, mas também quero acrescentar que, se você usar o Identity, também precisará de:

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

E, obviamente, substitua ambos IdentityUsere IdentityRolepor suas próprias classes, se necessário.

Acabei de testar isso com o .NET Core SDK 1.0.4 e o runtime 1.0.5.


Configure <RouteOptions> () é a melhor resposta imho: minúsculo e direto ao ponto (testado em mvc core 3.1)
— T-moty

12

Encontrei a solução.

No assembly: Microsoft.AspNet.Routinge no Microsoft.Extensions.DependencyInjectionnamespace, você pode fazer isso em seu ConfigureServices(IServiceCollection services)método:

services.ConfigureRouting(setupAction =>
{
    setupAction.LowercaseUrls = true;
});

15
Para ASP NET MVC CORE: services.AddRouting (options => {options.LowercaseUrls = true;});
— Skorunka František

Microsoft.Extensions.DependencyInjection em Microsoft.AspNetCore.Routing.dll
— Skorunka František

3
Isso era verdade antes do RTM, agora você deve usar .AddRouting em vez de .ConfigureRouting
— Yves Schelpe

0

Para identidade, a resposta de @Jorge Yanes Diez não funciona em ASP.NET Core 2.2( acho que 2.x ), então, se você usar Identity e ASP.NET Core 2.2 (2.x), aqui está a solução:

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

Ref: Configurar Identidade ASP.NET Core


-1

Tive isso em RegisterRoutes :: RouteConfig:

routes.LowercaseUrls = true;

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.