0

Web API サービス用に次のデフォルト ルートを設定しています ...

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

config.Routes.MapHttpRoute(
    name: "DefaultPost",
    routeTemplate: "api/{controller}",
    defaults: new { action = "Post" },
    constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Post) }
    );

config.Routes.MapHttpRoute(
    name: "DefaultGetWithId",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { action = "Get" },
    constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Get) }
    );

config.Routes.MapHttpRoute(
    name: "DefaultPutWithId",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { action = "Put" },
    constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Put) }
    );

config.Routes.MapHttpRoute(
    name: "DefaultDeleteWithId",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { action = "Delete" },
    constraints: new { httpMethod = new HttpMethodConstraint(HttpMethod.Delete) }
    );

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

「UsersController」の下に次のサービスがあります。

public UserDto Get(string id){}

[HttpGet]
public UserDto ByEmail(string email)

[HttpGet]
public bool IsEmailUnique(string email)

問題は、3 つのサービスのいずれかにアクセスしようとすると、「複数のアクションが見つかりました」というエラーが表示されることです。リクエストは、すべてのルートから最後のルートを選択して、リクエストを実行する必要があります。

「/api/users/byemail?email=blah@blah.com」を実行する場合、「ByEmail」がアクションであり、メソッドとアクションを使用して正しいメソッドと一致することを知ってはいけませんか? 私は何かが欠けていると思います。

4

1 に答える 1

0

BeEmail および IsEmailUnique メソッドを GET アクションにマップしたため、複数のアクションが検出されたようです。

名前付きアクション (DefaultControllerWithAction) のルート テンプレートを既にセットアップしているため、[HttpGet] 属性を削除できます。

この後、ルートテンプレート「DefaultControllerWithAction」は「/api/users/byemail」をうまく整理する必要があります

編集: 同じ ApiController で従来のルーティングと動詞ベースのルーティングを混在させると問題があるようです。これは codeplexで文書化されており、これを解決したと主張するブログ投稿が 1 つあります (まだテストされていません): http://blog.appliedis.com/2013/03/25/web-api-mixing-traditional-verb-based -ルーティング/

edit2:
これをテストしたところ、Kip Streithorst のソリューションが状況に適しています。

ステップ 1:アクションがオプションであることを指定する代わりに、デフォルト値をハードコーディングします。
ステップ 2:ハードコーディングされたデフォルトのアクション名で「動詞ベースのコントローラーを装飾する」

get リクエストの場合、これは次のようになります。

    config.Routes.MapHttpRoute(
        名前: "DefaultControllerWithAction",
        routeTemplate: "api/{controller}/{action}",
        デフォルト: 新しい { action = "DefaultAction }
        );
    config.Routes.MapHttpRoute(
        名前: "DefaultGetWithId",
        routeTemplate: "api/{controller}/{id}",
        デフォルト: new { action = "Get" },
        制約: 新しい { httpMethod = 新しい HttpMethodConstraint(HttpMethod.Get) }
        );
    config.Routes.MapHttpRoute(
        名前: "DefaultControllerWithIdAndAction",
        routeTemplate: "api/{controller}/{id}/{action}",
        デフォルト: 新しい { action = "DefaultAction" }
        );

    [ActionName("DefaultAction")]
    public UserDto Get(文字列 ID){}

    [HttpGet]
    public UserDto ByEmail(文字列メール)

    [HttpGet]
    public bool IsEmailUnique(文字列メール)
于 2013-03-29T14:26:32.970 に答える