Come si impone il routing in minuscolo in ASP.NET Core?


94

In ASP.NET 4 questo era facile come routes.LowercaseUrls = true;nel RegisterRoutesgestore dell'app.

Non riesco a trovare un equivalente in ASP.NET Core per ottenere questo risultato. Penso che sarebbe qui:

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

Ma niente negli configureRoutessguardi lo consente ... a meno che non ci sia un metodo di estensione da qualche parte che non riesco a trovare nei documenti forse?

Risposte:


202

Per ASP.NET Core:

Aggiungi la seguente riga al ConfigureServicesmetodo della Startupclasse.

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

Grazie a Skorunka per la risposta come commento. Ho pensato che valesse la pena promuovere a una risposta reale.


35
Vale la pena notare che dovresti metterlo PRIMA di chiamare effettivamente il AddMvc()tuo Startup.ConfigureServices()metodo. AddRouting()che viene anche chiamato da AddMvc()utilizza le Tryvarianti dei metodi per aggiungere dipendenze alla raccolta di servizi. Quindi, quando vede che le dipendenze di routing sono già state aggiunte, salterà quelle parti della AddMvc()logica di installazione.
Nick Albrecht

Cambiando questo alla risposta corretta poiché il mio era durante la transizione da asp 4 a core.
mariocatch

@ NickAlbrecht non sembra fare differenza se viene chiamato prima o dopo (almeno a partire da ASP.NET Core 5.0). AddRouting () verrà comunque chiamato due volte, quindi non importa in quale ordine.
Thomas Levesque

Credo che sia stato fatto intorno a .NET Core 3.x. Lo hanno cambiato in modo che il routing fosse una funzionalità autonoma invece che in bundle con MVC. Non credo che il routing venga più chiamato da AddMvc(o AddControllersWithViewsse non hai bisogno di RazorPages). Quindi l'ordine è davvero importante solo se stai usando AspNetCore 2. (Non ricordare se questa era un'opzione in 1.x). Tuttavia hanno fatto dividere il comportamento minuscola in due impostazioni, quindi se si vuole indirizzi di casi completamente inferiori, è necessario impostare sia LowercaseUrlse LowercaseQueryStringsal true.
Nick Albrecht

37

Aggiornamento nella versione ASP.NET Core> = 2.2

Da ASP.NET core 2.2 , insieme a lettere minuscole si può anche rendere il vostro itinerario tratteggiata usando ConstraintMapche renderà il vostro percorso /Employee/EmployeeDetails/1a /employee/employee-details/1posto di /employee/employeedetails/1.

Per fare ciò, prima creare la SlugifyParameterTransformerclasse dovrebbe essere come segue:

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

Per ASP.NET Core 2.2 MVC:

Nel ConfigureServicesmetodo della Startupclasse:

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

E la configurazione del percorso dovrebbe essere la seguente:

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

Per l'API Web ASP.NET Core 2.2:

Nel ConfigureServicesmetodo della Startupclasse:

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

Per ASP.NET Core> = 3.0 MVC:

Nel ConfigureServicesmetodo della Startupclasse:

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

E la configurazione del percorso dovrebbe essere la seguente:

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

Per ASP.NET Core> = 3.0 API Web:

Nel ConfigureServicesmetodo della Startupclasse:

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

Per ASP.NET Core> = 3.0 Razor Pages:

Nel ConfigureServicesmetodo della Startupclasse:

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

Questo farà /Employee/EmployeeDetails/1rotta verso/employee/employee-details/1


Ho provato questo codice e anche il codice ufficiale Microsoft, ma il trasformatore del parametro "slugify" non ha alcun effetto. Viene semplicemente ignorato dal sistema di routing (quindi gli URL non vengono sostituiti con quelli tratteggiati). Per controllarmi ho inserito il logger nel metodo TransformOutbound (), ma nessuna chiamata da lì.
user3172616

Va bene! Fammi controllare per favore!
TanvirArjel

@ user3172616 Ho controllato adesso! funziona come previsto! come generare un percorso come employee-details. Mi mostreresti la tua configurazione per favore?
TanvirArjel

@ user3172616 stai utilizzando l'instradamento degli attributi sulla rotta che hai testato?
TanvirArjel

Uso l'approccio di routing standard (non il routing degli attributi) sulla nuovissima soluzione core v2.2 in Visual Studio. Sono disponibili due screenshot (codice c # e codice .cshtml). Ho provato a generare collegamenti in modi diversi senza alcun effetto. imgur.com/a/L8dCF6c
user3172616

21

Come indicano altre risposte, aggiungendo:

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

prima

services.AddMvc(...)

funziona alla grande, ma voglio anche aggiungere che se usi Identity, avrai anche bisogno di:

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 ovviamente, sostituiscili entrambi IdentityUsere, IdentityRolese necessario , con le tue classi.

L'ho appena testato con .NET Core SDK 1.0.4 e il runtime 1.0.5.


Configure <RouteOptions> () è la migliore risposta imho: tiny and straight to the point (testato su mvc core 3.1)
T-moty

12

Trovato la soluzione.

Nell'assembly: Microsoft.AspNet.Routinge nello Microsoft.Extensions.DependencyInjectionspazio dei nomi, puoi farlo nel tuo ConfigureServices(IServiceCollection services)metodo:

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

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

Microsoft.Extensions.DependencyInjection in Microsoft.AspNetCore.Routing.dll
Skorunka František

3
Questo era vero prima di RTM, ora dovresti usare .AddRouting al posto di .ConfigureRouting
Yves Schelpe

0

Per l'identità, la risposta di @Jorge Yanes Diez non funziona in ASP.NET Core 2.2( penso 2.x ), quindi se usi Identity e ASP.NET Core 2.2 (2.x) ecco la soluzione:

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

Rif: configurare ASP.NET Core Identity


-1

Avevo questo su RegisterRoutes :: RouteConfig:

route.LowercaseUrls = true;

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.