ASP.NET MVC métodos de acción ambiguos

Tengo dos métodos de acción que son conflictivos. Básicamente, quiero poder llegar a la misma vista usando dos rutas diferentes, ya sea por la identificación de un artículo o por el nombre del artículo y el de su padre (los artículos pueden tener el mismo nombre en diferentes padres). Se puede utilizar un término de búsqueda para filtrar la lista.

Por ejemplo...

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

Aquí están mis métodos de acción (también hayRemove métodos de acción) ...

<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>

Y aquí están las rutas ...

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

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

Entiendo por qué está ocurriendo el error, ya que lapage el parámetro puede ser nulo, pero no puedo encontrar la mejor manera de resolverlo. ¿Es mi diseño pobre para empezar? He pensado en extenderMethod #1La firma para incluir los parámetros de búsqueda y mover la lógica enMethod #2 a un método privado al que ambos llamarían, pero no creo que eso realmente resuelva la ambigüedad.

Cualquier ayuda sería muy apreciada.

Solucion actual (basado en la respuesta de Levi)

Agregué la siguiente clase ...

<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>

Y luego decoraron los métodos de acción ...

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

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

Respuestas a la pregunta(5)

Su respuesta a la pregunta