'对象'不包含' CountryName'的定义

时间:2017-10-18 16:57:43

标签: c# asp.net-mvc linq

我正在尝试使用ViewBag.Unions传递数据。我在控制器上获取数据,但是当我在视图中循环时,它会说“对象”。不包含' CountryName'的定义。我从控制器和视图中提供完整代码。我无法解决这个问题。

控制器

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

查看

@{
    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> 

1 个答案:

答案 0 :(得分:3)

因为ViewBag是动态类型字典。因此,该集合中的每个项目都是动态类型。当您尝试访问动态类型对象的属性时,编译器会跳过类型检查,但它可能在运行时失败( 这正是我尽可能避免ViewBag / ViewData的原因之一 )。

您应该做的是,创建一个视图模型来表示此数据并将项目投影到LINQ表达式中

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

现在,由于您有一个强类型类,因此您不需要ViewBag来传递数据。您可以直接将MyViewModel个对象列表传递给视图。

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

现在确保您的视图强烈输入此集合类型

@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>

如果您仍想使用ViewBag传递数据(但为什么???),您可以这样做。您可以将其设置为查看包并在剃刀视图中访问它,而不是将项列表传递给view方法。在开始循环集合之前,请务必将其强制转换为列表MyViewModel

ViewBag.Items = items;
return View();

并在视图中

<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>