このシンプルなコントローラーを考えてみましょう:
Porduct product = new Product(){
// Creating a product object;
};
try
{
productManager.SaveProduct(product);
return RedirectToAction("List");
}
catch (Exception ex)
{
ViewBag.ErrorMessage = ex.Message;
return View("Create", product);
}
今、私のCreate
ビューで、ViewBag
オブジェクトをチェックして、Error
プロパティがあるかどうかを確認します。エラープロパティがある場合は、ユーザーにエラーメッセージを表示するために、ページにJavaScriptを挿入する必要があります。
これを確認する拡張メソッドを作成しました。
public static bool Has (this object obj, string propertyName)
{
Type type = obj.GetType();
return type.GetProperty(propertyName) != null;
}
次に、Create
ビューで、次のコード行を作成しました。
@if (ViewBag.Has("Error"))
{
// Injecting JavaScript here
}
しかし、私はこのエラーを受け取ります:
Null参照で実行時バインディングを実行できません
何か案が?
ViewBagは 動的オブジェクト 「実際の」タイプではないため、コードは機能しません。
次のコードが機能するはずです。
public static bool Has (this object obj, string propertyName)
{
var dynamic = obj as DynamicObject;
if(dynamic == null) return false;
return dynamic.GetDynamicMemberNames().Contains(propertyName);
}
@if (ViewBag.Error!=null)
{
// Injecting JavaScript here
}
ViewBagを使用する代わりに、ViewDataを使用して、保存しているアイテムを確認できます。 ViewDataオブジェクトは、キーで参照できるオブジェクトの辞書として使用されますが、ViewBagのように動的ではありません。
// Set the [ViewData][1] in the controller
ViewData["hideSearchForm"] = true;
// Use the condition in the view
if(Convert.ToBoolean(ViewData["hideSearchForm"])
hideSearchForm();
ここではViewBagを完全に避けます。ここで私の考えを参照してください: http://completedevelopment.blogspot.com/2011/12/stop-using-viewbag-in-most-places.html
別の方法は、カスタムエラーをスローしてキャッチすることです。データベースがダウンしているかどうか、またはそのビジネスロジックがエラーを保存しているかどうかをどのように確認しますか?上記の例では、単一の例外をキャッチするだけです。通常、各例外タイプをキャッチするより良い方法があり、組み込みのカスタムエラーページやELMAHを使用するなどの真に未処理の例外の一般的な例外ハンドラーがあります。
したがって、上記のように、ModelState.AddModelError()の代わりにこれらのエラーを見ることができます(組み込みの検証を使用していると仮定して) View(aspxページ)からModelStateにアクセスするにはどうすればよいですか) ?
そのため、「任意」の例外をキャッチしたときにメッセージを表示することを慎重に検討してください。
ViewData.ContainsKey("yourkey")
を使用できます。
コントローラー内:
ViewBag.IsExist = true;
ビューで:
if(ViewData.ContainsKey("IsExist")) {...}