web-dev-qa-db-ja.com

asp.net Web APIルーティングが機能しない

これが私のルーティング設定です:

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

そして、これが私のコントローラーです:

public class ProductsController : ApiController
{
    [AcceptVerbs("Get")]
    public object GetProducts()
    {
       // return all products...
    }

    [AcceptVerbs("Get")]
    public object Product(string name)
    {
       // return the Product with the given name...
    }
}

api/Products/GetProducts/を試してもうまくいきます。 api/Products/Product?name=testも機能しますが、api/Products/Product/testは機能しません。何が悪いのですか?

更新:

api/Products/Product/testを試してみると次のようになります。

{
  "Message": "No HTTP resource was found that matches the request URI 'http://localhost:42676/api/Products/Product/test'.",
  "MessageDetail": "No action was found on the controller 'Products' that matches the request."
}
12
ataravati

これは、ルーティング設定とそのデフォルト値が原因です。 2つの選択肢があります。

1)URIと一致するようにProduct()パラメーターと一致するようにルート設定を変更する。

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

2)もう1つの推奨される方法は、正しいメソッドシグネチャ属性を使用することです。

public object Product([FromUri(Name = "id")]string name){
       // return the Product with the given name
}

これは、メソッドが-を探すのではなく、api/Products/Product/testをリクエストするときにパラメータidを期待しているためですnameパラメータ。

15
Ananthan Unni

更新に基づいて:

WebApiはリフレクションに基づいて機能することに注意してください。これは、中括弧{vars}がメソッド内の同じ名前と一致する必要があることを意味します。

したがって、この_api/Products/Product/test_に基づいてこの_"api/{controller}/{action}/{id}"_に一致させるには、メソッドを次のように宣言する必要があります。

_[ActionName("Product")]
[HttpGet]
public object Product(string id){
   return id;
}
_

パラメータ_string name_が_string id_に置き換えられました。

これが私の完全なサンプルです:

_public class ProductsController : ApiController
{
    [ActionName("GetProducts")]
    [HttpGet]
    public object GetProducts()
    {
        return "GetProducts";
    }
    [ActionName("Product")]
    [HttpGet]
    public object Product(string id)
    {
        return id;
    }
}
_

まったく異なるテンプレートを使用してみました:

_ config.Routes.MapHttpRoute(
                name: "test",
                routeTemplate: "v2/{controller}/{action}/{id}",
                defaults: new { id = RouteParameter.Optional, demo = RouteParameter.Optional }
            );
_

しかし、それは私の側でうまくいきました。ところで、[AcceptVerbs("Get")]を削除して_[HttpGet]_に置き換えました。

7
Dalorzo

あなたのルートはidをパラメーターとして定義していますが、あなたのメソッドはnameパラメーターを期待しています。可能であれば属性ルーティングを選択し、Productメソッドで/ api/products/product/{name}を定義します。

http://www.asp.net/web-api/overview/web-api-routing-and-actions/attribute-routing-in-web-api-2

1
Montane