[解決済み] ASP.NET Web APIでエラーを返すためのベストプラクティス
質問
クライアントにエラーを返す方法について懸念していることがあります。
を投げて、すぐにエラーを返すのか? 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);
}
これは単なるサンプルコードで、バリデーションエラーもサーバーエラーも関係ありません。ただ、ベストプラクティス、それぞれのアプローチの長所と短所を知りたいのです。
どのように解決するのですか?
私の場合、通常
HttpResponseException
を送信するかどうかは、スローされた例外に応じてステータスコードを設定し、その例外が致命的かどうかで決まります。
HttpResponseException
をすぐに実行します。
結局はAPIがレスポンスを返しているのであって、ビューではないので、例外とステータスコードを含むメッセージをコンシューマに送り返しても問題ないと思います。私は今のところ、ほとんどの例外は間違ったパラメータや呼び出しなどによるものなので、エラーを蓄積して送り返す必要はありません。
私のアプリの例では、クライアントがデータを要求してくることがありますが、利用可能なデータがないため、私はカスタム
NoDataAvailableException
で、それを Web API アプリにバブリングさせ、カスタムフィルターでそれを捕捉して、正しいステータスコードとともに関連するメッセージを送り返すのです。
何がベストプラクティスなのか100%わかっているわけではありませんが、今のところこれがうまくいっているので、そうしています。
更新情報 :
この質問に答えてから、この話題についていくつかのブログ記事が書かれました。
https://weblogs.asp.net/fredriknormen/asp-net-web-api-exception-handling
(こちらはナイトリービルドでいくつかの新機能が追加されています) https://docs.microsoft.com/archive/blogs/youssefm/error-handling-in-asp-net-webapi
アップデート2
エラー処理プロセスのアップデート、2つのケースがあります。
-
見つからない、アクションに渡されたパラメータが無効などの一般的なエラーの場合、我々は
HttpResponseException
を実行し、直ちに処理を停止する。さらに、アクションのモデルエラーの場合、モデルステート辞書をRequest.CreateErrorResponse
拡張モジュールでラップしHttpResponseException
. モデル状態辞書を追加すると、レスポンスボディに送信されるモデルエラーのリストが表示されます。 -
上位レイヤーで発生したエラー、サーバーエラーについては、例外を Web API アプリにバブリングさせます。ここでは、グローバル例外フィルタを使用して例外を調べ、ELMAH でログを記録し、正しい HTTP ステータスコードと関連するフレンドリーなエラーメッセージをボディとして設定しようとします。
HttpResponseException
. 私たちが想定していない例外については、クライアントはデフォルトの500 internal server errorを受け取りますが、セキュリティ上の理由から一般的なメッセージが表示されます。
アップデート3
最近、Web API 2 を導入したことで、一般的なエラーの返送に
IHttpActionResult
インターフェース、特に
System.Web.Http.Results
名前空間の NotFound や BadRequest が適切な場合はそれらを拡張し、そうでない場合は例えば 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);
}
}
関連
-
[解決済み】ここで「要求URIに一致するHTTPリソースが見つかりませんでした」となるのはなぜですか?
-
[解決済み】取り消せないメンバはメソッドのように使えない?
-
[解決済み】Visual studio 2019がデバッグ時にフリーズする件
-
[解決済み】Moqを使用してメソッド呼び出しを検証する
-
[解決済み】ファイルへの読み書きの際に共有違反のIOExceptionが発生する C#
-
[解決済み】Linq 構文 - 複数列の選択
-
[解決済み】Nullableオブジェクトは値を持たなければならない?
-
[解決済み] Chromeを使用してASP.NET Web APIがXMLの代わりにJSONを返すようにするにはどうすればよいですか?
-
[解決済み] すべてのサーバーサイドのコードでConfigureAwaitを呼び出すためのベストプラクティス
-
[解決済み] ASP.NET Web APIに整数の配列を渡しますか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】C#で四捨五入する方法
-
解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C# [解決済み] Critical error detected c0000374 - C++ dll returns pointer off allocated memory to C#.
-
[解決済み】C#はJavaのcharAt()と同等?)
-
[解決済み] 'SubSonic.Schema .DatabaseColumn' 型のオブジェクトをシリアライズする際に、循環参照が検出されました。
-
[解決済み】取り消せないメンバはメソッドのように使えない?
-
[解決済み】Linq 構文 - 複数列の選択
-
[解決済み】画像のペイントにTextureBrushを使用する方法
-
[解決済み] 関数を終了するには?
-
[解決済み】プロセスが実行されているかどうかを知るには?
-
[解決済み】OKでないレスポンスに対してIHttpActionResultでコンテンツを返す。