Saya memiliki dua metode tindakan yang saling bertentangan. Pada dasarnya, saya ingin bisa mendapatkan tampilan yang sama menggunakan dua rute berbeda, baik dengan ID item atau dengan nama item dan induknya (item dapat memiliki nama yang sama di antara orang tua yang berbeda). Istilah pencarian dapat digunakan untuk memfilter daftar.
Sebagai contoh...
Items/{action}/ParentName/ItemName
Items/{action}/1234-4321-1234-4321
Berikut adalah metode tindakan saya (ada juga Remove
metode tindakan) ...
// 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) { ... }
Dan inilah rutenya ...
routes.MapRoute("AssignRemove",
"Items/{action}/{itemId}",
new { controller = "Items" }
);
routes.MapRoute("AssignRemovePretty",
"Items/{action}/{parentName}/{itemName}",
new { controller = "Items" }
);
Saya mengerti mengapa kesalahan terjadi, karena page
parameternya bisa nol, tetapi saya tidak tahu cara terbaik untuk mengatasinya. Apakah desain saya awalnya buruk? Saya telah berpikir tentang memperluas Method #1
tanda tangan untuk menyertakan parameter pencarian dan memindahkan logika Method #2
ke metode pribadi yang akan mereka panggil, tetapi saya tidak percaya itu benar-benar akan menyelesaikan ambiguitas.
Bantuan apa pun akan sangat dihargai.
Solusi Aktual (berdasarkan jawaban Levi's)
Saya menambahkan kelas berikut ...
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; }
}
Dan kemudian mendekorasi metode tindakan ...
[RequireRouteValues(new[] { "parentName", "itemName" })]
public ActionResult Assign(string parentName, string itemName) { ... }
[RequireRouteValues(new[] { "itemId" })]
public ActionResult Assign(string itemId) { ... }