2009-10-28 17 views
12

मैंने देखा कि एमवीसी 2 पूर्वावलोकन 2 में, क्षेत्रीय पंजीकरण प्रत्येक क्षेत्र के लिए मनमाने ढंग से क्रम में मार्ग लोड कर रहा है। क्या एक दूसरे से पहले पाने का कोई अच्छा तरीका है?एमवीसी 2 क्षेत्र पंजीकरण पंजीकरण आदेश

उदाहरण के लिए, मेरे पास दो क्षेत्र हैं - "साइट" और "व्यवस्थापक"। दोनों में "ब्लॉग" नियंत्रक है।

मैं निम्नलिखित चाहते हैं:

/admin/ --> go to Admin's Blog controller 
/  --> go to Site's Blog controller. 

समस्या यह है कि साइट के मार्ग पहले लोड कर रहा है है, इसलिए यह admin/{controller}/{action}/{id} के बजाय {controller}/{action}/{id} मिलान किया जाता है जब मैं यूआरएल "/ व्यवस्थापक /" पर जाएं। मुझे फिर 404 मिलते हैं, क्योंकि "साइट" क्षेत्र में कोई व्यवस्थापक नियंत्रक नहीं है।

दोनों क्षेत्रों "ब्लॉग" नियंत्रक के लिए डिफ़ॉल्ट हैं। मुझे एहसास है कि मैं यूआरएल के रूप में site/{controller}/... डाल सकता हूं, लेकिन यदि संभव हो तो मैं इसे रूट पर रखूंगा। मैंने वैश्विक रजिस्टर रूट फ़ंक्शन में डिफ़ॉल्ट मार्ग रखने का भी प्रयास किया, हालांकि, इसे "साइट्स" क्षेत्र में नहीं भेजा गया है।

अग्रिम धन्यवाद!

उत्तर

7

वर्तमान में क्षेत्रों को ऑर्डर करना संभव नहीं है। हालांकि, मुझे लगता है कि यह संभव है कि प्रत्येक क्षेत्र को अन्य क्षेत्रों से जितना संभव हो सके स्वतंत्र करने की कोशिश करें ताकि आदेश कोई फर्क नहीं पड़ता।

उदाहरण के लिए, डिफ़ॉल्ट {नियंत्रक}/{action}/{id} मार्ग होने की बजाय, शायद प्रत्येक नियंत्रक के लिए विशिष्ट मार्गों के साथ इसे प्रतिस्थापित करें। या उस डिफ़ॉल्ट मार्ग पर एक बाधा जोड़ें।

हम आदेश देने की अनुमति देने के लिए विकल्पों पर उलझ रहे हैं, लेकिन हम इस सुविधा को अधिक जटिल नहीं करना चाहते हैं।

+0

अरे फिल, स्पष्टीकरण के लिए धन्यवाद। मैंने अपनी "साइट" को क्षेत्र से बाहर ले जाना समाप्त कर दिया और अब यह "डिफ़ॉल्ट/गैर-क्षेत्र" अनुभाग (दृश्यों और नियंत्रकों के साथ रूट में) है। मैं फिर "अस्पष्ट नियंत्रक" त्रुटि से बचने के लिए अपने नेमस्पेस पैरामीटर को डिफ़ॉल्ट नियंत्रकों पर सेट करता हूं। इसके अलावा, मैं शायद साइट क्षेत्र के मार्गों में व्यवस्थापक को अनदेखा करने के लिए^((?! admin)। *) जैसी बाधाओं को सेट कर सकता था। मैं सहमत हूं, और अधिक जटिलता जोड़ना बहुत अच्छा नहीं है, हालांकि ऐसा लगता है कि एमवीसी 1 (गैर क्षेत्र) मार्ग संभावित रूप से क्रमशः भारी निर्भर हो सकते हैं। धन्यवाद! – Jason

+0

रूटिंग प्रक्रिया आम तौर पर नियमों के आदेश पर निर्भर करती है, इसलिए 'ऑर्डरिंग' सुविधा महत्वपूर्ण हो सकती है। – twk

+0

कृपया दो तकनीकों के लिए मेरी प्रतिक्रिया देखें जो आपको किसी भी क्रम में क्षेत्र पंजीकरण (और इस प्रकार उनके मार्ग) का ऑर्डर करने की अनुमति देती हैं। – Eilon

30

हैकड ने जो कहा, उसके अलावा क्षेत्रीय पंजीकरण (और इस प्रकार उनके मार्ग) को आदेश देना बहुत संभव है। आपको बस इतना करना है कि आप जो भी ऑर्डर चाहते हैं, मैन्युअल रूप से प्रत्येक क्षेत्र को पंजीकृत करें। यह RegisterAllAreas() को कॉल करने के रूप में चिकना नहीं है लेकिन यह निश्चित रूप से करने योग्य है।

protected void Application_Start() { 
    var area1reg = new Area1AreaRegistration(); 
    var area1context = new AreaRegistrationContext(area1reg.AreaName, RouteTable.Routes); 
    area1reg.RegisterArea(area1context); 

    var area2reg = new Area2AreaRegistration(); 
    var area2context = new AreaRegistrationContext(area2reg.AreaName, RouteTable.Routes); 
    area2reg.RegisterArea(area2context); 

    var area3reg = new Area3AreaRegistration(); 
    var area3context = new AreaRegistrationContext(area3reg.AreaName, RouteTable.Routes); 
    area3reg.RegisterArea(area3context); 
} 

एक अन्य विकल्प, RegisterAllAreas के लिए कोड() ले अपनी ऐप्लिकेशन में कॉपी, और आदेश निर्धारित करने के लिए अपने स्वयं के तंत्र का निर्माण करना है। यह प्रतिलिपि बनाने के लिए कोड का एक छोटा सा कोड है यदि आप सभी फैंसी कैशिंग तर्क चाहते हैं कि अंतर्निहित विधि करता है, लेकिन आपके ऐप को इसकी आवश्यकता भी नहीं हो सकती है।

AreaUtils.cs

using System; 
    using System.Web.Mvc; 
    using System.Web.Routing; 

    namespace SledgeHammer.Mvc.Site 
    { 
     public static class Utils 
     { 
       public static void RegisterArea<T>(RouteCollection routes, 
    object state) where T : AreaRegistration 

      { 
       AreaRegistration registration = 
    (AreaRegistration)Activator.CreateInstance(typeof(T)); 

        AreaRegistrationContext context = 
    new AreaRegistrationContext(registration.AreaName, routes, state); 

        string tNamespace = registration.GetType().Namespace; 
        if (tNamespace != null) 
       { 
        context.Namespaces.Add(tNamespace + ".*"); 
       } 

       registration.RegisterArea(context); 
      } 
     } 

    } 

Global.asax में:

Utils.RegisterArea<SystemAreaRegistration>(RouteTable.Routes, null); 
Utils.RegisterArea<ClientSitesAreaRegistration>(RouteTable.Routes, null); 

//AreaRegistration.RegisterAllAreas(); do not dublicate register areas 

उत्पन्न क्षेत्र पंजीकरण कोड में कोई requred परिवर्तन

+0

ग्रेट उत्तर। इसके अलावा, यदि आप कोई विधि बनाते हैं तो कम कोड और फिर यह प्रति क्षेत्र कोड की एक पंक्ति है। – CRice

4

मैं इस समाधान कर सकते हैं। मैं अनुरोध में डोमेन के प्रकार (सिस्टम डोमेन या उपयोगकर्ता साइट) द्वारा रूट फ़िल्टर करने के लिए मार्गों में कस्टम स्थिरांक का भी उपयोग करता हूं।

इस उदाहरण के रूप में अपने क्षेत्र पंजीकरण है:

namespace SledgeHammer.MVC.Site.Areas.System 
{ 
    public class SystemAreaRegistration : AreaRegistration 
    { 
     public override string AreaName 
     { 
      get { return "System"; } 
     } 

     public override void RegisterArea(AreaRegistrationContext context) 
     { 
      context.MapRoute(
       "System_Feedback", 
       "Feedback", 
       new { controller = "Feedback", action = "Index" } 
      ); 
      context.MapRoute(
       "System_Information", 
       "Information/{action}/{id}", 
       new { controller = "Information", action = "Index", id = UrlParameter.Optional } 
      ); 
     } 
    } 
} 



namespace SledgeHammer.MVC.Site.Areas.ClientSites 
{ 
    public class ClientSitesAreaRegistration : AreaRegistration 
    { 
     public override string AreaName 
     { 
      get { return "ClientSites"; } 
     } 

     public override void RegisterArea(AreaRegistrationContext context) 
     { 
      context.MapRoute(
       "ClientSites_default", 
       "{controller}/{action}/{id}", 
       new { controller = "Site", action = "Index", id = UrlParameter.Optional }, 
       new { Host = new SiteInGroups("clients") } 
      ); 
     } 
    } 
} 
+0

आपकी उपयोग कक्षा बहुत बढ़िया है क्योंकि यह बताती है कि आपको क्षेत्रों के लिए नामस्थान जोड़ने की आवश्यकता है अन्यथा राउटर नियंत्रकों से जुड़े नहीं होंगे –

4

संदर्भ के लिए,

MVC3 (MVC2 के बारे में पता नहीं है) जब तुम सिर्फ एक विशेष क्षेत्र/आप नियंत्रक के लिए रूट मैप करना चाहते हैं में बस एक वैश्विक मार्ग का उपयोग कर सकते हैं। बस नामस्थान/क्षेत्र निर्दिष्ट करना याद रखें।

routes.MapRoute(
     "CatchRoot", "", 
     new { controller = "SITEBLOG-CONTROLLER-NAME", action = "Index"} 
    ).DataTokens.Add("area", "SITE-AREA-NAME"); 
+0

+1 - यह एक अच्छा समाधान है क्योंकि यह सब कुछ क्षेत्रों में समूहित करने की अनुमति देता है लेकिन एक एक क्लीनर यूआरएल के साथ कैच-सब के रूप में सेवा करने के लिए क्षेत्र। –

+0

पूरी तरह से काम करता है! मुझे 'विशेष एक' और वास्तविक क्षेत्रों के बजाय क्षेत्रों में सभी नियंत्रकों की अनुमति देता है। किसी को भी वांछित करने के लिए, रूट कॉन्फ़िगरेशन में डिफ़ॉल्ट मार्ग पंजीकृत करें। – FDIM

संबंधित मुद्दे