ASP.NET MVC में "क्लासिक" फ्रेंडली url

छवि
यह विषय ASP.NET MVC एप्लिकेशन में www.site.com/helloworld जैसे लिंक बनाने के तरीके पर ध्यान केंद्रित करेगा। मैंने सुना है कि विस्मयादिबोधक उद्घोषणा "यह आवश्यक क्यों है?" और "आप सामान्य मानव मार्ग के साथ सहज क्यों नहीं हैं?" और मेरे पास इस विषय पर एक उत्तर है।

तथ्य यह है कि हमारी परियोजना वेब फॉर्म के साथ एमवीसी के लिए आगे बढ़ रही है, और प्रासंगिक विज्ञापन लंबे समय से भुगतान किए गए हैं। रूटिंग एक महान बात है, हालांकि, यह देखते हुए कि साइट केवल लैंडिंग पृष्ठों के बारे में नहीं है, हम इसे इतने चालाक तरीके से ट्यून नहीं कर सकते हैं कि नियमित रूप से एमवीसी-लिंक / कंट्रोलर / एक्शन और हमारे अविश्वसनीय रूप से अनुकूल यूआरएल काम करते रहें। कारण सरल है: डिफ़ॉल्ट रूटिंग ( "{controller}/{action}/{id}", new { controller = "Default", action = "Index", id = UrlParameter.Optional } ) डिफॉल्ट मानों को मानता है, इसलिए www.site.com/helloworld हमें एक्शन इंडेक्स में हेलोवर्ल्ड नियंत्रक में स्थानांतरित करने का प्रयास करेगा।
उदासी।
कुछ करना पड़ेगा। इसके अलावा, प्रत्येक लिंक के लिए एक नियंत्रक बनाने का विकल्प स्पष्ट रूप से हमें सूट नहीं करता है - उनका अंधेरा, और सामान्य तौर पर यह अश्लील साहित्य है, है ना?

हम दूसरे रास्ते से जाएंगे। ©


संकल्पना


हम एक राउटर पर एक हैंडलर लगाएंगे जो मित्रता के लिए लिंक की जांच करेगा - इसके लिए हम नियमित अभिव्यक्ति का उपयोग करेंगे।
यदि लिंक MVC-shnaya है - बस जारी रखें, बिना अनावश्यक इशारे किए।
यदि लिंक किसी विशिष्ट MVC लिंक की तरह नहीं दिखता है, तो हम डेटाबेस में एक मैच के लिए देखने की कोशिश करेंगे - जो नियंत्रक और कार्रवाई का उपयोग करने के लिए।
यदि हमें कुछ नहीं मिला, तो मानक रूटिंग और डिफ़ॉल्ट मानों का उपयोग करने का प्रयास करें। पहले से ही 404 हैं, इसलिए 404 हैं।


आदर्श


छवि

इतना सरल और सरल। ContentID यहाँ विदेशी कुंजी है, हालाँकि, यदि आप चाहें, तो आप VARCHAR (MAX) का उपयोग कर सकते हैं और सामग्री को यहाँ लिख सकते हैं। इस तथ्य के कारण हमारे पास ऐसा कार्यान्वयन है कि सामग्री को टुकड़ों में विभाजित किया गया है (मुख्य सामग्री, शीर्षक, मेटा विवरण टैग ...) - एसईओ, आप समझते हैं।


कार्यान्वयन


कार्यान्वयन का आधार यह है:
 routes.MapRoute( "Default", "{controller}/{action}/{id}", new { controller = "Default", action = "Index", id = UrlParameter.Optional } ).RouteHandler = new FriendlyUrlRouteHandler(); 

हम अपने राउटर (MvcRouteHandler के वंशज) के लिए एक हैंडलर संलग्न करते हैं, जो तैयार मूल्यों को संसाधित करता है। यही है, पहले, रूटिंग तंत्र लिंक का पता लगाएगा, डिफ़ॉल्ट मानों को भरें, फिर हम व्यवसाय में पहुंच जाएंगे और यदि आवश्यक हो, तो मूल्यों को हमारे साथ बदलें।

  public class FriendlyUrlRouteHandler : MvcRouteHandler { private static readonly Regex TypicalLink = new Regex("^.+/.+(/.*)?"); protected override IHttpHandler GetHttpHandler(RequestContext requestContext) { // Path  www.site.com/helloworld?id=1   /helloworld //      var url = requestContext.HttpContext.Request.Path.TrimStart('/'); if (!string.IsNullOrEmpty(url) && !TypicalLink.IsMatch(url)) { PageItem page = RedirectManager.GetPageByFriendlyUrl(url); if (page != null) { FillRequest(page.ControllerName, page.ActionName ?? "GetStatic", page.ID.ToString(), requestContext); } } return base.GetHttpHandler(requestContext); } /// <summary>  request-   ,    </summary> private static void FillRequest(string controller, string action, string id, RequestContext requestContext) { if (requestContext == null) { throw new ArgumentNullException("requestContext"); } requestContext.RouteData.Values["controller"] = controller; requestContext.RouteData.Values["action"] = action; requestContext.RouteData.Values["id"] = id; } } 


मैं एक पैरामीटर के रूप में रिकॉर्ड आईडी का उपयोग करता हूं, और पेज लोड करते समय मैं एक दृश्य का उपयोग करता हूं, जिसमें कई टेबल शामिल होते हैं। यदि आपको ऐसी परेशानियों की आवश्यकता नहीं है, तो आप बस पैरामीटर ContentID के रूप में पास कर सकते हैं, न कि पूरे रिकॉर्ड की आईडी।

डिफ़ॉल्ट क्रिया GetStatic है, जिसे नियंत्रकों के लिए हमारे आधार वर्ग में आभासी के रूप में परिभाषित किया गया है। एक विशिष्ट नियंत्रक में, वह डेटाबेस से पृष्ठ का पाठ लेता है, और अनुभाग की विशेषताओं और लेआउट को ध्यान में रखते हुए एक पृष्ठ बनाता है।
  public abstract class BaseController : Controller { /// <summary>     </summary> public virtual ActionResult GetStatic(int id) { return HttpNotFound(); } } 


और अंत में, पुनर्निर्देशित तंत्र ही। सच कहूं, तो मुझे याद नहीं है कि मैं उसे एक अलग वर्ग में क्यों ले गया। दूसरी ओर, क्यों नहीं।
  public static class RedirectManager { public static PageItem GetPageByFriendlyUrl(string friendlyUrl) { PageItem page = null; using (var cmd = new SqlCommand()) { cmd.Connection = new SqlConnection(/*YourConnectionString*/); cmd.CommandText = "select * from FriendlyUrl where FriendlyUrl = @FriendlyUrl"; cmd.Parameters.Add("@FriendlyUrl", SqlDbType.NVarChar).Value = friendlyUrl.TrimEnd('/'); cmd.Connection.Open(); using (var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection)) { if (reader.Read()) { page = new PageItem { ID = (int) reader["Id"], ControllerName = (string) reader["ControllerName"], ActionName = (string) reader["ActionName"], FriendlyUrl = (string) reader["FriendlyUrl"], }; } } return page; } } } 



परिणाम


अंत में, हमें वही मिला, जिसके लिए हम प्रयास कर रहे थे। डेटाबेस में भरने के बाद, हमें सही पृष्ठों पर पुनर्निर्देशित किया गया, और पता बार में कुछ भी नहीं बदला, और हमें अतिरिक्त नृत्य के बिना 200 ओके मिले।

बेशक, स्थिति काफी अनैतिक है - ज्यादातर मामलों में, मानक रूटिंग पर्याप्त से अधिक है: आप एक नियंत्रक बना सकते हैं, उदाहरण के लिए, स्टेटिक, जो URL का उपयोग करके डेटाबेस से डेटा भी लेगा। लेकिन अगर प्रासंगिक विज्ञापन पहले से ही भुगतान किया गया है, या केवल लिंक बनाने की एक जंगली इच्छा है जिसमें एक भी अतिरिक्त स्लैश नहीं है, तो वर्णित विकल्प, मेरी राय में, बहुत उपयुक्त है।

अंत में, हमने कार्य निर्धारित किया, और सफलतापूर्वक इसके साथ मुकाबला किया।
मेरी राय में, यह अच्छा है।

Source: https://habr.com/ru/post/In132799/


All Articles