WebAPI - 没有参数的多个GET方法

时间:2016-07-23 18:50:11

标签: c# asp.net-web-api

只要每个端点的参数不同,我就能创建我想要的任何端点:

public IHttpActionResult GetFightersByWeightClass(string WeightClass)
...

public IHttpActionResult GetFighterByExactName(string NameEquals)
...

但是一旦我尝试创建两个不同命名的共享相同参数的函数,我就无法使用它们。我有两个不需要参数的端点,如下所示:

public class FighterController : ApiController
{
    /// <summary>
    /// Gets all fighters.
    /// </summary>
    /// <returns></returns>
    [ActionName("GetAllFighters")]
    public IEnumerable<Fighter> GetAllFighters()
    {
        return allFighters;
    }

    /// <summary>
    /// Gets all fighters that are currently undefeated.
    /// </summary>
    /// <returns></returns>
    [ActionName("GetAllUndefeatedFighters")]
    public IHttpActionResult GetAllUndefeatedFighters()
    {
        var results = allFighters.FindAll(f => f.MMARecord.Losses == 0);

        if (results == null)
        {
            return NotFound();
        }

        return Ok(results);
    }
}

这两个网址都会返回:

{"Message":"An error has occurred.","ExceptionMessage":"Multiple actions were found that match the request: \r\nGetAllFighters on type MMAAPI.Controllers.FighterController\r\nGetAllUndefeatedFighters on type MMAAPI.Controllers.FighterController","ExceptionType":"System.InvalidOperationException","StackTrace":" at System.Web.Http.Controllers.ApiControllerActionSelector.ActionSelectorCacheItem.SelectAction(HttpControllerContext controllerContext)\r\n at System.Web.Http.Controllers.ApiControllerActionSelector.SelectAction(HttpControllerContext controllerContext)\r\n at System.Web.Http.ApiController.ExecuteAsync(HttpControllerContext controllerContext, CancellationToken cancellationToken)\r\n at System.Web.Http.Dispatcher.HttpControllerDispatcher.<SendAsync>d__1.MoveNext()"}

不确定为什么会这样,他们每个人都有自己独特的动作和功能名称,所以我认为他们会这样工作......:

http://localhost:55865/api/fighter/GetAllUndefeatedFighters - 只显示零损失的战士

http://localhost:55865/api/fighter/ - 显示所有战士

......但是没有效果。如果我删除其中一个,则其他工作,反之亦然。因此,当他们都活跃时,他们不工作。知道为什么吗?

3 个答案:

答案 0 :(得分:3)

Web API允许您使用属性路由来自定义端点URI。 要使用它,请添加:

config.MapHttpAttributeRoutes();

Register课程中的WebApiConfig方法。然后,无论Action名称如何,您都可以将端点设置为您想要的任何内容。

[Route("getallfighters"), HttpGet, ResponseType(typeof(Fighter))]
public IHttpActionResult ThisNameDoesntMatterNow()
{
    //...
}

你的URI变为:

api/fighter/getallfighters

您甚至可以将属性路由添加到控制器:

[RoutePrefix("api/v1/fighters")]
public class FightersController : ApiController
{  
    //...
}

答案 1 :(得分:1)

使用路线属性

    /// <summary>
    /// Gets all fighters.
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    [System.Web.Http.Route("api/GetAllFighters")]
    public IEnumerable<Fighter> GetAllFighters()
    {
        return allFighters;
    }

    /// <summary>
    /// Gets all fighters that are currently undefeated.
    /// </summary>
    /// <returns></returns>
    [HttpGet]
    [System.Web.Http.Route("api/GetAllUndefeatedFighters")]
    public IHttpActionResult GetAllUndefeatedFighters()
    {
        var results = allFighters.FindAll(f => f.MMARecord.Losses == 0);

        if (results == null)
        {
            return NotFound();
        }

        return Ok(results);
    }

并使用不同的路径调用两个方法

http://www.yourdomain/api/GetAllFighters
http://www.yourdomain/api/GetAllUndefeatedFighters

答案 2 :(得分:1)

另外两个答案的组合对我很有用。 (我已经从问题中略微改变了名字。)

[RoutePrefix("api/v1/fighters")]
public class FighterController : ApiController
{
    /// <summary>
    /// Gets all fighters.
    /// </summary>
    /// <returns>An enumeration of fighters.</returns>
    [Route(""), HttpGet]
    public IEnumerable<Fighter> GetAllFighters()
    {
        return allFighters;
    }

    /// <summary>
    /// Gets all fighters that are currently undefeated.
    /// </summary>
    /// <returns>An enumeration of fighters.</returns>
    [Route("undefeated"), HttpGet]
    public IEnumerable<Fighter> GetAllUndefeatedFighters()
    {
        return allFighters.FindAll(f => f.MMARecord.Losses == 0);
    }
}

因此,您的终端将是:

GET /api/v1/fighters

GET /api/v1/fighters/undefeated