コントローラーのアクションから呼び出される独自のコードによって例外がスローされた場合、どのように処理する必要がありますか? try-catchステートメントがまったくないベストプラクティスの例がたくさんあります。たとえば、リポジトリのデータにアクセスする場合:
public ViewResult Index()
{
IList<CustomModel> customModels = _customModelRepository.GetAll();
return View(customModels);
}
呼び出しがアクセスできないデータベースに対する呼び出しであり、たとえばEntity FrameworkのようなORMを使用している場合、明らかにこのコードは例外をスローする可能性があります。
しかし、私が見ることができるのは、例外が発生してユーザーに厄介なエラーメッセージを表示することだけです。
私はHandleError属性を知っていますが、未処理の例外が発生した場合にエラーページにリダイレクトするために主に使用されることを理解しています。
もちろん、このコードはtry-catchでラップすることもできますが、特にロジックが多い場合はうまく分離できません。
public ViewResult Index()
{
if (ValidationCheck())
{
IList<CustomModel> customModels = new List<CustomModel>();
try
{
customModels = _customModelRepository.GetAll();
}
catch (SqlException ex)
{
// Handle exception
}
if (CustomModelsAreValid(customModels))
// Do something
else
// Do something else
}
return View();
}
以前、データベース呼び出しなどの例外をスローする可能性のあるすべてのコードを抽出して、エラーを処理し、ユーザーにメッセージを表示するためにメッセージを返すDataProviderクラスに入れました。
これを処理する最善の方法は何だろうと思っていましたか?一部の例外はそうすべきではないので、私はいつもエラーページに戻りたくありません。代わりに、ユーザーへのエラーメッセージが通常のビューで表示されます。以前の方法は正しかったのですか、それともより良い解決策はありますか?
よりユーザーフレンドリーなメッセージを表示するには、3つのことを行います。
EDIT:ASP.NET Web APIは密接に関連しているため、言及したいと思いました。 Web APIエンドポイントのコンシューマーは必ずしもブラウザーであるとは限らないため、エラーの処理方法は少し異なります。まだ「FriendlyException」(上記の#2)を使用していますが、ErrorControllerにリダイレクトする代わりに、すべてのエンドポイントがErrorプロパティを含むある種のベースタイプを返すようにします。したがって、例外がWeb APIコントローラーに至るまでバブルする場合は、API応答のErrorプロパティにそのエラーを必ず貼り付けます。このエラーメッセージは、APIコントローラーが依存するクラスからバブルアップしたフレンドリメッセージであるか、例外タイプがFriendlyExceptionでない場合は一般的なメッセージです。これにより、消費側クライアントは、API応答のErrorプロパティが空かどうかを簡単に確認できます。エラーが存在する場合はメッセージを表示し、存在しない場合は通常どおり続行します。ナイスなのは、わかりやすいメッセージの概念のため、メッセージは一般的な「エラー」よりもユーザーにとってはるかに意味があるかもしれないということです。メッセージ。 Xamarinを使用してモバイルアプリを作成するときにこの戦略を使用します。WebサービスとiOS/Androidアプリ間でC#タイプを共有できます。
Asp.Net MVCでは、コントローラーのOnExceptionメソッドをオーバーライドすることもできます。
protected override void OnException(ExceptionContext filterContext)
{
if (filterContext.ExceptionHandled)
{
return;
}
filterContext.Result = new ViewResult
{
ViewName = ...
};
filterContext.ExceptionHandled = true;
}
これにより、必要に応じて例外を参照するメッセージを含むカスタムエラーページにリダイレクトできます。
エラーを処理するコントローラーを持つプロジェクトを参照するプロジェクトがいくつかあるため、OnExceptionオーバーライドを使用しました。
Security/HandleErrorsController.cs
protected override void OnException(ExceptionContext filterContext)
{
MyLogger.Error(filterContext.Exception); //method for log in EventViewer
if (filterContext.ExceptionHandled)
return;
filterContext.HttpContext.Response.StatusCode = (int)System.Net.HttpStatusCode.InternalServerError;
filterContext.Result = new JsonResult
{
Data = new
{
Success = false,
Error = "Please report to admin.",
ErrorText = filterContext.Exception.Message,
Stack = filterContext.Exception.StackTrace
},
JsonRequestBehavior = JsonRequestBehavior.AllowGet
};
filterContext.ExceptionHandled = true;
}
エラー処理には非常に多くの方法があるため、答えは常に「依存する」ため、このような質問はすべて建設的ではありません。
例外は基本的に回復不能であるため、多くの人がHandleErrorメソッドを使用することを好みます。つまり、オブジェクトを返せない場合はどうしますか?とにかくエラーを表示しますよね?
問題は、エラーをどのように表示するかです。エラーページを表示することが許容される場合、HandleErrorは正常に機能し、エラーを記録する簡単な場所を提供します。 Ajaxを使用している場合、またはより洗練されたものが必要な場合は、その方法を開発する必要があります。
DataProviderクラスについて話します。これが基本的にリポジトリです。リポジトリにビルドしてみませんか?