web-dev-qa-db-ja.com

Web APIルートを正しくマップする方法

私はWeb APIを使用してTwitterのようなサイトのAPIを構築していますが、ルートのマッピングに問題があります

ユーザーコントローラーに対して次のアクションを実行します。

public User Get(string firstname, string lastname)
public User Get(Guid id)
public User Friends(Guid id)
public User Followers(Guid id)
public User Favorites(Guid id)

目的のルートと生成されたドキュメントは次のようになります。

api/users?firstname={firstname}&lastname={lastname}
api/users/{id}
api/users/{id}/friends
api/users/{id}/followers
api/users/{id}/favorites

WebApiConfig.csで私は:

config.Routes.MapHttpRoute(
    "2",
    "api/{controller}/{id}",
    new { action = "get", id = RouteParameter.Optional }
);


config.Routes.MapHttpRoute(
     "1",
     "api/{controller}/{id}/{action}"
);

WebAPIルートを正しくマップするにはどうすればよいですか?

17
Donny

あなたが望む柔軟性を考えると、あなたは見てみる必要があります

ASP.NET Web API 2の属性ルーティング

WebApiConfig.csで次のような属性ルーティングを有効にします

// Web API routes
config.MapHttpAttributeRoutes();

UserController内

アクションの名前を指定Friends, Followers and Favoritesシングルユーザーではなくコレクションを返すことを意味します

[RoutePrefix("api/users")]
public class UserController: ApiController {

    //eg: GET api/users?firstname={firstname}&lastname={lastname}
    [HttpGet]
    [Route("")]
    public User Get([FromUri]string firstname,[FromUri] string lastname) {...}

    //eg: GET api/users/{id}
    [HttpGet]
    [Route("{id:guid}")]
    public User Get(Guid id){...}

    //eg: GET api/users/{id}/friends
    [HttpGet]
    [Route("{id:guid}/friends")]
    public IEnumerable<User> Friends(Guid id){...}

    //eg: GET api/users/{id}/followers
    [HttpGet]
    [Route("{id:guid}/followers")]
    public IEnumerable<User> Followers(Guid id){...}

    //eg: GET api/users/{id}/favorites
    [HttpGet]
    [Route("{id:guid}/favorites")]
    public IEnumerable<User> Favorites(Guid id){...}
}
34
Nkosi

ルーティングは順序に依存します。 firstの一致が常に優先されます。したがって、ルートを最も具体的なものから最も具体的でないものへと順序付けることが重要です。

// All parameters are required, or it won't match.
// So it will only match URLs 4 segments in length
// starting with /api.
config.Routes.MapHttpRoute(
     "1",
     "api/{controller}/{id}/{action}"
);

// Controller is required, id is optional.
// So it will match any URL starting with
// /api that is 2 or 3 segments in length.
config.Routes.MapHttpRoute(
    "2",
    "api/{controller}/{id}",
    new { action = "get", id = RouteParameter.Optional }
);

ルートがこのように順序付けられると、期待どおりの動作が得られます。

5
NightOwl888

このテーマには、次のようなさまざまな役立つ参考資料があります。

これらをご覧になりましたか?

更新..

どのパラメータがどれであるかを明示的に示すためのより良い実践、すなわち:

    config.Routes.MapHttpRoute(
        name: "2",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { action = "Get", id = RouteParameter.Optional },
    );

    config.Routes.MapHttpRoute(
        name: "1",
        routeTemplate: "api/{controller}/{action}/{id}",
        defaults: null
    );

私が間違っていると思う主なことは、ルート「1」のアクション/ IDの順序が間違っていたことです。

1
MikeDub