找到了与请求Web API匹配的多个操作?

我正在使用Web API,我是新手。 我陷入了路由问题。 我有一个控制器有以下行动:

// GET api/Ceremony public IEnumerable GetCeremonies() { return db.Ceremonies.AsEnumerable(); } // GET api/Ceremony/5 public Ceremony GetCeremony(int id) { Ceremony ceremony = db.Ceremonies.Find(id); return ceremony; } public IEnumerable GetFilteredCeremonies(Search filter) { return filter.Ceremonies(); } 

当我将动作GetFilteredCeremonies添加到我的控制器时出现问题。 在我对GetCeremonies操作进行ajax调用时添加此项后,它会返回一个Exception并显示以下消息:

 "Message":"An error has occurred.","ExceptionMessage":"Multiple actions were found that match the request 

仅供参考:参数Search是Model类,它包含属性和函数名称Ceremonies。

编辑

路线:

 config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); 

如果您不要求使用使用api/{controller}/{id}路由的REST服务并尝试根据方法GET / POST / DELETE / PUT解析操作,则可以修改到经典MVC路由到api/{controller}/{action}/{id}路由api/{controller}/{action}/{id}它将解决您的问题。

这里的问题是你的2 Get方法将解析为api/Ceremony而MVC不允许参数重载。 针对此类问题的快速解决方法(不一定是首选方法)是使您的id参数可以为空,例如

 // GET api/Ceremony public IEnumerable GetCeremonies(int? id) { if (id.HasValue) { Ceremony ceremony = db.Ceremonies.Find(id); return ceremony; } else { return db.Ceremonies.AsEnumerable(); } } 

然而,当您尝试查询单个仪式时,您将返回一个仪式列表,当您尝试查询单个仪式时 – 如果您可以接受它,那么它可能是您的解决方案。

建议的解决方案是将路径适当地映射到正确的操作,例如

 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 } ); 

这是我的控制器:

 public class PhoneFeaturesController : ApiController { public List GetbyPhoneId(int id) { var repository = new PhoneFeatureRepository(); return repository.GetFeaturesByPhoneId(id); } public PhoneFeature GetByFeatureId(int id) { var repository = new PhoneFeatureRepository(); return repository.GetFeaturesById(id); } } 

这是我的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 = @"^[az]+$" }); 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 } ); 

我测试了这样:

 /api/PhoneFeatures//api/PhoneFeatures/GetFeatureById/101 /api/PhoneFeatures/GetByFeatureId/12 

它在各种条件下都能顺利运行:)

幸运的是,现在使用WEB API2可以使用属性路由 。 微软已大规模开源,然后一个名为Tim McCall的向导从社区中贡献了它。 因此,从2013年年底到2014年初,您可以在WEB API方法中添加[Route("myroute")]等属性。 见下面的代码示例。

仍然 – 正如我刚刚发现的那样 – 你必须确保使用System.Web.Http.Route和NOT System.Web.Mvc.Route 。 否则,您仍会收到错误消息。 Multiple actions were found that match the request

 using System.Web.Http; ... [Route("getceremonies")] [HttpGet] // GET api/Ceremony public IEnumerable 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 GetFilteredCeremonies(Search filter) { return filter.Ceremonies(); } 

请检查您有两种方法,它们具有不同的名称和相同的参数。

如果是这样,请删除任何方法并尝试。

引发此错误是因为有两种方法正在寻找相同的参数。 尝试删除其中任何一个并尝试…

我希望你在调用GetFilteredCeremonies(Search filter)同时做HttpGet

在这种情况下,您无法在像要Search GET请求中传递复杂对象。

如果出于某种原因,您肯定希望在获取请求中获得复杂类型,那么可以解决一些问题。 您可能需要编写自定义模型绑定器,然后设置该属性。 请参阅这篇文章 。

在项目根目录的App_Start文件夹中编辑WebApiConfig.cs ,并在MapHttpRoute方法中将{action}添加到routeTemplate参数,如下所示:

  config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{action}/{id}", defaults: new { id = RouteParameter.Optional } ); 

我找到了另一个修复,它不需要从控制器移出方法或更改路由映射配置。 只需将[NonAction]属性添加到要排除的方法中:

 [NonAction] public IEnumerable GetFilteredCeremonies(Search filter)