web-dev-qa-db-ja.com

HttpClientがGETリクエストのコンテンツまたはボディを送信することは可能ですか?

現在、パラメーター化されたGETリクエストをAPIインターフェースに送信するために、次のコードを書いています。

api/master/city/filter?cityid=1&citycode='ny'

しかし、URLの長さには2,083文字の制限があることがわかります。

これを回避するために、GET要求のコンテンツ本文でjson形式でパラメーターを送信したいと思います。

ただし、HttpClientのGetメソッドはいずれもコンテンツ本文の送信を許可していません。 POSTの場合、コンテンツ本文を許可するPostAsyncという名前のメソッドがHttpClient内にあることがわかりました。

URLの長さ制限を回避するために、URLにないGETリクエストのパラメーターを送信する方法はありますか?

14
John

一般に、本文を含むHTTP GETリクエストが推奨されない理由については、この回答の最後にある警告をお読みください。


  • .NETCoreを使用している場合、標準の HttpClient でこのことを行うことができますボックス。たとえば、JSONボディでGETリクエストを送信するには:

    HttpClient client = ...
    
    ...
    
    var request = new HttpRequestMessage
    {
        Method = HttpMethod.Get,
        RequestUri = new Uri("some url"),
        Content = new StringContent("some json", Encoding.UTF8, ContentType.Json),
    };
    
    var response = await client.SendAsync(request).ConfigureAwait(false);
    response.EnsureSuccessStatusCode();
    
    var responseBody = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
    
  • .NETFrameworkはこのすぐに使用できるものをサポートしていません(上記のコードを試すとProtocolViolationExceptionを受け取ります) )。ありがたいことに、Microsoftは System.Net.Http.WinHttpHandler パッケージを提供しています。このパッケージはdoes機能をサポートします-デフォルトの代わりにインストールして使用してください HttpClientHandlerHttpClientインスタンスを構築する場合:

    var handler = new WinHttpHandler();
    var client = new HttpClient(handler);
    
    <rest of code as above>
    

    参照: https://github.com/dotnet/corefx/issues/28135#issuecomment-467261945


警告:

  • ボディを含むHTTP GETは、HTTP仕様の灰色の領域に該当するやや型破りな構造です。最終的な結果は、多くの古いソフトウェアがそのような要求をまったく処理できないか、またはそれを信じているために明示的に拒否することです奇形である。そのようなリクエストを送信しようとしているエンドポイントがそれをサポートしていることを非常に確認する必要があります。そうしないと、せいぜいHTTPエラーコードが返されます。最悪の場合、体は静かに廃棄されます。これにより、頭を悩ますようなデバッグにつながる可能性があります!
  • キャッシングプロキシサーバー、特に古いサーバーは、本文が存在することを期待していないため、URLのみに基づいてGET要求をキャッシュする場合があります。これにより、最も最近のリクエストが永久にキャッシュされる(ソフトウェアが破損する)か、キャッシュされたリクエストのみが発行された最新のものになります(キャッシュが意図したとおりに動作しなくなります)。繰り返しますが、これを理解するのは非常に苦痛です。
20
Ian Kemp