Проверка наличия свойства ViewBag для условного внедрения JavaScript - PullRequest
33 голосов
/ 27 декабря 2011

Рассмотрим этот простой контроллер:

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
}

Однако я получаю эту ошибку:

Невозможно выполнить привязку во время выполнения для нулевой ссылки

Есть идеи?

Ответы [ 5 ]

98 голосов
/ 22 июня 2012
@if (ViewBag.Error!=null)
{
    // Injecting JavaScript here
}
21 голосов
/ 10 сентября 2012

Ваш код не работает, потому что 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);
}
4 голосов
/ 05 июня 2012

Вместо использования 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();
3 голосов
/ 27 декабря 2011

Я бы полностью избегал ViewBag. Посмотрите мои мысли здесь на этом: http://completedevelopment.blogspot.com/2011/12/stop-using-viewbag-in-most-places.html

Альтернативой может быть выбрасывание пользовательской ошибки и ее перехват. Как вы знаете, если база данных не работает, или это ошибка сохранения бизнес-логики? в приведенном выше примере вы просто перехватываете одно исключение, обычно есть лучший способ отловить каждый тип исключения, а затем общий обработчик исключений для действительно необработанных исключений, таких как встроенные пользовательские страницы ошибок или использование ELMAH.

Так что выше, я бы вместо ModelState.AddModelError () Затем вы можете посмотреть на эти ошибки (при условии, что вы не собираетесь использовать встроенную проверку) через Как получить доступ к ModelState из моего представления (страница aspx)?

Поэтому, пожалуйста, внимательно рассмотрите сообщение, когда вы видите «любое» исключение.

2 голосов
/ 29 апреля 2015

Вы можете использовать ViewData.ContainsKey("yourkey").

В контроллере:

ViewBag.IsExist = true;

В поле зрения:

if(ViewData.ContainsKey("IsExist")) {...}
...