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

Tom*_*der 27 c# asp.net-web-api

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

    // 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();
    }
Run Code Online (Sandbox Code Playgroud)

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

"Message":"An error has occurred.","ExceptionMessage":"Multiple actions were 
 found that match the request
Run Code Online (Sandbox Code Playgroud)

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

编辑

路线:

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

Adm*_*vić 22

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


Jam*_*mes 8

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

// 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();
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

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 }
);
Run Code Online (Sandbox Code Playgroud)

  • 我认为那里有一个错误,你的路由器应该有不同的名字 (3认同)

Bar*_*art 5

幸运的是,现在有了 WEB API2,您可以使用Attribute Routing。微软已经大规模开源,然后一位名叫 Tim McCall 的向导从社区贡献了它。因此,自 2013 年年底或 2014 年初以来,您可以[Route("myroute")]在 WEB API 方法上添加属性。请参阅下面的代码示例。

仍然 - 正如我刚刚发现的 - 你必须确保使用System.Web.Http.Route而不是System.Web.Mvc.Route. 否则,您仍会收到错误消息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();
}
Run Code Online (Sandbox Code Playgroud)