9

次のアクションを持つWebAPIコントローラーがあります。

    [HttpPut]
    public string Put(int id, JObject data)

    [HttpPut, ActionName("Lock")]
    public bool Lock(int id)

    [HttpPut, ActionName("Unlock")]
    public bool Unlock(int id)

そして、次のルートがマッピングされました。

        routes.MapHttpRoute(
            name: "Api",
            routeTemplate: "api/{controller}/{id}",
            defaults: new { id = RouteParameter.Optional }
        );
        routes.MapHttpRoute(
            name: "ApiAction",
            routeTemplate: "api/{controller}/{action}/{id}"
        );

次のリクエストを行うと、すべてが期待どおりに機能します。

PUT /api/items/Lock/5
PUT /api/items/Unlock/5

しかし、私が次のことを要求しようとすると、

PUT /api/items/5

次の例外が発生します。

Multiple actions were found that match the request:
    Put(int id, JObject data)
    Lock(int id)
    Unlock(int id)

デフォルトルートに空のアクション名を追加しようとしましたが、それは役に立ちませんでした:

[HttpPut, ActionName("")]
public string Put(int id, JObject data)

デフォルトのRESTfulルーティングをカスタムアクション名と組み合わせる方法はありますか?

編集:ルーティングメカニズムは、コントローラーの選択によって混乱することはありません。単一のコントローラーでのアクションの選択によって混乱します。私が必要としているのは、アクションが指定されていないときにデフォルトのアクションと一致させることです。それが物事を明確にすることを願っています。

4

3 に答える 3

6

これは、デフォルトのアクションセレクターである。から予想されるエラーですApiControllerActionSelector。基本的に、HTTPPut動詞に対応する3つのアクションメソッドがあります。また、デフォルトのアクションセレクターは、すべてプリミティブな.NETタイプ、よく知られているシンプルタイプ(、、、、、、) System.String、および基System.DateTimeになるシンプルタイプ(例:)であるシンプルアクションパラメータータイプを考慮することにも注意してください。System.DecimalSystem.GuidSystem.DateTimeOffsetSystem.TimeSpanNullable<System.Int32>

あなたの問題の解決策として、私はそれらのために以下の2つのコントローラーを作成します:

public class FooController : ApiController { 

    public string Put(int id, JObject data)
}

public class FooRPCController : ApiController { 

    [HttpPut]
    public bool Lock(int id)

    [HttpPut]
    public bool Unlock(int id)
}

ルートは次のようになります。

routes.MapHttpRoute(
    name: "ApiAction",
    routeTemplate: "api/Foo/{action}/{id}",
    defaults: new { controller = "FooRPC" }
);

routes.MapHttpRoute(
    name: "Api",
    routeTemplate: "api/Foo/{id}",
    defaults: new { id = RouteParameter.Optional, controller = "Foo" }
);

一方(あなたのトピックに完全には関連していません)、特に複雑な型のパラメーターを使用した、アクションの選択に関する3つのブログ投稿があります。彼らはあなたにいくつかのより多くの視点を与えるかもしれないので、私はあなたがそれらをチェックすることをお勧めします:

于 2012-10-29T20:09:33.847 に答える
2

Giscard Biambyの助けを借りて、私は正しい方向に私を向けたこの答えを見つけました。最終的に、この特定の問題を解決するために、私は次のようにしました。

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

ありがとう@GiscardBiamby

于 2012-11-29T18:39:21.970 に答える
-3

まず、[HttpPut, ActionName("")]これへのルートを削除してから変更します

config.Routes.MapHttpRoute(
    name: "Api",
    routeTemplate: "api/{controller}/{id}",
    defaults: new { id = RouteParameter.Optional },
    constraints: new { id = @"^[0-9]+$" }
    );  
于 2012-10-29T07:15:05.463 に答える