2008-12-18 20 views
31

यहां मेरा परिदृश्य है। उदाहरण के लिए कहें कि मुझे खोज मानदंडों के आधार पर कारों की एक सूची वापस करने की आवश्यकता है। मैं परिणामों को प्रदर्शित करने के लिए एक ही दृश्य देखना चाहता हूं क्योंकि आउटपुट वही होगा, लेकिन मुझे वहां जाने के कई तरीकों की आवश्यकता है। उदाहरण के लिए, मेरे पास वर्ष के अनुसार खोज करने के लिए टेक्स्टबॉक्स वाला एक फॉर्म हो सकता है। मेरे पास एक और अलग पृष्ठ हो सकता है जिसमें सभी लाल, टोयोटा कारों के लिए हाइपरलिंक हो। मैं इन दृश्यों और नियंत्रक में इन एकाधिक परिदृश्यों को कैसे संभाल सकता हूं। मेरी दुविधा यह है कि खोज में कई विकल्प हो सकते हैं ... वर्ष, बनाना, मॉडल, आदि, लेकिन मुझे नहीं पता कि उन्हें कहां रखा जाए।खोज के लिए एएसपी.नेट एमवीसी कस्टम रूटिंग

इसके लिए सबसे अच्छा तरीका क्या है? क्या मुझे रूटिंग में पैरामीटर को परिभाषित करना चाहिए या क्वेरी स्ट्रिंग्स आदि के साथ जाना चाहिए?

उत्तर

78

विकल्प 1

बेशक

आप हमेशा की/कार/खोज /? विक्रेता = टोयोटा & रंग = लाल & मॉडल = रास्ता Corola और मुझे लगता है कि यह आप के लिए अच्छा होगा चुन सकते हैं ।

routes.MapRoute(
    "CarSearch", 
    "car/search", 
    new { controller = "car", action = "search" } 
); 

आप इस मामले में अनुरोध में अनुरोध से पैराम प्राप्त कर सकते हैं।

विकल्प 2

या आप अनुमार्गण तालिका में पैरामीटर परिभाषित कर सकते हैं, लेकिन AFAIK यह, सभी संभव संयोजनों के लिए नियमों का एक सेट बनाने के लिए आवश्यक हो जाएगा क्योंकि पैरामीटर के आदेश बात है, उदाहरण के लिए:

 routes.MapRoute(
      "CarSearch1", 
      "car/search/vendor/{vendor}/color/{color}/model/{model}", 
      new {controller = "car", action = "search"} 
     ); 

     routes.MapRoute(
      "CarSearch2", 
      "car/search/color/{color}/vendor/{vendor}/model/{model}", 
      new {controller = "car", action = "search"} 
     ); 

     routes.MapRoute(
      "CarSearch3", 
      "car/search/model/{model}/color/{color}/vendor/{vendor}", 
      new {controller = "car", action = "search"} 
     ); 

... एक बहुत कुछ। यह सच है यदि आप मानक MvcRouteHandler के साथ जा रहे हैं।

किंतु ऐसा इस लिए एक आसान तरीके :)

विकल्प 3

मुश्किल है, लेकिन, मुझे लगता है, सबसे खूबसूरत तरीका है, अपने स्वयं के IRouteHandler कार्यान्वयन सुनिश्चित करने के लिए है - यह आप दे देंगे और अधिक पैराम क्रम में लचीलापन। लेकिन फिर, यह एक कठिन तरीका है, यदि आपके पास एक साधारण ऐप है तो इसके साथ न जाएं। तो, कितना यह इस तरह से (बहुत ही सरल उदाहरण) बनाने के लिए की उदाहरण के लिए:

routes.Add 
    (
     new Route 
      (
       "car/search/{*data}", 
       new RouteValueDictionary(new {controller = "car", action = "search", data = ""}), 
       new MyRouteHandler() 
      ) 
    ); 

वर्गों है कि मानक अनुरोध संसाधन श्रृंखला ट्वीक करेगा जोड़ें:

मार्गों की सूची में नया मार्ग जोड़ें:

class MyRouteHandler : IRouteHandler 
{ 
    public IHttpHandler GetHttpHandler(RequestContext requestContext) 
    { 
     return new MyHttpHandler(requestContext); 
    } 
} 

class MyHttpHandler : MvcHandler 
{ 
    public MyHttpHandler(RequestContext requestContext) : base(requestContext) 
    { 
    } 

    protected override void ProcessRequest(HttpContextBase httpContext) 
    { 
     IController controller = new CarController(); 
     (controller as Controller).ActionInvoker = new MyActionInvoker(); 
     controller.Execute(RequestContext); 
    } 
} 

class MyActionInvoker : ControllerActionInvoker 
{ 
    protected override ActionResult InvokeActionMethod(MethodInfo methodInfo, IDictionary<string, object> parameters) 
    { 
     // if form of model/{model}/color/{color}/vendor/{vendor} 
     var data = ControllerContext.RouteData.GetRequiredString("data"); 
     var tokens = data.Split('/'); 

     var searchParams = new Dictionary<string, string>(); 
     for (var i = 0; i < tokens.Length; i++) 
     { 
      searchParams.Add(tokens[i], tokens[++i]); 
     } 

     parameters["searchParams"] = searchParams; 

     return base.InvokeActionMethod(methodInfo, parameters); 
    } 
} 

नियंत्रक में:

public ActionResult Search(IDictionary<string, string> searchParams) 
{ 
    ViewData.Add 
     (
      // output 'model = Corola, color = red, vendor = Toyota' 
      "SearchParams", 
      string.Join(", ", searchParams.Select(pair => pair.Key + " = " + pair.Value).ToArray()) 
     ); 
    return View(); 
} 

और यह होगा किसी भी खोज पैरामीटर आज़माना आदेश:

/car/search/vendor/Toyota/color/red/model/Corola 
/car/search/color/red/model/Corola/vendor/Toyota 
/car/search/model/Corola/color/red/vendor/Toyota 

लेकिन भी एक लिंक पीढ़ी तर्क करना भूल जाते हैं न क्योंकि Html.ActionLink और Html.RenderLink आप की/कार/खोज/मॉडल/Corola सुंदर रूप में यूआरएल नहीं देंगे/रंग/लाल/विक्रेता/टोयोटा, तो आपको एक कस्टम लिंक जनरेटर बनाना होगा।

तो, यदि आपको वास्तव में लचीली रूटिंग की आवश्यकता है - तो आप बेहतर तरीके से इस कठिन तरीके से जाना चाहेंगे :)

+0

से आते हैं, मुझे लगता है कि इस समय मेरी सबसे अच्छी कार्रवाई का विकल्प विकल्प 1 होगा। विकल्प 2 जिस तरह से मैंने शुरुआत में नेतृत्व किया था, लेकिन ऐसा लगता है कि सभी संभावित रूटिंग संयोजनों को रखना अक्षम है। विकल्प 3 बाद में अच्छा लगता है अगर मैं रिफैक्टर करना चाहता हूं, लेकिन एक एमवीसी एनओयूबी होने के नाते मैं आसान मार्ग के साथ रहूंगा। –

+0

उत्कृष्ट जवाब! @Eric – AnthonyWJones

+0

को अपनाने के लिए मत भूलना धन्यवाद, एंथनी :) – maxnk

0

नियंत्रक पर प्रत्येक विधि (क्रिया) विभिन्न मानकों को ले लेगी, लेकिन खोज परिणामों का एक ही संग्रह बनायेगी। फिर, प्रत्येक

return View("SearchResult", searchResultCollection); 

वे सभी एक ही दृश्य, SearchResult.aspx का उपयोग करते हैं।

0

इन पंक्तियों के साथ कुछ करना चाहिए जो आप कर रहे हैं। ध्यान दें कि दो अलग-अलग क्रिया विधियां कैसे हैं, लेकिन उनमें से दोनों DisplayResults() पर एक कॉल वापस लौटते हैं - इसलिए वे अलग-अलग व्यूडेटा के साथ एक ही दृश्य का उपयोग कर समाप्त होते हैं।

public class SearchController : Controller { 

    public ActionResult ByColor(Color[] colors) { 
     List<Car> results = carRepository.FindByColor(colors); 
     return(DisplayResults(result)); 
    } 

    public ActionResult ByMake(string make) { 
     List<Car> results = carRepository.FindByMake(make); 
     return(DisplayResults(results)); 
    } 

    private ActionResult DisplayResults(IList<Car> results) { 

     // Here we explicitly return the view /Views/Search/Results.aspx 
     // by specifying the view name in the call to View(); 
     return(View("Results", results)); 
    } 
} 
+0

धन्यवाद। आपका उदाहरण यह है कि मेरी सोच कैसे शुरू हुई, लेकिन मुझे लगता है कि एमवीसी रूटिंग के लिए मेरी समझ की कमी ने मुझे स्टंप किया। मैं केवल कुछ दिनों के लिए इसे देख रहा हूं। आप ActionResult में रंगों का ऐरे कैसे पारित करेंगे। मेरी समझ यह है कि ये पैरा यूआरएल –

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