c# - tenga - Se encontraron varias acciones que coinciden con la API web de solicitud?
se encontraron varias acciones que coincidían con la solicitud get (8)
Afortunadamente, hoy en día, con WEB API2 puede usar Attribute Routing . Microsoft se ha ido de código abierto a gran escala y luego un asistente llamado Tim McCall lo ha contribuido desde la comunidad. Entonces, desde algún lugar hasta el final de 2013, a principios de 2014, puede agregar atributos como [Route("myroute")]
en sus métodos de API WEB. Vea el siguiente ejemplo de código.
Sin embargo, como acabo de descubrir, debe asegurarse de usar System.Web.Http.Route
y NO System.Web.Mvc.Route
. De lo contrario, seguirá recibiendo el mensaje de error Multiple actions were found that match the request
.
using System.Web.Http;
...
[Route("getceremonies")]
[HttpGet]
// GET api/Ceremony
public IEnumerable<Ceremony> GetCeremonies()
{
return db.Ceremonies.AsEnumerable();
}
[Route("getceremony")]
[HttpGet]
// GET api/Ceremony/5
public Ceremony GetCeremony(int id)
{
Ceremony ceremony = db.Ceremonies.Find(id);
return ceremony;
}
[Route("getfilteredceremonies")]
[HttpGet]
public IEnumerable<Ceremony> GetFilteredCeremonies(Search filter)
{
return filter.Ceremonies();
}
Estoy usando API web y soy nuevo en esto. Estoy atrapado en un problema de enrutamiento. Tengo un controlador con las siguientes acciones:
// GET api/Ceremony
public IEnumerable<Ceremony> GetCeremonies()
{
return db.Ceremonies.AsEnumerable();
}
// GET api/Ceremony/5
public Ceremony GetCeremony(int id)
{
Ceremony ceremony = db.Ceremonies.Find(id);
return ceremony;
}
public IEnumerable<Ceremony> GetFilteredCeremonies(Search filter)
{
return filter.Ceremonies();
}
El problema ocurrió cuando agregué la acción GetFilteredCeremonies
a mi controlador. Después de agregar esto cuando GetCeremonies
una llamada ajax a la acción GetCeremonies
, devuelve una excepción con el siguiente mensaje:
"Message":"An error has occurred.","ExceptionMessage":"Multiple actions were
found that match the request
FYI: El parámetro Search
es la clase Model que contiene propiedades y un nombre de función Ceremonies.
EDITAR
Ruta:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Aquí está mi controlador:
public class PhoneFeaturesController : ApiController
{
public List<PhoneFeature> GetbyPhoneId(int id)
{
var repository = new PhoneFeatureRepository();
return repository.GetFeaturesByPhoneId(id);
}
public PhoneFeature GetByFeatureId(int id)
{
var repository = new PhoneFeatureRepository();
return repository.GetFeaturesById(id);
}
}
Aquí está mi enrutamiento api:
config.Routes.MapHttpRoute(
name: "ApiWithId",
routeTemplate: "Api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional },
constraints: new { id = @"^[0-9]+$" });
config.Routes.MapHttpRoute(
name: "ApiWithAction",
routeTemplate: "api/{controller}/{action}/{name}",
defaults: null,
constraints: new { name = @"^[a-z]+$" });
config.Routes.MapHttpRoute(
name: "ApiByAction",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { action = "Get" },
constraints: new { id = @"^[0-9]+$" });
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
Lo probé así:
/api/PhoneFeatures//api/PhoneFeatures/GetFeatureById/101
/api/PhoneFeatures/GetByFeatureId/12
Funciona sin problemas en todas las condiciones :)
Edite su WebApiConfig.cs en la carpeta App_Start en la raíz del proyecto y agregue {action} al parámetro routeTemplate en el método MapHttpRoute como se muestra a continuación:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{action}/{id}",
defaults: new { id = RouteParameter.Optional }
);
El problema aquí es que sus 2 métodos Get
se resolverán en api/Ceremony
y MVC no permitirá la sobrecarga de parámetros. Una solución rápida (no necesariamente el enfoque preferido) para este tipo de problema es hacer que tu parámetro de id
nulable, por ejemplo
// GET api/Ceremony
public IEnumerable<Ceremony> GetCeremonies(int? id)
{
if (id.HasValue)
{
Ceremony ceremony = db.Ceremonies.Find(id);
return ceremony;
}
else
{
return db.Ceremonies.AsEnumerable();
}
}
Sin embargo, estarías devolviendo una lista de ceremonias cuando con 1 artículo cuando tratas de buscar una sola ceremonia. Si pudieras vivir con eso, entonces podría ser la solución para ti.
La solución recomendada es asignar sus rutas de forma adecuada a las acciones correctas, por ejemplo
context.Routes.MapHttpRoute(
name: "GetAllCeremonies",
routeTemplate: "api/{controller}",
defaults: new { action = "GetCeremonies" }
);
context.Routes.MapHttpRoute(
name: "GetSingleCeremony",
routeTemplate: "api/{controller}/{id}",
defaults: new { action = "GetCeremony", id = UrlParameter.Optional }
);
Encontré otra solución que no requiere mover métodos fuera del controlador o cambiar la configuración de asignación de ruta. Simplemente agregue el atributo [NonAction]
al método que desea excluir:
[NonAction]
public IEnumerable<Ceremony> GetFilteredCeremonies(Search filter)
Espero que estés haciendo HttpGet mientras invocas GetFilteredCeremonies(Search filter)
En ese caso, no puede pasar el objeto complejo en la solicitud GET como la Search
que está pasando.
Si por alguna razón, definitivamente desea obtener tipos complejos en su solicitud de obtención, hay algunos problemas. Es posible que deba escribir un archivador de modelo personalizado y luego establecer el atributo. por favor consulte este artículo .
Por favor, compruebe que tiene dos métodos que tienen el nombre diferente y los mismos parámetros.
Si es así, elimine cualquiera de los métodos y pruebe.
Este error se planteó porque hay dos métodos que buscan los mismos parámetros. trata de eliminar cualquiera de ellos y prueba ...
Si no está obligado a usar los servicios REST que usan la ruta api/{controller}/{id}
e intentan resolver la acción según el método GET / POST / DELETE / PUT , puede modificar su ruta a la ruta MVC clásica para api/{controller}/{action}/{id}
y resolverá tus problemas.