मैं ASP.NET MVC में लोअरकेस रूट कैसे कर सकता हूं?


145

अगर ASP.NET MVC में मार्ग संभव हो, तो मुझे लोअरकेस, प्लस अंडरस्कोर कैसे हो सकता है? ताकि मुझे /dinners/details/2कॉल करना पड़े DinnersController.Details(2)और, हो सके तो /dinners/more_details/2कॉल करें DinnersController.MoreDetails(2)?

यह सब अभी भी जैसे पैटर्न का उपयोग करते हुए {controller}/{action}/{id}


मैंने अपने सभी मार्गों को विभिन्न कारणों से मैन्युअल रूप से लिखना समाप्त कर दिया है और मुझे लगता है कि ऐसा कुछ भी नहीं है जो केवल CRUD नहीं है, ऐसा करने से बचना मुश्किल है। इसलिए मैंने उन्हें केवल लोअरकेस में लिखा।
पिलीनो

का उपयोग करते हुए वेब फार्म ? यहां जाएं: msdn.microsoft.com/en-us/library/... । (मैं धीरे-धीरे अपनी परियोजना को वेब रूपों से एमवीसी में परिवर्तित कर रहा हूं और इस परियोजना में दोनों हैं)
जेस

मुझे पूरा यकीन है कि आप इसे डिफ़ॉल्ट रूप से कर सकते हैं

मुझे नहीं लगता कि यह मायने रखता है यदि आप कम या ऊपरी मामले में मार्गों में टाइप करते हैं।

जवाबों:


238

System.Web.Routing 4.5 के साथ, आप रूटकेस के लोअरकेसकेस प्रॉपर्टी को सेट करके इसे सीधा लागू कर सकते हैं:

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

यह मानते हुए कि आप एसईओ कारणों से ऐसा कर रहे हैं, आप आने वाले यूआरएल को कम करने के लिए पुनर्निर्देशित करना चाहते हैं (जैसा कि इस लेख के कई लिंक में कहा गया है)।

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

4
यह अब तक 4.0 में सबसे सरल काम है।
पॉल टर्नर

1
काश यह शीर्ष पर होता ... लगभग कार्गो-कोड का एक बहुत कुछ!
akatakritos

2
शानदार उत्तर :-) बाद वाला एसईओ हिस्सा एक HTTP मॉड्यूल में अच्छी तरह से फिट बैठता है।
डेविड किर्कलैंड

1
@Aaron शेरमेन जाने के लिए Application_BeginRequest भाग को कहां से दबाया गया है? यह मुझे सार्वजनिक त्रुटियाँ दे रहा है जब इसके अंदर का सार्वजनिक रूट रूटफोन और जब इसके बाहर का भी।
रिचर्ड मिचेनिक

1
@ richard-mišenčík इसे Global.asax फ़ाइल में जोड़ें
ITmeze

44

जब मैं एक ही काम करना चाहता था और अच्छी तरह से काम करना चाहता था, तो इन दो ट्यूटोरियल ने मदद की:

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

संपादित करें: क्षेत्रों वाली परियोजनाओं के लिए, आपको GetVirtualPath () विधि को संशोधित करना होगा:

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

9
GONeale लिंक बदल गया है; URL अब goneale.com/2008/12/19/lowercase-route-urls-in-aspnet-mvc
डैनियल

4
@ डेरेक - नहीं, क्षेत्र के उपयोग के दौरान ट्यूटोरियल टूट जाते हैं। EVERYTHING की कोशिश करने के 3 दिनों के बाद ... मुझे एक बेहतर समाधान मिला, एक पुस्तकालय को रूटिंग रूटिंग कहा जाता है। समस्या को हल करता है और जीवन को बहुत आसान बनाता है। philliphaydon.com/2011/08/…
Phill

6
पीवीसी 4 के लिए संपत्ति मार्गों का उपयोग करके एक बेहतर समाधान है। लोवरकेस यूआरएल = सच; अधिक जानकारी dhuvelle.com/2012/11/tips-for-aspnet-mvc-4-lowercase-urls.html
मार्क

4
@GONeale आपके URL का क्या हुआ? दूसरा लिंक अब मर चुका है! हालांकि मुझे हंसी आई, शीर्षक है "द बेस्ट गॉन एले साइट ऑन द इंटरनेट"
ल्यूक

2
@chteuchteu कि लिंक मेरे लिए काम नहीं किया, लेकिन यह एक किया था।
च्यू एक्स

22

आप ASP.NET कोर का उपयोग करने के लिए हुआ, तो आप शायद पर एक नजर है चाहिए इस :

निम्न ConfigureServicesविधि को Startupवर्ग की विधि में जोड़ें ।

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

1
कोर 2.0 के लिए भी। इसके अलावा stackoverflow.com/a/45777372/195755 पर
yzorg

21

यदि आप लिंक बनाने के लिए UrlHelper का उपयोग कर रहे हैं, तो आप बस लोअरकेस के रूप में कार्रवाई और नियंत्रक का नाम निर्दिष्ट कर सकते हैं:

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

में परिणाम: / मीडिया / तस्वीरें / हटाएं / 64 (भले ही मेरे नियंत्रक और कार्रवाई पास्कल मामला हो)।


16
मुझे लगता है कि एक केंद्रीय स्थान में यह काम करना सबसे आसान और सबसे मानक समाधान है। यह इनलाइन CSS जितना ही खराब है। (जाहिरा तौर पर 15 लोग इनलाइन CSS का उपयोग करते हैं)।
मफिन मैन

क्या यह लिनक्स सर्वरों के लिए भी सही है?
QMaster

15

मुझे निक बर्र्डी के कोडर जर्नल में यह मिला, लेकिन इसमें इस बात की जानकारी नहीं थी कि LowercaseRouteकक्षा को कैसे लागू किया जाए । इसलिए अतिरिक्त जानकारी के साथ यहां पर पुनर्स्थापना करें।

पहले Routeवर्ग का विस्तार करें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;
    }
}

फिर RegisterRoutesGlobal.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
    //);
}

लेकिन मैं मार्गों का उपयोग करने का एक तरीका जानना चाहूंगा। MapRoute ...


GONeale का लेख एक विस्तार विधि प्रदान करता है, ताकि आप लिख सकें routes.MapRouteLowercase(...कि ऊपर से कौन सा अच्छा है: goneale.wordpress.com/2008/12/19/…
Drew Noakes

1
गोनैले का पूरा ब्लॉग गायब हो गया। यहां समान सामग्री (और समान एक्सटेंशन विधि) के साथ एक और ब्लॉग प्रविष्टि है । यह डुप्लिकेट सामग्री को कम करने के संदर्भ में इस स्थिति को संबोधित करता है।
Patridge

11

आप इस वर्ग को रूट-कॉलेक्शन के विस्तार के रूप में जोड़कर MapRoute सिंटैक्स का उपयोग जारी रख सकते हैं:

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

अब आप "MapRoute" के बजाय अपने एप्लिकेशन के स्टार्टअप "MapRouteLowerCase" में उपयोग कर सकते हैं:

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

इसे पढ़ने वाले किसी के लिए, LowercaseRouteऊपर दिए गए पहले कोड स्निपेट में कक्षा इस अन्य उत्तर
chue x

6

इसके वास्तव में दो उत्तर हैं:

  1. आप पहले से ही ऐसा कर सकते हैं: मार्ग इंजन केस-असंवेदनशील तुलना करता है। यदि आप एक लोअर-केस रूट टाइप करते हैं, तो इसे उपयुक्त कंट्रोलर और एक्शन में भेजा जाएगा।
  2. यदि आप रूट लिंक (एक्शनलिंक, रूटलिंक, आदि) उत्पन्न करने वाले नियंत्रणों का उपयोग कर रहे हैं, तो वे मिश्रित-केस लिंक का उत्पादन करेंगे जब तक कि आप इस डिफ़ॉल्ट व्यवहार को ओवरराइड नहीं करते हैं।

आप अंडरस्कोर के लिए अपने दम पर हैं, हालांकि ...


2

क्या आप ActionName विशेषता का उपयोग कर सकते हैं?

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

 }

मुझे नहीं लगता कि मामला मायने रखता है। URL में More_Details, more_DET Colors, mOrE_DeTaIL आप सभी को एक ही कंट्रोलर एक्शन में ले जाते हैं।


मैंने कोशिश नहीं की है - क्या यह आपको एक का उपयोग करने देगा? ("मोरेडटेल" या "अधिक_डेट्स")
गेलेक्टिककोवेबॉय

अनुसरण करने के लिए, मैंने इसे आज़माया और इसके लिए आपको निर्दिष्ट नाम का उपयोग करने की आवश्यकता है, इसलिए नहीं, यह आपको इसे किसी भी तरह से संभालने की अनुमति नहीं देगा। इसके अलावा, आपने अपने नियंत्रक क्रिया और दृश्य का निर्माण कैसे किया है, इसके आधार पर, आपको स्पष्ट रूप से दृश्य का नाम निर्दिष्ट करने की आवश्यकता हो सकती है।
गैलेक्टीकॉवॉय
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.