मेरे पास दो एक्शन तरीके हैं जो परस्पर विरोधी हैं। मूल रूप से, मैं दो अलग-अलग मार्गों का उपयोग करके एक ही दृश्य के लिए सक्षम होना चाहता हूं, या तो आइटम की आईडी या आइटम के नाम से और उसके माता-पिता के आइटम (अलग-अलग माता-पिता के समान नाम हो सकते हैं)। सूची को फ़िल्टर करने के लिए एक खोज शब्द का उपयोग किया जा सकता है।
उदाहरण के लिए...
Items/{action}/ParentName/ItemName
Items/{action}/1234-4321-1234-4321
यहाँ मेरे एक्शन के तरीके हैं ( Remove
एक्शन के तरीके भी हैं ) ...
// Method #1
public ActionResult Assign(string parentName, string itemName) {
// Logic to retrieve item's ID here...
string itemId = ...;
return RedirectToAction("Assign", "Items", new { itemId });
}
// Method #2
public ActionResult Assign(string itemId, string searchTerm, int? page) { ... }
और यहाँ मार्ग हैं ...
routes.MapRoute("AssignRemove",
"Items/{action}/{itemId}",
new { controller = "Items" }
);
routes.MapRoute("AssignRemovePretty",
"Items/{action}/{parentName}/{itemName}",
new { controller = "Items" }
);
मैं समझता हूं कि त्रुटि क्यों हो रही है, चूंकि page
पैरामीटर अशक्त हो सकता है, लेकिन मैं इसे हल करने का सबसे अच्छा तरीका नहीं समझ सकता। क्या मेरा डिजाइन शुरू करने के लिए खराब है? मैंने Method #1
खोज मापदंडों को शामिल करने के लिए हस्ताक्षर के बारे में सोचा है और तर्क Method #2
को एक निजी पद्धति में स्थानांतरित करने के लिए कहा है जिसे वे दोनों कहेंगे, लेकिन मुझे विश्वास नहीं है कि वास्तव में अस्पष्टता का समाधान होगा।
किसी भी तरह की सहायता का स्वागत किया जाएगा।
वास्तविक समाधान (लेवी के उत्तर पर आधारित)
मैंने निम्न वर्ग जोड़ा है ...
public class RequireRouteValuesAttribute : ActionMethodSelectorAttribute {
public RequireRouteValuesAttribute(string[] valueNames) {
ValueNames = valueNames;
}
public override bool IsValidForRequest(ControllerContext controllerContext, MethodInfo methodInfo) {
bool contains = false;
foreach (var value in ValueNames) {
contains = controllerContext.RequestContext.RouteData.Values.ContainsKey(value);
if (!contains) break;
}
return contains;
}
public string[] ValueNames { get; private set; }
}
और फिर एक्शन के तरीकों को सजाया ...
[RequireRouteValues(new[] { "parentName", "itemName" })]
public ActionResult Assign(string parentName, string itemName) { ... }
[RequireRouteValues(new[] { "itemId" })]
public ActionResult Assign(string itemId) { ... }
return ValueNames.All(v => controllerContext.RequestContext.RouteData.Values.ContainsKey(v));
contains = ...
: इस तरह कुछ करने के लिए खंडcontains = controllerContext.RequestContext.RouteData.Values.ContainsKey(value) || controllerContext.RequestContext.HttpContext.Request.Params.AllKeys.Contains(value);
ActionResult DoSomething(Person p)
जहां Person
विभिन्न सरल गुण हैं जैसे Name
, और इसके लिए अनुरोध सीधे संपत्ति के नाम के साथ किए जाते हैं (जैसे, /dosomething/?name=joe+someone&other=properties
)।
controllerContext.HttpContext.Request[value] != null
इसके बजाय उपयोग करना चाहिए controllerContext.RequestContext.RouteData.Values.ContainsKey(value)
; लेकिन फिर भी काम का एक अच्छा टुकड़ा।