Wieloznaczne metody działania ASP.NET MVC

Mam dwie sprzeczne metody działania. Zasadniczo chcę być w stanie dostać się do tego samego widoku za pomocą dwóch różnych tras, albo przez identyfikator przedmiotu, albo przez nazwę przedmiotu i jego rodziców (przedmioty mogą mieć tę samą nazwę dla różnych rodziców). Wyszukiwanego terminu można użyć do filtrowania listy.

Na przykład...

<code>Items/{action}/ParentName/ItemName
Items/{action}/1234-4321-1234-4321
</code>

Oto moje metody działania (są teżRemove metody akcji) ...

<code>// 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) { ... }
</code>

A oto trasy ...

<code>routes.MapRoute("AssignRemove",
                "Items/{action}/{itemId}",
                new { controller = "Items" }
                );

routes.MapRoute("AssignRemovePretty",
                "Items/{action}/{parentName}/{itemName}",
                new { controller = "Items" }
                );
</code>

Rozumiem, dlaczego błąd występuje, ponieważpage parametr może mieć wartość NULL, ale nie mogę znaleźć najlepszego sposobu na jego rozwiązanie. Czy mój projekt jest kiepski? Myślałem o przedłużeniuMethod #1podpis do uwzględnienia parametrów wyszukiwania i przeniesienia logikiMethod #2 do prywatnej metody, którą oboje dzwoniliby, ale nie wierzę, że to rzeczywiście rozwiąże dwuznaczność.

Każda pomoc byłaby bardzo mile widziana.

Rzeczywiste rozwiązanie (na podstawie odpowiedzi Levi'ego)

Dodałem następującą klasę ...

<code>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; }
}
</code>

A następnie udekorował metody działania ...

<code>[RequireRouteValues(new[] { "parentName", "itemName" })]
public ActionResult Assign(string parentName, string itemName) { ... }

[RequireRouteValues(new[] { "itemId" })]
public ActionResult Assign(string itemId) { ... }
</code>

questionAnswers(5)

yourAnswerToTheQuestion