考虑这个简单的控制器:
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
属性。如果它有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
}
然而,我收到此错误:
无法对空引用执行运行时绑定
有什么想法吗?
答案 0 :(得分:98)
@if (ViewBag.Error!=null)
{
// Injecting JavaScript here
}
答案 1 :(得分:21)
您的代码无效,因为ViewBag是dynamic object而不是'真实'类型。
以下代码应该有效:
public static bool Has (this object obj, string propertyName)
{
var dynamic = obj as DynamicObject;
if(dynamic == null) return false;
return dynamic.GetDynamicMemberNames().Contains(propertyName);
}
答案 2 :(得分:4)
不使用ViewBag,而是使用ViewData,以便检查要存储的项目。 ViewData对象用作可以按键引用的对象的Dictionary,它不像ViewBag那样是动态的。
// Set the [ViewData][1] in the controller
ViewData["hideSearchForm"] = true;
// Use the condition in the view
if(Convert.ToBoolean(ViewData["hideSearchForm"])
hideSearchForm();
答案 3 :(得分:3)
我完全避免使用ViewBag。 在这里看到我的想法: http://completedevelopment.blogspot.com/2011/12/stop-using-viewbag-in-most-places.html
替代方法是抛出自定义错误并捕获它。你怎么知道数据库是否已关闭,或者它的业务逻辑是否保存错误?在上面的示例中,您只捕获一个异常,通常有更好的方法来捕获每个异常类型,然后是真正未处理的异常的常规异常处理程序,例如内置的自定义错误页面或使用ELMAH。
所以,我会改为 ModelState.AddModelError() 然后,您可以查看这些错误(假设您不会使用内置验证) How do I access the ModelState from within my View (aspx page)?
因此,当您发现“任何”异常时,请仔细考虑显示消息。
答案 4 :(得分:2)
您可以使用ViewData.ContainsKey("yourkey")
。
在控制器中:
ViewBag.IsExist = true;
在视图中:
if(ViewData.ContainsKey("IsExist")) {...}
答案 5 :(得分:0)
我需要对此进行测试,但是:
@if (ViewBag.ABoolParam ?? false)
{
//do stuff
}
我认为会为您提供 ViewBag 属性的值,或者如果缺少则返回默认值。