回答:
の慣用的な使用法はEnsureSuccessStatusCode
、特定の方法で失敗のケースを処理したくない場合に、リクエストの成功を簡潔に検証することです。これは、クライアントのプロトタイプをすばやく作成したい場合に特に便利です。
障害のケースを特定の方法で処理する場合は、次のことは行わないでください。
var response = await client.GetAsync(...);
try
{
response.EnsureSuccessStatusCode();
// Handle success
}
catch (HttpRequestException)
{
// Handle failure
}
これはすぐにそれをキャッチするために例外をスローしますが、意味がありません。のIsSuccessStatusCode
プロパティはHttpResponseMessage
この目的のためにあります。代わりに以下を実行してください。
var response = await client.GetAsync(...);
if (response.IsSuccessStatusCode)
{
// Handle success
}
else
{
// Handle failure
}
(int)response.StatusCode
(msdn.microsoft.com/en-us/library/…を参照)
意味のある何も返さないので、EnsureSuccessStatusCodeは好きではありません。それが私が自分の拡張機能を作成した理由です:
public static class HttpResponseMessageExtensions
{
public static async Task EnsureSuccessStatusCodeAsync(this HttpResponseMessage response)
{
if (response.IsSuccessStatusCode)
{
return;
}
var content = await response.Content.ReadAsStringAsync();
if (response.Content != null)
response.Content.Dispose();
throw new SimpleHttpResponseException(response.StatusCode, content);
}
}
public class SimpleHttpResponseException : Exception
{
public HttpStatusCode StatusCode { get; private set; }
public SimpleHttpResponseException(HttpStatusCode statusCode, string content) : base(content)
{
StatusCode = statusCode;
}
}
MicrosoftのEnsureSuccessStatusCodeのソースコードはここにあります
SOリンクに基づく同期バージョン:
public static void EnsureSuccessStatusCode(this HttpResponseMessage response)
{
if (response.IsSuccessStatusCode)
{
return;
}
var content = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();
if (response.Content != null)
response.Content.Dispose();
throw new SimpleHttpResponseException(response.StatusCode, content);
}
IsSuccessStatusCodeについて私が気に入らないのは、「うまく」再利用できないことです。たとえば、pollyのようなライブラリを使用して、ネットワークの問題が発生した場合にリクエストを繰り返すことができます。その場合は、pollyまたは他のライブラリが処理できるように、コードで例外を発生させる必要があります...
EnsureSuccessStatusCode
ます。あなたはいつも処分response.Content
(最終的にした後も、常に呼び出されるためreturn;
の文)と、それはfuther読書のためのコンテンツを破壊します。元の実装では、ステータスコードが成功の結果を示さない場合にのみコンテンツが破棄されます。
await response.Content.ReadAsStringAsync()
にそれから次にチェックするのか分かりませんif (response.Content != null)
HttpRequest
コールを保護するようにPollyを設定し、特定の例外と特定HttpResponseCode
のを処理するようにポリシーを設定できます。こちらのポリーのreadmeの例を
response.Content
メソッドが呼び出された直後にnullになる可能性があるのはなぜですか?
同じメソッドで例外を処理したくない場合は、EnsureSuccessStatusCodeを使用します。
public async Task DoSomethingAsync(User user)
{
try
{
...
var userId = await GetUserIdAsync(user)
...
}
catch(Exception e)
{
throw;
}
}
public async Task GetUserIdAsync(User user)
{
using(var client = new HttpClient())
{
...
response = await client.PostAsync(_url, context);
response.EnsureSuccesStatusCode();
...
}
}
GetUserIdAsyncでスローされる例外は、DoSomethingAsyncで処理されます。