webapiconfig varios varias solicitud solicitado recurso que pueden parámetros ningún net método enlazar encontraron encontrado contenido con coincidían coinciden coincida asp admite acciones asp.net-mvc-5 attributerouting asp.net-mvc-controller asp.net-mvc-5.1

asp.net-mvc-5 - varios - se encontraron varias acciones que coincidían con la solicitud web api



Se encontraron varios tipos de controladores que coinciden con la URL. Esto puede suceder si las rutas de atributos en múltiples controladores coinciden con la URL solicitada (3)

... ¿Supongo que soy el primero en preguntar sobre este?

Supongamos que tiene las siguientes rutas, cada una declarada en un controlador diferente:

[HttpGet, Route("sign-up/register", Order = 1)] [HttpGet, Route("sign-up/{ticket}", Order = 2)]

... puedes hacer esto en MVC 5.0 con el mismo código, excepto para el parámetro Order . Pero después de actualizar a MVC 5.1, obtiene el mensaje de excepción en el título de la pregunta:

Se encontraron varios tipos de controladores que coinciden con la URL. Esto puede suceder si las rutas de atributos en múltiples controladores coinciden con la URL solicitada.

Entonces, ¿la nueva propiedad RouteAttribute.Order es solo a nivel de controlador? Sé que en AttributeRouting.NET también puedes hacer SitePrecedence . ¿Es la única forma de tener rutas como la anterior cuando todas las acciones están en el mismo controlador?

Actualizar

Lo siento, debería haber mencionado que estas rutas están en controladores MVC, no en WebAPI. No estoy seguro de cómo esto afecta a ApiControllers.


En el caso del enrutamiento de atributos, la API web intenta encontrar todos los controladores que coinciden con una solicitud. Si ve que varios controladores pueden manejar esto, arroja una excepción ya que considera que posiblemente sea un error del usuario. Esta búsqueda de ruta es diferente de la ruta normal donde gana el primer partido.

Como solución alternativa, si tiene estas dos acciones dentro del mismo controlador, la API web respeta la prioridad de la ruta y debería ver su situación funcionando.



Hay dos formas de solucionar esto:

Una restricción de expresiones regulares, como aquí: MVC Error de atributo de ruta en dos rutas diferentes

O una restricción de ruta personalizada, como aquí: https://blogs.msdn.microsoft.com/webdev/2013/10/17/attribute-routing-in-asp-net-mvc-5/

Puede crear restricciones de ruta personalizadas implementando la interfaz IRouteConstraint. Por ejemplo, la siguiente restricción restringe un parámetro al conjunto de valores válidos:

public class ValuesConstraint : IRouteConstraint { private readonly string[] validOptions; public ValuesConstraint(string options) { validOptions = options.Split(''|''); } public bool Match(HttpContextBase httpContext, Route route, string parameterName, RouteValueDictionary values, RouteDirection routeDirection) { object value; if (values.TryGetValue(parameterName, out value) && value != null) { return validOptions.Contains(value.ToString(), StringComparer.OrdinalIgnoreCase); } return false; } }

El siguiente código muestra cómo registrar la restricción:

public class RouteConfig { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); var constraintsResolver = new DefaultInlineConstraintResolver(); constraintsResolver.ConstraintMap.Add("values", typeof(ValuesConstraint)); routes.MapMvcAttributeRoutes(constraintsResolver); } }

Ahora puede aplicar la restricción en sus rutas:

public class TemperatureController : Controller { // eg: temp/celsius and /temp/fahrenheit but not /temp/kelvin [Route("temp/{scale:values(celsius|fahrenheit)}")] public ActionResult Show(string scale) { return Content("scale is " + scale); } }

En mi opinión, este no es un gran diseño. No hay juicios sobre qué URL pretendía ni reglas de especificidad al hacer coincidir, a menos que usted mismo los establezca explícitamente. Pero al menos puede obtener sus URL de la manera que desee. Esperemos que su lista de restricciones no sea demasiado larga. Si es así, o no desea codificar el parámetro de cadena de ruta y sus restricciones, podría compilarlo programáticamente fuera del método de acción y alimentarlo al atributo Ruta como una variable.