只要每个端点的参数不同,我就能创建我想要的任何端点:
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/ - 显示所有战士
......但是没有效果。如果我删除其中一个,则其他工作,反之亦然。因此,当他们都活跃时,他们不工作。知道为什么吗?
答案 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