2

我有一个Web API,看起来像下面...

public class LeaguesController : ApiController
{
    //api/Leagues/active/1
    //api/Leagues/complete/1
    //api/Leagues/both/1
    [GET("api/Leagues/{type}/{id}")]
    public List<Competition> Get([FromUri]int id, 
                                [FromUri]CompetitionManager.MiniLeagueType type)
    {
        return CompetitionManager.GetUsersMiniLeagues(id, true, type);
    }

    //api/Leagues/GetMiniLeagueTable/3
    [GET("api/Leagues/GetMiniLeagueTable/{id}")]
    public List<SportTableRow> GetMiniLeagueTable([FromUri]int id)
    {
        return SportManager.GetMiniLeagueTable("", id).TableRows;
    }
}

当我调用第一种方法Get时,它工作正常。当我使用 fiddler 或 Chrome REST Client 调用第二种方法GetMiniLeagueTable时,我收到以下错误:

{ 消息:“请求无效。” MessageDetail:“参数字典包含不可为空类型‘CompetitionManager+MiniLeagueType’的参数‘类型’的空条目,用于‘LeaguesController’中的方法‘System.Collections.Generic.List`1[Competition] Get(Int32, MiniLeagueType)’ '. 可选参数必须是引用类型、可空类型或声明为可选参数。” }

AttributeRouting用来装饰方法,但这似乎不起作用。在我介绍之前它运行良好MiniLeagueType

有没有人遇到过这个问题,或者你能指出我哪里出错了吗?

4

2 回答 2

5

我认为原因是这个网址:api/Leagues/GetMiniLeagueTable/3。这个 url 匹配两个路由,因为它可以被解释为 : api/Leagues?type=GetMiniLeagueTable&id=3。但它不能转换GetMiniLeagueTableCompetitionManager.MiniLeagueType值,因此会引发错误。

您应该制作更具体的路由,例如api/Leagues/GetCompetitions/{type}/{id},以防止 url 匹配 2 个或更多不同的路由。

另一种可能性是反转您的操作顺序,因为如果 url 不匹配,它将在执行下一个操作之前检查第一个操作的路线。

于 2013-11-13T22:21:30.453 回答
3

看起来 url: /api/Leagues/GetMiniLeagueTable/3 将匹配两条路线。

假设它与第一个路由匹配,那么它将无法将 GetMiniLeagueTable 转换为 CompetitionManager.MiniLeagueType ,除非这是一个有效的枚举值。

您的第二条路线可能需要先进行测试,并且只有当它与 url 不匹配时,才尝试第二条路线。

我自己没有使用属性路由(尽管我在最新的 web api 中使用了类似的属性路由)我猜ActionPrecedence会有所帮助。

尝试

[GET("api/Leagues/{type}/{id}", ActionPrecedence = 2)]

[GET("api/Leagues/GetMiniLeagueTable/{id}", ActionPrecedence = 1)]
于 2013-11-13T22:23:55.827 回答