2017-10-18 4 views
0

J'essaie de transmettre des données en utilisant ViewBag.Unions. Je reçois des données au contrôleur, mais quand je foreach loop dans la vue, il dit «objet» ne contient pas une définition de «CountryName». Je donne le code complet du contrôleur et de la vue. Je ne peux pas résoudre ce problème.'objet' ne contient pas de définition pour 'CountryName'

Contrôleur

public ActionResult Index() 
     { 



      List<Country> listCountry = _db.Countries.ToList(); 
      ViewBag.Countries = listCountry; 

      ViewBag.Unions = (from unon in _db.Unions 
           join upz in _db.Upazilas on unon.UpazilaId equals upz.UpazilaId 
           join dic in _db.Districts on upz.DistrictId equals dic.DistrictId 
           join div in _db.Divisions on dic.DivisionId equals div.DivisionId 
           join con in _db.Countries on div.CountryId equals con.CountryId 

           select new 
           { 
            con.CountryName, 
            div.DivisionName, 
            dic.DistrictName, 
            upz.UpazilaName, 
            unon.UnionName 
           }).ToList(); 

      return View(); 
     } 

Voir

@{ 
    ViewBag.Title = "Index"; 
} 

<h2>Index</h2> 



<table class=""> 
    <thead> 
     <tr> 
      <td>Country</td> 
      <td>Division</td> 
      <td>District</td> 
      <td>Upazila</td> 
      <td>Union</td> 
     </tr> 
    </thead> 
    <tbody> 
      @if (ViewBag.Unions != null) 
      { 

       foreach (var un in ViewBag.Unions) 
       { 
        <tr> 
         <td>@un.CountryName </td> 
         <td>@un.DivisionName</td> 
         <td>@un.DistrictName</td> 
         <td>@un.UpazilaName</td> 
         <td>@un.UnionName</td> 
        </tr> 
       } 

      } 
     </tbody> 
</table> 

Répondre

3

Parce que ViewBag est un dictionnaire de type dynamique. Ainsi, chacun de vos objets dans cette collection est de type dynamique. Le compilateur ignore la vérification de type lorsque vous essayez d'accéder à une propriété d'un objet de type dynamique, mais il peut échouer en cours d'exécution (C'est exactement l'une des raisons pour lesquelles j'évite autant que possible ViewBag/ViewData).

Ce que vous devez faire est, créer un modèle de vue pour représenter ces données et projet que dans votre expression LINQ

public class MyViewModel 
{ 
    public string CountryName { set;get;} 
    public string DivisionName { set;get;} 
    public string DistrictName { set;get;} 
} 

Maintenant, puisque vous avez une classe fortement typé, vous ne avez pas vraiment besoin ViewBag à passer les données. Vous pouvez passer directement la liste des objets MyViewModel à la vue.

var items = (from unon in _db.Unions 
        join upz in _db.Upazilas on unon.UpazilaId equals upz.UpazilaId 
        join dic in _db.Districts on upz.DistrictId equals dic.DistrictId 
        join div in _db.Divisions on dic.DivisionId equals div.DivisionId 
        join con in _db.Countries on div.CountryId equals con.CountryId 
       select new MyViewModel 
            { 
             CountryName = con.CountryName, 
             DivisionName = div.DivisionName, 
             DistrictName = dic.DistrictName   
            }).ToList(); 

return View(items); 

Maintenant, assurez-vous que votre point de vue est fortement typée à ce type de collection

@model List<MyViewModel> 
<table class="table> 
@foreach(var item in Model) 
{ 
    <tr> 
     <td>@item.CountryName</td> 
     <td>@item.DivisionName</td> 
     <td>@item.DistrictnName</td> 
    </tr> 
} 
</table> 

Si vous voulez continuer à utiliser ViewBag pour transmettre les données (mais pourquoi ???), vous pouvez le faire. Au lieu de passer la liste des éléments à la méthode de vue, vous pouvez le définir pour voir le sac et y accéder dans votre vue rasoir. Assurez-vous de le transtyper dans une liste MyViewModel avant de commencer à boucler la collection.

ViewBag.Items = items; 
return View(); 

et dans la vue

<table class="table> 
@foreach(var item in ViewBag.Items as List<MyViewModel>) 
{ 
    <tr> 
     <td>@item.CountryName</td> 
     <td>@item.DivisionName</td> 
     <td>@item.DistrictnName</td> 
    </tr> 
} 
</table> 
+0

Votre réponse est correcte. Mais je veux utiliser l'objet anonyme dans ViewBag pour passer le contrôleur de données à voir. –

+0

Oui, vous pouvez utiliser le sac de vue pour transmettre les données (identique à ce que vous avez fait dans votre message d'origine). Vous devez diffuser l'élément de dictionnaire ViewBag dans la liste de MyViewModel et cela vous donnera l'intellisense pour ces noms de propriété. – Shyju