2011-08-04 5 views
29

मैं निम्न स्वरूप में किसी अन्य प्रणाली से एक URL लेने के लिए सेटअप करने के लिए कोशिश कर रहा हूँ MVC में एक कस्टम मार्ग:मैं ASP.NET MVC में क्वेरीस्ट्रिंग वाले URL को कैसे रूट करूं?

../ABC/ABC01?Key=123&Group=456

01 सेकंड एबीसी के बाद एक कदम संख्या इस बदल जाएगा और कुंजी है और समूह पैरामीटर बदल जाएगा। मुझे इसे नियंत्रक में एक क्रिया में चरण संख्या कुंजी और समूह को पैरामीटर के रूप में रूट करने की आवश्यकता है। मैं निम्नलिखित कोड का प्रयास किया है, लेकिन यह एक अपवाद फेंकता है:

कोड:

routes.MapRoute(
    "OpenCase", 
    "ABC/ABC{stepNo}?Key={key}&Group={group}", 
    new {controller = "ABC1", action = "OpenCase"} 
); 

अपवाद:

`The route URL cannot start with a '/' or '~' character and it cannot contain a '?' character.` 

उत्तर

35

आप मार्ग में क्वेरी स्ट्रिंग शामिल नहीं कर सकते। इस तरह एक मार्ग के साथ प्रयास करें:

routes.MapRoute("OpenCase", "ABC/ABC{stepNo}", 
    new { controller = "ABC1", action = "OpenCase" }); 

फिर, अपने नियंत्रक पर इस तरह की एक पद्धति जोड़ें:

public class ABC1 : Controller 
{ 
    public ActionResult OpenCase(string stepno, string key, string group) 
    { 
     // do stuff here 
     return View(); 
    }   
} 

ASP.NET MVC स्वचालित रूप में विधि में पैरामीटर के लिए क्वेरी स्ट्रिंग पैरामीटर मैप कर देंगे नियंत्रक।

4

जब मार्गों को परिभाषित करने के लिए, आप एक / मार्ग के प्रारंभ में उपयोग नहीं कर सकते:

routes.MapRoute("OpenCase", 
    "ABC/{controller}/{key}/{group}", 
    new { controller = "", action = "OpenCase" }, 
    new { key = @"\d+", group = @"\d+" } 
    ); 

फिर अपने कार्रवाई के रूप में देखना चाहिए इस प्रकार है::

public ActionResult OpenCase(int key, int group) 
{ 
    //do stuff here 
} 

routes.MapRoute("OpenCase", 
    "/ABC/{controller}/{key}/{group}", <-- Bad; see/at beginning 
    new { controller = "", action = "OpenCase" }, 
    new { key = @"\d+", group = @"\d+" } 
    ); 

routes.MapRoute("OpenCase", 
    "ABC/{controller}/{key}/{group}", <-- Good; No/at beginning 
    new { controller = "", action = "OpenCase" }, 
    new { key = @"\d+", group = @"\d+" } 
    ); 

इस प्रयास करें

ऐसा लगता है कि आप stepNo और " एबीसी "एक नियंत्रक प्राप्त करने के लिए जो ABC1 है। यही कारण है कि मैंने यूआरएल के उस खंड को {controller} के साथ बदल दिया।

चूंकि आपके पास एक मार्ग भी है जो 'कुंजी' और 'समूह' को परिभाषित करता है, उपर्युक्त मार्ग आपके प्रारंभिक यूआरएल को भी पकड़ लेगा और इसे क्रिया में भेज देगा।

1

नई एएसपी.नेट एमवीसी परियोजना में क्वेरीस्ट्रिंग में आधारित रूटिंग का उपयोग करने का कोई कारण नहीं है। यह पुराने प्रोजेक्ट के लिए उपयोगी हो सकता है जिसे क्लासिक एएसपी.नेट परियोजना से परिवर्तित कर दिया गया है और आप यूआरएल को संरक्षित करना चाहते हैं।

एक समाधान विशेषता रूटिंग हो सकता है।

एक अन्य समाधान RouteBase से पाने से कस्टम मार्ग writting में हो सकता है:

public class MyOldClassicAspRouting : RouteBase 
{ 

    public override RouteData GetRouteData(HttpContextBase httpContext) 
    { 
    if (httpContext.Request.Headers == null) //for unittest 
     return null; 

    var queryString = httpContext.Request.QueryString; 

    //add your logic here based on querystring 
    RouteData routeData = new RouteData(this, new MvcRouteHandler()); 
    routeData.Values.Add("controller", "..."); 
    routeData.Values.Add("action", "..."); 
    } 

    public override VirtualPathData GetVirtualPath(RequestContext requestContext, RouteValueDictionary values) 
    { 
    //Implement your formating Url formating here 
    return null; 
    } 
} 

और अपने कस्टम मार्ग वर्ग रजिस्टर

public static void RegisterRoutes(RouteCollection routes) 
{ 
    ... 

    routes.Add(new MyOldClassicAspRouting()); 
} 
0

क्वेरी स्ट्रिंग तर्क आम तौर पर उस नियंत्रक की और उस के लिए विशिष्ट हैं विशिष्ट अनुप्रयोग तर्क।

तो यह बेहतर होगा अगर यह रूट नियमों में लिखा नहीं गया है, जो सामान्य हैं।

आप निम्न तरीके से कार्रवाई तर्क पर क्वेरी स्ट्रिंग का पता लगा सकते हैं।

मुझे लगता है कि StepNo को संभालने के लिए एक नियंत्रक होना बेहतर है।

public class ABC : Controller 
{ 
    public ActionResult OpenCase(OpenCaseArguments arg) 
    { 
     // do stuff here 
     // use arg.StepNo, arg.Key and arg.Group as You need 
     return View(); 
    }   
} 

public class OpenCaseArguments 
{ 
    private string _id; 
    public string id 
    { 
     get 
     { 
      return _id; 
     } 

     set 
     { 
      _id = value; // keep original value; 
      ParseQueryString(value); 
     } 
    } 

    public string StepNo { get; set; } 
    public string Key { get; set; } 
    public string Group { get; set; } 

    private void ParseQueryString(string qs) 
    { 
     var n = qs.IndexOf('?'); 
     if (n < 0) return; 
     StepNo = qs.Substring(0, n); // extract the first part eg. {stepNo} 
     NameValueCollection parms = HttpUtility.ParseQueryString(qs.Substring(n + 1)); 
     if (parms.Get("Key") != null) Key = parms.Get("Key"); 
     if (parms.Get("Group") != null) Group = parms.Get("Group"); 
    } 

} 

मॉडलबिंडर OpenCaseArguments के आईडी फ़ील्ड को {id} मान असाइन करें। सेट विधि क्वेरीस्ट्रिंग स्प्लिट तर्क संभालती है।

और इस तरह से रूटिंग रखें। नोट रूटिंग आईडी क्वेरी में अपनी क्वेरीस्ट्रिंग प्राप्त करें।

routes.MapRoute(
    "OpenCase", 
    "ABC/OpenCase/{id}", 
    new {controller = "ABC", action = "OpenCase"} 
); 

मैंने नियंत्रक कार्रवाई पर एकाधिक फ़ील्ड कुंजी मान प्राप्त करने के लिए इस विधि का उपयोग किया है।

+0

ध्यान दें कि एमवीसी स्वचालित रूप से क्वेरी क्वेरी को 'QueryStringValueProvider' के साथ पार करती है। इन मानों को क्रिया विधि में प्राप्त करने के लिए आपको केवल इतना करना है कि क्वेरी स्ट्रिंग कुंजियों के रूप में समान विधि वाले पैरामीटर को क्रिया विधि या मॉडल में जोड़ना है। इसके लिए अपना स्वयं का क्वेरी स्ट्रिंग पार्सर बनाने की आवश्यकता नहीं है। – NightOwl888

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