クライアントにエラーを返す方法について懸念があります。
すぐにエラーを返すには?HttpResponseExceptionエラーが発生した場合:
public void Post(Customer customer)
{
if (string.IsNullOrEmpty(customer.Name))
{
throw new HttpResponseException("Customer Name cannot be empty", HttpStatusCode.BadRequest)
}
if (customer.Accounts.Count == 0)
{
throw new HttpResponseException("Customer does not have any account", HttpStatusCode.BadRequest)
}
}
または、すべてのエラーを蓄積してクライアントに送り返します。
public void Post(Customer customer)
{
List<string> errors = new List<string>();
if (string.IsNullOrEmpty(customer.Name))
{
errors.Add("Customer Name cannot be empty");
}
if (customer.Accounts.Count == 0)
{
errors.Add("Customer does not have any account");
}
var responseMessage = new HttpResponseMessage<List<string>>(errors, HttpStatusCode.BadRequest);
throw new HttpResponseException(responseMessage);
}
これは単なるサンプル コードです。検証エラーやサーバー エラーは問題ではありません。ベスト プラクティス、各アプローチの長所と短所を知りたいだけです。
ベストアンサー1
私の場合は、通常、 を返してHttpResponseException
、スローされた例外に応じてステータス コードを設定し、例外が致命的かどうかによって、 をすぐに戻すかどうかが決まりますHttpResponseException
。
結局のところ、これはビューではなくレスポンスを返す API なので、例外とステータス コードを含むメッセージをコンシューマーに送り返すのは問題ないと思います。ほとんどの例外は通常、誤ったパラメーターや呼び出しなどが原因であるため、現時点ではエラーを蓄積して送り返す必要はありません。
私のアプリの例では、クライアントがデータを要求することがありますが、利用可能なデータがないため、カスタムをスローしてNoDataAvailableException
Web API アプリにバブルさせ、そこでカスタム フィルターがそれをキャプチャして、適切なステータス コードとともに関連するメッセージを送り返します。
これのベストプラクティスが何であるかは 100% 確信はありませんが、これは現時点ではうまく機能しているので、私はこれを行っています。
アップデート:
私がこの質問に答えて以来、このトピックに関するブログ投稿がいくつか書かれました。
https://weblogs.asp.net/fredriknormen/asp-net-web-api-例外処理
(これにはナイトリービルドでいくつかの新機能があります)https://learn.microsoft.com/archive/blogs/youssefm/error-handling-in-asp-net-webapi
アップデート2
エラー処理プロセスの更新では、次の 2 つのケースがあります。
見つからない、またはアクションに渡される無効なパラメータなどの一般的なエラーの場合は、 を返して
HttpResponseException
処理を直ちに停止します。さらに、アクション内のモデル エラーの場合は、モデル状態辞書をRequest.CreateErrorResponse
拡張機能に渡し、 でラップしますHttpResponseException
。モデル状態辞書を追加すると、応答本文で送信されるモデル エラーのリストが生成されます。上位層で発生するエラー、つまりサーバー エラーについては、例外を Web API アプリにバブルさせます。ここでは、例外を調べ、ELMAH でログに記録し、正しい HTTP ステータス コードと適切なわかりやすいエラー メッセージを本文として再度設定して意味を解釈しようとするグローバル例外フィルターがあります。
HttpResponseException
予期しない例外については、クライアントは既定の 500 内部サーバー エラーを受け取りますが、セキュリティ上の理由から汎用的なメッセージを受け取ります。
アップデート3
最近、Web API 2を導入して以来、一般的なエラーを返すために、IHttpアクション結果インターフェース、具体的には、適合する場合は NotFound、BadRequest などの名前空間の組み込みクラスを使用しSystem.Web.Http.Results
、適合しない場合は拡張します。たとえば、応答メッセージを含む NotFound 結果などです。
public class NotFoundWithMessageResult : IHttpActionResult
{
private string message;
public NotFoundWithMessageResult(string message)
{
this.message = message;
}
public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
{
var response = new HttpResponseMessage(HttpStatusCode.NotFound);
response.Content = new StringContent(message);
return Task.FromResult(response);
}
}