简体   繁体   English

WebAPI-多个不带参数的GET方法

[英]WebAPI - multiple GET methods with no parameters

I've been able create whatever endpoints I've wanted as long as the parameters for each one is different: 只要每个端点的参数都不同,我就可以创建任何想要的端点:

public IHttpActionResult GetFightersByWeightClass(string WeightClass)
...

public IHttpActionResult GetFighterByExactName(string NameEquals)
...

But as soon as I try to create two differently named functions that share the same parameters I am unable to use both. 但是,一旦我尝试创建两个共享相同参数的名称不同的函数,我将无法同时使用这两个函数。 I have two endpoints that don't require parameters, shown below: 我有两个不需要参数的端点,如下所示:

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

Both URLs return this: 这两个URL都返回此:

{"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()"}

Not sure why this is happening they each have their own unique action and function name, so I thought they would work like this...: 不知道为什么会这样,他们每个人都有自己独特的动作和函数名,所以我认为他们会像这样工作:

http://localhost:55865/api/fighter/GetAllUndefeatedFighters -- Just shows fighters with zero losses http:// localhost:55865 / api / fighter / GetAllUndefeatedFighters-仅显示战斗机零损失

http://localhost:55865/api/fighter/ -- shows all fighters http:// localhost:55865 / api / fighter / -显示所有战斗机

...but instead neither works. ...但是两者都不起作用。 If I remove one of them, they other works and vice versa. 如果我删除其中一个,则其他项目也会起作用,反之亦然。 So they aren't working when they are both active. 因此,当它们都处于活动状态时,它们将无法工作。 Any idea why? 知道为什么吗?

Web API allows you to use Attribute routing to customize endpoint URIs. Web API允许您使用属性路由来自定义端点URI。 To use it, add: 要使用它,请添加:

config.MapHttpAttributeRoutes();

to the Register method in your WebApiConfig class. WebApiConfig类中的Register方法。 Then you can set the endpoints to whatever you want regardless of the Action name. 然后,您可以将端点设置为所需的任何值,而与操作名称无关。

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

And your URI becomes: 并且您的URI变为:

api/fighter/getallfighters

You can even add attribute routing to your controller: 您甚至可以将属性路由添加到控制器:

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

Use route attribute 使用路线属性

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

and call two method using different route 并使用不同的路线调用两种方法

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

A combination of the two other answers works well for me. 其他两个答案的组合对我来说效果很好。 (I've changed the names slightly from the question.) (我从问题中稍微更改了名称。)

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

As such, your endpoints would be: 这样,您的端点将是:

GET /api/v1/fighters

GET /api/v1/fighters/undefeated

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM