web-dev-qa-db-ja.com

ASP.NET WebAPIコントローラーにカスタムメソッドを追加する方法

ASP.NET MVC WebAPIプロジェクトでは、デフォルトで次のコントローラーを作成しました

 public class ValuesController : ApiController
    {
        // GET api/values
        public IEnumerable<string> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/values/5
        public string Get(int id)
        {
            return "value";
        }

        // POST api/values
        public void Post([FromBody]string value)
        {
        }

        // PUT api/values/5
        public void Put(int id, [FromBody]string value)
        {
        }

        // DELETE api/values/5
        public void Delete(int id)
        {
        }
}

ただし、カスタムメソッドを追加して、get/postもサポートできるようにすることは可能ですか?

ありがとうございました!

23
Developer

RoutePrefixなどの属性をHttpタイプで使用できます。

[Route("ChangePassword")]
[HttpPost] // There are HttpGet, HttpPost, HttpPut, HttpDelete.
public async Task<IHttpActionResult> ChangePassword(ChangePasswordModel model)
{        
}

Httpタイプは、ルート名と組み合わせて正しいメソッドにマップします。

18
Shawn Mclean

コードにGETPOSTが含まれているので、従うかどうかはわかりませんが、いずれにしても他のオプションがあります。

オプション1

最初に、App_StartファイルのWebApiConfig.csフォルダーでカスタムルートを構成できます。私が通常使用するものは次のとおりです。

    // GET /api/{resource}/{action}
    config.Routes.MapHttpRoute(
        name: "Web API RPC",
        routeTemplate: "{controller}/{action}",
        defaults: new { },
        constraints: new { action = @"[A-Za-z]+", httpMethod = new HttpMethodConstraint("GET") }
        );

    // GET|PUT|DELETE /api/{resource}/{id}/{code}
    config.Routes.MapHttpRoute(
        name: "Web API Resource",
        routeTemplate: "{controller}/{id}/{code}",
        defaults: new { code = RouteParameter.Optional },
        constraints: new { id = @"\d+" }
        );

    // GET /api/{resource}
    config.Routes.MapHttpRoute(
        name: "Web API Get All",
        routeTemplate: "{controller}",
        defaults: new { action = "Get" },
        constraints: new { httpMethod = new HttpMethodConstraint("GET") }
        );

    // PUT /api/{resource}
    config.Routes.MapHttpRoute(
        name: "Web API Update",
        routeTemplate: "{controller}",
        defaults: new { action = "Put" },
        constraints: new { httpMethod = new HttpMethodConstraint("PUT") }
        );

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

    // POST /api/{resource}/{action}
    config.Routes.MapHttpRoute(
        name: "Web API RPC Post",
        routeTemplate: "{controller}/{action}",
        defaults: new { },
        constraints: new { action = @"[A-Za-z]+", httpMethod = new HttpMethodConstraint("POST") }
        );

RESTfulエンドポイントとRPCエンドポイントの組み合わせを使用します。一部の純粋主義者にとって、これは聖戦の根拠です。私にとっては、この2つの組み合わせを使用します。これは強力な組み合わせであり、適切な理由が見つからないためです。

オプション2

他の人が指摘しているように、私自身も最近これらのことをしているので、属性ルーティングを使用します。

    [HttpGet]
    [GET("SomeController/SomeUrlSegment/{someParameter}")]
    public int SomeUrlSegment(string someParameter)
    {
        //do stuff
    }

この作業を行うには、属性ルーティング用のNuGetパッケージが必要でした(NuGetで「属性ルーティング」を検索してください)が、MVC 5/WebAPI 2にはネイティブに含まれていると思います。

お役に立てれば。

14
Matt Cashatt

属性ルーティングを使用できます:

[Route("customers/{customerId}/orders")]
public IEnumerable<Order> GetOrdersByCustomer(int customerId) { ... }

始めるためのドキュメント:

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

11
Iain

最初にこのルートをwebapiconfig.csに配置します

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

これで、このようなコントローラーにアクションを追加できます

 [HttpPost]
    public void Upload()
    {
           //Do some thing
    }

アップロードアクションをhttppost属性で装飾しました。これは、このアクションが投稿リクエストのみを受け入れることを意味します。

1
elia07