2016-03-29 20 views
13

複数のパラメータを渡してMVC 6コントローラのメソッドを取得する方法を教えてください。たとえば、私は次のようなことができるようにしたい。複数のパラメータをASP.NETコアのgetメソッドに渡す方法

[Route("api/[controller]")] 
public class PersonController : Controller 
{ 
    public string Get(int id) 
    { 
    } 

    public string Get(string firstName, string lastName) 
    { 

    } 

    public string Get(string firstName, string lastName, string address) 
    { 

    } 
} 

だから私のように問い合わせることができます。

api/person?id=1 
api/person?firstName=john&lastName=doe 
api/person?firstName=john&lastName=doe&address=streetA 

答えて

6

URLから検索パラメータを解析するために、あなたは例えば、[FromQuery]とコントローラメソッドのパラメータに注釈を付ける必要があります。

[Route("api/person")] 
public class PersonController : Controller 
{ 
    [HttpGet] 
    public string GetById([FromQuery]int id) 
    { 

    } 

    [HttpGet] 
    public string GetByName([FromQuery]string firstName, [FromQuery]string lastName) 
    { 

    } 

    [HttpGet] 
    public string GetByNameAndAddress([FromQuery]string firstName, [FromQuery]string lastName, [FromQuery]string address) 
    { 

    } 
} 
+0

なぜこれが必要ですか?クエリ文字列からのパラメータバインドはデフォルトで行われます... – metalheart

+0

私は両方を試しましたが、失敗するかどうかを試みるときに失敗します。[FromQuery] – mstrand

+0

@metalheart FromQueryの装飾なしでは動作しませんでした... –

16

ちょうど1コントローラのアクションを使用していないのはなぜ?

public string Get(int? id, string firstName, string lastName, string address) 
{ 
    if (id.HasValue) 
     GetById(id); 
    else if (string.IsNullOrEmpty(address)) 
     GetByName(firstName, lastName); 
    else 
     GetByNameAddress(firstName, lastName, address); 
} 

別のオプションルーティング属性を使用することですが、その後、あなたは別のURL形式を持っている必要があるだろう:

//api/person/byId?id=1 
[HttpGet("byId")] 
public string Get(int id) 
{ 
} 

//api/person/byName?firstName=a&lastName=b 
[HttpGet("byName")] 
public string Get(string firstName, string lastName, string address) 
{ 
} 
+0

はい、私はPersonをオンにすることができるようにするすべての属性を取り入れるただ1つのアクションを使用して今解決します。一般的な検索のように。私はコントローラで過負荷のアクションを持つ方法がどこにあるのかは分かりますが、そうでないかもしれません。 – mstrand

15

ます。また、この使用することができます。

// GET api/user/firstname/lastname/address 

[HttpGet("{firstName}/{lastName}/{address}")] 

public string GetQuery(string id, string firstName, string lastName,string  address) 
{ 
return $"{firstName}:{lastName}"; 
} 
+1

同じ姓で皆を取得する必要があるまで、 –

0

enter image description here

NB-IがFromURIを削除しました。私はURLから値を渡して結果を得ることができます。誰もが知っていればfromuriを使用してください

+0

パラメータバインディング[1]の簡単な型 "(int、bool、doubleなど)、さらにTimeSpan、DateTime、Guid、decimal 、および文字列 "は自動的にURIから読み取られます。 [FromURI]属性は、これらの型のいずれかでないパラメータが、デフォルトの場所である本文ではなくURIからのURIの読み込みを強制する場合に必要です。完全性のために、[FromBody]属性は本質的に複合型とは逆です。 [1] https://docs.microsoft。com/en-us/aspnet/web-api/overview/formats-and-model-binding /パラメータバインディング-aspnet-web-api) –

0

別の答えの後、あなたのコメントであなたが尋ねたオーバーロードに関するいくつかの詳細を追加するには、ここで概要です。アクションは、各GETクエリと呼ばれますApiControllerショーのコメント:

public class ValuesController : ApiController 
{ 
    // EXPLANATION: See the view for the buttons which call these WebApi actions. For WebApi controllers, 
    //   there can only be one action for a given HTTP verb (GET, POST, etc) which has the same method signature, (even if the param names differ) so 
    //   you can't have Get(string height) and Get(string width), but you can have Get(int height) and Get(string width). 
    //   It isn't a particularly good idea to do that, but it is true. The key names in the query string must match the 
    //   parameter names in the action, and the match is NOT case sensitive. This demo app allows you to test each of these 
    //   rules, as follows: 
    // 
    // When you send an HTTP GET request with no parameters (/api/values) then the Get() action will be called. 
    // When you send an HTTP GET request with a height parameter (/api/values?height=5) then the Get(int height) action will be called. 
    // When you send an HTTP GET request with a width parameter (/api/values?width=8) then the Get(string width) action will be called. 
    // When you send an HTTP GET request with height and width parameters (/api/values?height=3&width=7) then the 
    //   Get(string height, string width) action will be called. 
    // When you send an HTTP GET request with a depth parameter (/api/values?depth=2) then the Get() action will be called 
    //   and the depth parameter will be obtained from Request.GetQueryNameValuePairs(). 
    // When you send an HTTP GET request with height and depth parameters (/api/values?height=4&depth=5) then the Get(int height) 
    //   action will be called, and the depth parameter would need to be obtained from Request.GetQueryNameValuePairs(). 
    // When you send an HTTP GET request with width and depth parameters (/api/values?width=3&depth=5) then the Get(string width) 
    //   action will be called, and the depth parameter would need to be obtained from Request.GetQueryNameValuePairs(). 
    // When you send an HTTP GET request with height, width and depth parameters (/api/values?height=7&width=2&depth=9) then the 
    //   Get(string height, string width) action will be called, and the depth parameter would need to be obtained from 
    //   Request.GetQueryNameValuePairs(). 
    // When you send an HTTP GET request with a width parameter, but with the first letter of the parameter capitalized (/api/values?Width=8) 
    //   then the Get(string width) action will be called because the case does NOT matter. 
    // NOTE: If you were to uncomment the Get(string height) action below, then you would get an error about there already being 
    //   a member named Get with the same parameter types. The same goes for Get(int id). 
    // 
    // ANOTHER NOTE: Using the nullable operator (e.g. string? paramName) you can make optional parameters. It would work better to 
    //   demonstrate this in another ApiController, since using nullable params and having a lot of signatures is a recipe 
    //   for confusion. 

    // GET api/values 
    public IEnumerable<string> Get() 
    { 
     return Request.GetQueryNameValuePairs().Select(pair => "Get() => " + pair.Key + ": " + pair.Value); 
     //return new string[] { "value1", "value2" }; 
    } 

    //// GET api/values/5 
    //public IEnumerable<string> Get(int id) 
    //{ 
    // return new string[] { "Get(height) => height: " + id }; 
    //} 

    // GET api/values?height=5 
    public IEnumerable<string> Get(int height) // int id) 
    { 
     return new string[] { "Get(height) => height: " + height }; 
    } 

    // GET api/values?height=3 
    public IEnumerable<string> Get(string height) 
    { 
     return new string[] { "Get(height) => height: " + height }; 
    } 

    //// GET api/values?width=3 
    //public IEnumerable<string> Get(string width) 
    //{ 
    // return new string[] { "Get(width) => width: " + width }; 
    //} 

    // GET api/values?height=4&width=3 
    public IEnumerable<string> Get(string height, string width) 
    { 
     return new string[] { "Get(height, width) => height: " + height + ", width: " + width }; 
    } 
} 

あなたは不思議に思った場合には、このための単一のルートをのみが必要になります。

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

を、あなたはそれをテストすることができすべてこのMVCビュー、または何かsimlarで。はい、私はあなたがマークアップとJavaScriptを混ぜるべきではないことを知っています、そして、私はあなたの通常のようにブートストラップを使用していませんが、これはデモ目的のみです。

<div class="jumbotron"> 
    <h1>Multiple parameters test</h1> 
    <p class="lead">Click a link below, which will send an HTTP GET request with parameters to a WebAPI controller.</p> 
</div> 
<script language="javascript"> 
    function passNothing() { 
     $.get("/api/values", function (data) { alert(data); }); 
    } 

    function passHeight(height) { 
     $.get("/api/values?height=" + height, function (data) { alert(data); }); 
    } 

    function passWidth(width) { 
     $.get("/api/values?width=" + width, function (data) { alert(data); }); 
    } 

    function passHeightAndWidth(height, width) { 
     $.get("/api/values?height=" + height + "&width=" + width, function (data) { alert(data); }); 
    } 

    function passDepth(depth) { 
     $.get("/api/values?depth=" + depth, function (data) { alert(data); }); 
    } 

    function passHeightAndDepth(height, depth) { 
     $.get("/api/values?height=" + height + "&depth=" + depth, function (data) { alert(data); }); 
    } 

    function passWidthAndDepth(width, depth) { 
     $.get("/api/values?width=" + width + "&depth=" + depth, function (data) { alert(data); }); 
    } 

    function passHeightWidthAndDepth(height, width, depth) { 
     $.get("/api/values?height=" + height + "&width=" + width + "&depth=" + depth, function (data) { alert(data); }); 
    } 

    function passWidthWithPascalCase(width) { 
     $.get("/api/values?Width=" + width, function (data) { alert(data); }); 
    } 
</script> 
<div class="row"> 
    <button class="btn" onclick="passNothing();">Pass Nothing</button> 
    <button class="btn" onclick="passHeight(5);">Pass Height of 5</button> 
    <button class="btn" onclick="passWidth(8);">Pass Width of 8</button> 
    <button class="btn" onclick="passHeightAndWidth(3, 7);">Pass Height of 3 and Width of 7</button> 
    <button class="btn" onclick="passDepth(2);">Pass Depth of 2</button> 
    <button class="btn" onclick="passHeightAndDepth(4, 5);">Pass Height of 4 and Depth of 5</button> 
    <button class="btn" onclick="passWidthAndDepth(3, 5);">Pass Width of 3 and Depth of 5</button> 
    <button class="btn" onclick="passHeightWidthAndDepth(7, 2, 9);">Pass Height of 7, Width of 2 and Depth of 9</button> 
    <button class="btn" onclick="passHeightWidthAndDepth(7, 2, 9);">Pass Height of 7, Width of 2 and Depth of 9</button> 
    <button class="btn" onclick="passWidthWithPascalCase(8);">Pass Width of 8, but with Pascal case</button> 
</div> 
関連する問題