문제

I have a Web API, that looks like the following...

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

When I call the first method Get, this works fine. When I use fiddler or Chrome REST Client to call the second method GetMiniLeagueTable, I am getting the following error:

{ Message: "The request is invalid." MessageDetail: "The parameters dictionary contains a null entry for parameter 'type' of non-nullable type 'CompetitionManager+MiniLeagueType' for method 'System.Collections.Generic.List`1[Competition] Get(Int32, MiniLeagueType)' in 'LeaguesController'. An optional parameter must be a reference type, a nullable type, or be declared as an optional parameter." }

I am using AttributeRouting to decorate the methods, but this doesn't seem to work. It was working fine before I introduced MiniLeagueType.

Has anyone come across this issue, or can you point me to where I am going wrong?

도움이 되었습니까?

해결책

I think that the cause is this url : api/Leagues/GetMiniLeagueTable/3. This url matches both routes, as it can be interpreted as such : api/Leagues?type=GetMiniLeagueTable&id=3. But it cannot convert GetMiniLeagueTable as a CompetitionManager.MiniLeagueType value, so it raises an error.

You should make more specific routes, for example api/Leagues/GetCompetitions/{type}/{id}, in order to prevent url matching 2 or more different routes.

Another possibility is to invert your action orders, as it will check first action's route before going for the next one if the url doesn't match.

다른 팁

It looks like the url: /api/Leagues/GetMiniLeagueTable/3 would match both routes.

Assuming it matches the first route, it would then be unable to convert GetMiniLeagueTable to CompetitionManager.MiniLeagueType unless that was a valid enum value.

You second route probably needs to be tested first, and only if that fails to match the url, try the second.

Not having used attributerouting myself (though I have used the similar attribute routing in the latest web api) I'm guessing the ActionPrecedence will help.

Try

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

And

[GET("api/Leagues/GetMiniLeagueTable/{id}", ActionPrecedence = 1)]
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top