3

MSDN でこのドキュメントを調べましたが、答えがわかりません。

次のように定義されたルートがあることを考慮してください。

    config.Routes.MapHttpRoute(
        name: "DefaultWithActionAndID",
        routeTemplate: "v{version}/{controller}/{action}/{id}",
        defaults: null,
        constraints: new {
            action = @"[a-zA-Z]+",
            id = @"\d+"
        }
    );

    config.Routes.MapHttpRoute(
        name: "DefaultWithID",
        routeTemplate: "v{version}/{controller}/{id}",
        defaults: null,
        constraints: new {
            id = @"\d+"
        }
    );

    config.Routes.MapHttpRoute(
        name: "DefaultWithoutActionOrId",
        routeTemplate: "v{version}/{controller}",
        defaults: null,
    );

これで、次のような 2 つのコントローラーができました。

public class ItemController:ApiController{
    [HttpGet]
    public Item Get(int id){}

    [HttpGet]
    public Item GetSomething(int id){}

    [HttpPut]
    public Item Put(Item newItem){}
}

public class AnotherController:ApiController{
    [HttpPut]
    public HttpResponseMessage Put(Something item){}
}

次のように、これらすべてのエンドポイントを呼び出せるようにしたいと思います。

GET /api/Item/344
GET /api/Item?id=344
GET /api/Item/Something/2334
GET /api/Item/Something?id=2334
PUT /api/Item     body={newItem}
PUT /api/Another  body={newSomething}

これは機能しますが、デフォルトのアクション名として「Get」を追加した場合のみです。ルートでデフォルトのアクション名を指定しないと、一致する複数のアクション名についてエラーが発生します。デフォルトのアクション名を追加すると、アクション名がデフォルトと一致せず見つからないため、エラーなしで PUT() メソッドに PUT を呼び出すことはできません。

    // Will work in some cases, but not all
    config.Routes.MapHttpRoute(
        name: "DefaultWithID",
        routeTemplate: "v{version}/{controller}/{id}",
        defaults: new {
            action="Get",
            id=RouteParameters.Optional
        },
        constraints: new {
            id = @"\d+"
        }
    );

    // Works
GET /api/Item/344
GET /api/Item?id=344
GET /api/Item/Something/2334
GET /api/Item/Something?id=2334

// Doesn't work
PUT /api/Item     body={newItem}
PUT /api/Another  body={newSomething}

HTTP 動詞に一致する名前のアクションを使用するようルーティングに指示するにはどうすればよいですか (使用する前に存在する場合)。

4

2 に答える 2

3

次のようにルートを定義するとします。

    config.Routes.MapHttpRoute(
            name: "DefaultWithActionAndID",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional },
            constraints: new {action = @"[a-zA-Z]+", id = @"\d*" }
            );

    config.Routes.MapHttpRoute(
        name: "DefaultWithID",
        routeTemplate: "api/{controller}/{id}",
        defaults: new { action = "GET", id = RouteParameter.Optional },
        constraints: new { id = @"\d*", httpMethod = new HttpMethodConstraint(new string[] { "GET" }) }
        );

    config.Routes.MapHttpRoute(
        name: "DefaultWithoutActionOrId",
        routeTemplate: "api/{controller}",
        defaults: new { action = "PUT" },
        constraints: new { httpMethod = new HttpMethodConstraint(new string[] { "PUT" }) }
        );

また、次のActionNameように GetSomething メソッドに属性を配置します。

[ActionName("Something")]
public Item GetSomething(int id){}

その後、上記のすべてのエンドポイントに到達できるはずです。

于 2013-05-02T07:57:42.603 に答える
0

私の見方では、次の設定が必要です。

1.

/api/Item/344
{controller}/{id}

2.

/api/Item/Something/2334
{controller}/{action}/{id}

'GetSomething' メソッドを次のように装飾します。

[ActionName("Something")]
public Item GetSomething(int id){}

3.

/api/Item?id=344
/api/Item/Something?id=2334

これらについて完全にはわかりません-上記のルートにデフォルトを追加しようとしましたか:

defaults: new { id = RouteParameter.Optional }

4.

PUT#3が適用されればうまくいくと思います

それが何かを変えるかどうか私に知らせてください。

于 2013-05-01T20:12:52.910 に答える