by WebSurfer
2012年11月10日 10:14
例外の種類によって処置を分けるような場合、InnerException プロパティの情報が必要な場合があります。
例えば、先の記事 更新操作中の例外の処
置 のサンプルを見てください。この例では、DetailsViewInsertedEventArgs オブジェクトから取得できる Exception オブジェクトの
InnerException に格納されているオリジナルの例外を調べて処置を分けています。
ところが、SqlDataSource と GridView を組み合わせて更新操作を行うような場合、GridViewUpdatedEventArgs オブジェクトから取得できる
Exception オブジェクトには InnerException は含まれません。Exception オブジェクトそのものがオリジナルの例外となり、InnerException プロパ
ティは null を返します。
どのような場合に InnerException が含まれるのか/含まれないのか、自分が探した限りですが、 MSDN ライブラリなどには明確な記述は見つけら
れませんでした。
なので InnerException を見るべきか Exception そのものを見るべきかは、コードを書いて実際に動かしてみて調べないとわかないということにな
ります。
さらに、InnerException が何重かネストしているケースがあるかもしれません。
というわけで、再帰を使って一番最初に発生した例外を取得するのがよさそうです。以下のような感じです。
public static Exception GetInnerException(Exception ex)
{
if (ex.InnerException == null)
{
return ex;
}
return GetInnerException(ex.InnerException);
}
protected void GridView1_RowUpdated(object sender,
GridViewUpdatedEventArgs e)
{
if (e.Exception == null && e.AffectedRows == 1)
{
// Update に成功
}
else
{
if (e.Exception != null)
{
Exception ex = GetInnerException(e.Exception);
if (ex is SqlException)
{
if (((SqlException)ex).Number == 2627)
{
// PK 制約違反
Label1.Text = ex.Message;
e.ExceptionHandled = true;
}
}
}
e.KeepInEditMode = true;
}
}
実際はここまでやる必要はなく、せいぜい一つ下まで調べて、コードを書けば十分かもしれません。