it-swarm.com.de

Wie kann ich in ASP.NET MVC Routen in Kleinbuchstaben erstellen?

Wie kann ich in ASP.NET MVC Routen in Kleinbuchstaben und, falls möglich, mit Unterstrichen versehen? Damit ich /dinners/details/2DinnersController.Details(2) und, wenn möglich, /dinners/more_details/2DinnersController.MoreDetails(2) aufrufen müsste?

Dies alles, während weiterhin Muster wie {controller}/{action}/{id} Verwendet werden.

144
pupeno

Mit System.Web.Routing 4.5 können Sie dies einfach implementieren, indem Sie die LowercaseUrls-Eigenschaft von RouteCollection festlegen:

public static void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        routes.LowercaseUrls = true;

        routes.MapRoute(
            name: "Default",
            url: "{controller}/{action}/{id}",
            defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional }
        );
    }

Angenommen, Sie tun dies aus SEO-Gründen, um eingehende URLs in Kleinbuchstaben umzuleiten (wie in vielen Links in diesem Artikel erwähnt).

protected void Application_BeginRequest(object sender, EventArgs e)
{
  //You don't want to redirect on posts, or images/css/js
  bool isGet = HttpContext.Current.Request.RequestType.ToLowerInvariant().Contains("get");
  if (isGet && HttpContext.Current.Request.Url.AbsolutePath.Contains(".") == false)    
  {
     string lowercaseURL = (Request.Url.Scheme + "://" + HttpContext.Current.Request.Url.Authority + HttpContext.Current.Request.Url.AbsolutePath);
     if (Regex.IsMatch(lowercaseURL, @"[A-Z]"))
     {
      //You don't want to change casing on query strings
      lowercaseURL = lowercaseURL.ToLower() + HttpContext.Current.Request.Url.Query;

      Response.Clear();
      Response.Status = "301 Moved Permanently";
      Response.AddHeader("Location", lowercaseURL); 
      Response.End();
    }
 }
}
233
ITmeze

Diese beiden Tutorials haben geholfen, als ich dasselbe tun und gut arbeiten wollte:

http://www.coderjournal.com/2008/03/force-mvc-route-url-lowercase/http://goneale.com/2008/12/19/lowercase -route-urls-in-aspnet-mvc /

BEARBEITEN: Für Projekte mit Bereichen müssen Sie die GetVirtualPath () -Methode ändern:

public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
{
  var lowerCaseValues = new RouteValueDictionary();

  foreach (var v in values)
  {
    switch (v.Key.ToUpperInvariant())
    {
      case "ACTION":
      case "AREA":
      case "CONTROLLER":
        lowerCaseValues.Add(v.Key, ((string)v.Value).ToLowerInvariant());
        break;
      default:
        lowerCaseValues.Add(v.Key.ToLowerInvariant(), v.Value);
        break;
    }
  }
  return base.GetVirtualPath(requestContext, lowerCaseValues);
}
44
Derek Lawless

Wenn Sie den UrlHelper zum Generieren des Links verwenden, können Sie einfach den Namen der Aktion und des Controllers in Kleinbuchstaben angeben:

itemDelete.NavigateUrl = Url.Action("delete", "photos", new { key = item.Key });

Ergebnisse in:/media/photos/delete/64 (obwohl mein Controller und meine Aktion Pascal-Fall sind).

21
Matt

Wenn Sie zufällig ASP.NET Core verwendet haben, sollten Sie sich wahrscheinlich this ansehen:

Fügen Sie der Methode ConfigureServices der Klasse Startup die folgende Zeile hinzu.

services.AddRouting(options => options.LowercaseUrls = true);
18
Ebrahim Byagowi

Ich fand dies in Nick Berardis Coder Journal , aber es gab keine Informationen darüber, wie die LowercaseRoute -Klasse implementiert werden kann. Daher hier mit zusätzlichen Informationen umbuchen.

Erweitern Sie zuerst die Klasse Route zu LowercaseRoute

public class LowercaseRoute : Route
{
    public LowercaseRoute(string url, IRouteHandler routeHandler)
        : base(url, routeHandler) { }
    public LowercaseRoute(string url, RouteValueDictionary defaults, IRouteHandler routeHandler)
        : base(url, defaults, routeHandler) { }
    public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, IRouteHandler routeHandler)
        : base(url, defaults, constraints, routeHandler) { }
    public LowercaseRoute(string url, RouteValueDictionary defaults, RouteValueDictionary constraints, RouteValueDictionary dataTokens, IRouteHandler routeHandler) : base(url, defaults, constraints, dataTokens, routeHandler) { }
    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values)
    {
        VirtualPathData path = base.GetVirtualPath(requestContext, values);

        if (path != null)
            path.VirtualPath = path.VirtualPath.ToLowerInvariant();

        return path;
    }
}

Ändern Sie dann die RegisterRoutes -Methode von Global.asax.cs

public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.Add(new LowercaseRoute("{controller}/{action}/{id}", 
        new RouteValueDictionary(new { controller = "Home", action = "Index", id = "" }), 
        new MvcRouteHandler()));

    //routes.MapRoute(
    //    "Default",                                              // Route name
    //    "{controller}/{action}/{id}",                           // URL with parameters
    //    new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
    //);
}

Ich möchte jedoch eine Möglichkeit kennen, Routen zu verwenden.MapRoute ...

15
John Oxley

Sie können die MapRoute-Syntax weiterhin verwenden, indem Sie diese Klasse als Erweiterung zu RouteCollection hinzufügen:

public static class RouteCollectionExtension
{
    public static Route MapRouteLowerCase(this RouteCollection routes, string name, string url, object defaults)
    {
        return routes.MapRouteLowerCase(name, url, defaults, null);
    }

    public static Route MapRouteLowerCase(this RouteCollection routes, string name, string url, object defaults, object constraints)
    {
        Route route = new LowercaseRoute(url, new MvcRouteHandler())
        {
            Defaults = new RouteValueDictionary(defaults),
            Constraints = new RouteValueDictionary(constraints)
        };

        routes.Add(name, route);

        return route;
    }
}

Jetzt können Sie im Startup Ihrer Anwendung "MapRouteLowerCase" anstelle von "MapRoute" verwenden:

    public void RegisterRoutes(RouteCollection routes)
    {
        routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

        // Url shortcuts
        routes.MapRouteLowerCase("Home", "", new { controller = "Home", action = "Index" });
        routes.MapRouteLowerCase("Login", "login", new { controller = "Account", action = "Login" });
        routes.MapRouteLowerCase("Logout", "logout", new { controller = "Account", action = "Logout" });

        routes.MapRouteLowerCase(
            "Default",                                              // Route name
            "{controller}/{action}/{id}",                           // URL with parameters
            new { controller = "Home", action = "Index", id = "" }  // Parameter defaults
        );
    }
11
Markus Wolters

Dies hat tatsächlich zwei Antworten:

  1. Sie können dies bereits tun: Die Routen-Engine führt einen Vergleich durch, bei dem die Groß- und Kleinschreibung nicht berücksichtigt wird. Wenn Sie eine Route in Kleinbuchstaben eingeben, wird diese an den entsprechenden Controller und die entsprechende Aktion weitergeleitet.
  2. Wenn Sie Steuerelemente verwenden, die Routenverknüpfungen (ActionLink, RouteLink usw.) generieren, werden Verknüpfungen in Groß- und Kleinschreibung erstellt, sofern Sie dieses Standardverhalten nicht außer Kraft setzen.

Du bist allein für die Unterstriche, obwohl ...

6
GalacticCowboy

Könnten Sie das ActionName-Attribut verwenden?

 [ActionName("more_details")]
 public ActionResult MoreDetails(int? page)
 {

 }

Ich denke nicht, dass es auf den Fall ankommt. Mit More_Details, more_DETAILS, mOrE_DeTaILs in der URL gelangen Sie alle zur gleichen Controller-Aktion.

2
GuyIncognito