web-dev-qa-db-fra.com

Vérification pour voir si ViewBag a une propriété ou non, pour injecter conditionnellement JavaScript

Considérez ce contrôleur simple:

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);
}

Maintenant, dans ma vue Create, je veux vérifier l'objet ViewBag, pour voir s'il a la propriété Error ou non. S'il a la propriété error, j'ai besoin d'injecter du JavaScript dans la page, pour afficher le message d'erreur à mon utilisateur.

J'ai créé une méthode d'extension pour vérifier cela:

public static bool Has (this object obj, string propertyName) 
{
    Type type = obj.GetType();
    return type.GetProperty(propertyName) != null;
}

Ensuite, dans la vue Create, j'ai écrit cette ligne de code:

@if (ViewBag.Has("Error"))
{
    // Injecting JavaScript here
}

Cependant, j'obtiens cette erreur:

Impossible d'exécuter la liaison d'exécution sur une référence null

Une idée?

33
Saeed Neamati

Votre code ne fonctionne pas car ViewBag est un objet dynamique pas un type 'réel'.

le code suivant devrait fonctionner:

public static bool Has (this object obj, string propertyName) 
{
    var dynamic = obj as DynamicObject;
    if(dynamic == null) return false;
    return dynamic.GetDynamicMemberNames().Contains(propertyName);
}
21
JeffreyABecker
@if (ViewBag.Error!=null)
{
    // Injecting JavaScript here
}
99
jazzcat

Au lieu d'utiliser le ViewBag, utilisez ViewData afin de pouvoir vérifier le contenu de l'élément que vous stockez. L'objet ViewData est utilisé comme dictionnaire d'objets que vous pouvez référencer par clé, ce n'est pas une dynamique comme ViewBag.

// Set the [ViewData][1] in the controller
ViewData["hideSearchForm"] = true;    

// Use the condition in the view
if(Convert.ToBoolean(ViewData["hideSearchForm"])
    hideSearchForm();
4
JustEngland

J'éviterais complètement ViewBag ici. Voir mes réflexions ici à ce sujet: http://completedevelopment.blogspot.com/2011/12/stop-using-viewbag-in-most-places.html

L'alternative serait de lancer une erreur personnalisée et de l'attraper. comment savoir si la base de données est en panne ou s'il s'agit d'une erreur de sauvegarde de la logique métier? dans l'exemple ci-dessus, vous interceptez simplement une seule exception, il existe généralement une meilleure façon d'intercepter chaque type d'exception, puis un gestionnaire d'exceptions général pour les exceptions vraiment non gérées telles que les pages d'erreur personnalisées intégrées ou en utilisant ELMAH.

Donc ci-dessus, je préfère plutôt ModelState.AddModelError () Vous pouvez ensuite regarder ces erreurs (en supposant que vous ne voulez pas utiliser la validation intégrée) via Comment accéder au ModelState depuis ma vue (page aspx) ?

Veuillez donc considérer attentivement l'affichage d'un message lorsque vous interceptez "toute" exception.

3
Adam Tuliper - MSFT

Vous pouvez utiliser ViewData.ContainsKey("yourkey").

Dans le contrôleur:

ViewBag.IsExist = true;

En vue:

if(ViewData.ContainsKey("IsExist")) {...}
2
Kiran Kumar