web-dev-qa-db-ja.com

ASP.Net Web API GETに複数のパラメータを渡す方法

私は(うまくいけば)RESTful APIを実装するために.NET MVC4 Web APIを使用しています。私はいくつかのパラメータをシステムに渡し、それに何らかのアクションを実行させ、そして結果としてオブジェクトのリストを返す必要があります。具体的には、2つの日付を渡し、それらの間にあるレコードを返します。それ以降の呼び出しがシステム内で再処理されないように、返されたレコードも追跡します。

私はいくつかのアプローチを検討しました:

  1. パラメータを1つのJSON文字列にシリアル化し、それをAPIで個別に選択します。 http://forums.asp.net/t/1807316.aspx/1

  2. クエリ文字列でパラメータを渡します。
    複数のクエリパラメータを安らかなAPIに渡すための最良の方法は何ですか?

  3. 経路内のパラメーターを定義する:api/controller/date1/date2

  4. POSTを使うと、本質的にparamsを使ってオブジェクトを渡すことができます。

  5. Web API(現在)がそれをサポートしているのでODATAを研究しています。私はまだこれについてあまりやっていないので、私はそれにあまり精通していません。

適切なRESTプラクティスは、データがいつ引き出されるかを示しているようです。GETを使用する必要があります。しかし、GETも無効にする必要があります(副作用は発生しません)ので、APIシステムでレコードをマークしてから副作用が発生するため、特定の実装で違反しているのではないでしょうか。

それはまた、可変パラメータをサポートするという問題に私を導いた。入力パラメーター・リストが変更された場合、それが頻繁に起こる場合は選択肢3のために経路を再定義しなければならないのは面倒です。そして、パラメータが実行時に定義されているとどうなるでしょう...

いずれにしても、私の特定の実装では、どちらを選択した方が良いと思われますか?

124
sig606

このレコードマーキングはどういう意味ですか?これがロギング目的でのみ使用される場合は、GETを使用してすべてのキャッシュを無効にします。これは、このリソースに対するすべてのクエリをログに記録するためです。レコードマーキングに別の目的がある場合は、POSTを使用します。ユーザは自分の行動がシステムに影響を与えること、そしてPOSTメソッドは警告であることを知っておくべきです。

10
LukLed

私は最も簡単な方法は単にAttributeRoutingを使うことだと思います。

それはあなたのコントローラ内で明白です、なぜあなたはあなたのGlobal WebApiConfigファイルにこれを望みますか?

例:

    [Route("api/YOURCONTROLLER/{paramOne}/{paramTwo}")]
    public string Get(int paramOne, int paramTwo)
    {
        return "The [Route] with multiple params worked";
    }

{}の名前はあなたのパラメータと一致する必要があります。

そのように単純な、今、あなたはこのインスタンスで複数のパラメータを扱う別々のGETを持っています。

新しいルートをWebApiConfigエントリに追加するだけです。

たとえば、

public IEnumerable<SampleObject> Get(int pageNumber, int pageSize) { ..

追加:

config.Routes.MapHttpRoute(
    name: "GetPagedData",
    routeTemplate: "api/{controller}/{pageNumber}/{pageSize}"
);

次に、HTTP呼び出しにパラメータを追加します。

GET //<service address>/Api/Data/2/10 
48
Graham Wright

パラメーターを渡す必要がある場合は、RESTfull APIを実装する必要があります。これは、Markの最初の例 "api/controller?start = date1&end = date2"で説明されているのと同じスタイルで、クエリ文字列のパラメータを渡すことによって行いました。

コントローラで私は---からのヒントを使用した RLはC#で分割された?

// uri: /api/courses
public IEnumerable<Course> Get()
{
    NameValueCollection nvc = HttpUtility.ParseQueryString(Request.RequestUri.Query);
    var system = nvc["System"];
    // BL comes here
    return _courses;
}

私の場合は、Ajax経由でWebApiを呼び出していました。

$.ajax({
        url: '/api/DbMetaData',
        type: 'GET',
        data: { system : 'My System',
                searchString: '123' },
        dataType: 'json',
        success: function (data) {
                  $.each(data, function (index, v) {
                  alert(index + ': ' + v.name);
                  });
         },
         statusCode: {
                  404: function () {
                       alert('Failed');
                       }
        }
   });

これが役立つことを願っています...

46
Nigel Findlater

私は優れた解決策を見つけました http://habrahabr.ru/post/164945/

public class ResourceQuery
{
   public string Param1 { get; set; }
   public int OptionalParam2 { get; set; }
}

public class SampleResourceController : ApiController
{
    public SampleResourceModel Get([FromUri] ResourceQuery query)
    {
        // action
    }
}
37
Andrew Veriga

GETまたはPOSTの使用は、@ LukLedで明確に説明されています。 。あなたがパラメータを渡すことができる方法に関して、私は2番目のアプローチで行くことを提案するでしょう(私はODATAについてもあまり知りません)。

1.パラメータを1つのJSON文字列にシリアル化し、それをAPIで分離します。 http://forums.asp.net/t/1807316.aspx/1

これはユーザーフレンドリーおよびSEOフレンドリーではありません

2.クエリ文字列にパラメータを渡します。安らかなAPIに複数のクエリパラメータを渡すための最良の方法は何ですか?

これは通常の好ましい方法です。

3.ルート内のパラメータを定義する:api/controller/date1/date2

これは絶対に良い方法ではありません。これはdate2date1のサブリソースであると感じさせるもので、そうではありません。 date1date2はどちらもクエリパラメータであり、同じレベルにあります。

簡単な場合では、私はこのようなURIを提案します、

api/controller?start=date1&end=date2

しかし、私は個人的には以下のURIパターンが好きですが、この場合はパラメータをマッピングするためのカスタムコードを書く必要があります。

api/controller/date1,date2
8
VJAI

ここで完全に記述されるようにパラメータ結合を使用してください: http://www.asp.net/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web -api

8
danan
 [Route("api/controller/{one}/{two}")]
    public string Get(int One, int Two)
    {
        return "both params of the root link({one},{two}) and Get function parameters (one, two)  should be same ";
    }

ルートリンクのパラメータ({one}、{two})とGet関数のパラメータ(1、2)は同じである必要があります。

2
ashwath hegde

私はこれが本当に古いことを知っています、しかし私は最近同じことを望んでいましたそしてここに私が見つけたものがあります...

    public HttpResponseMessage Get([FromUri] string var, [FromUri] string test) {
        var retStr = new HttpResponseMessage(HttpStatusCode.OK);
        if (var.ToLower() == "getnew" && test.ToLower() == "test") {
            retStr.Content = new StringContent("Found Test", System.Text.Encoding.UTF8, "text/plain");
        } else {
            retStr.Content = new StringContent("Couldn't Find that test", System.Text.Encoding.UTF8, "text/plain");
        }

        return retStr;
    }

だから今あなたのアドレス/ URI /に...

http(s):// myURL/api/myController /?var = getnew&test = test

結果: "Found Test"


http(s):// myURL/api/myController /?var = getnew&test = anything

結果: "そのテストは見つかりませんでした"

1
Rick Riggs
    public HttpResponseMessage Get(int id,string numb)
    {
        //this will differ according to your entity name
        using (MarketEntities entities = new MarketEntities())
        {
          var ent=  entities.Api_For_Test.FirstOrDefault(e => e.ID == id && e.IDNO.ToString()== numb);
            if (ent != null)
            {
                return Request.CreateResponse(HttpStatusCode.OK, ent);
            }
            else
            {
                return Request.CreateErrorResponse(HttpStatusCode.NotFound, "Applicant with ID " + id.ToString() + " not found in the system");
            }
        }
    }
0
Jesse Mwangi

.Netコアでは次のようにできます。

    [Route("api/[controller]")]
    [ApiController]
    public class ReportController : ControllerBase
    {
...
...        
        // GET api/report/5454510/10/abc
        [HttpGet("{id}/{page}/{etc}")]
        public async Task<ActionResult<string>> Get(string id, int page, string etc)
0
DineshNS