无法在C#Razor foreach语句中将Type List()转换为Custom Class Type

时间:2015-03-11 09:16:28

标签: c# asp.net-mvc razor

我有一个数据列表,包括MainMenus和SubMenus,MainMenus,其中ParentID = 0,如下例所示: - MainMenus and SubMenus combined

我已经使用存储过程和连接三个表来阅读上述数据 主菜单 子菜单 UserPermission

首先选择MainMenus并将它们连接到UserPermission并仅过滤当前用户有权访问的MainMenus。 然后结合(联盟) 选择SubMenus并将它们连接到UserPermission并仅过滤当前用户有权访问的那些SubMenus。 现在,我有上面的表格结果集。我使用

得到了表格结果集
public DataTable getUserMenus(string userID)
    {
        DataTable dataTable = new DataTable();
        using (var conn = new SqlConnection(connString))
        {
            using (var cmd = new SqlCommand("Proc_GetUserMenus", conn))
            {
                conn.Open();
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.Parameters.AddWithValue("@UserID", userID);
                SqlDataAdapter da = new SqlDataAdapter(cmd);
                da.Fill(dataTable);

            }
        }
        return dataTable;
    }

当我返回我想要的结果集时,我使用以下代码将DataTable转换为IEnumerable

public IEnumerable<GeneratedMenus> ConvertToGeneratedMenus(DataTable dataTable)
    {
        foreach (DataRow row in dataTable.Rows)
        {
            yield return new GeneratedMenus
            {
                MenuID = Convert.ToInt32(row["MenuID"]),
                MenuName = Convert.ToString(row["MenuName"]),
                ActionName = Convert.ToString(row["ActionName"]),
                ControllerName = Convert.ToString(row["ControllerName"]),
                ParentID = Convert.ToInt32(row["ParentID"]),

            };


        }
    }

GeneratedMenus是我为Hold MainMenus和SubMenus创建的类,它看起来像

public class GeneratedMenus
    {
        public int MenuID { get; set; }
        public string MenuName { get; set; }
        public string ActionName { get; set; }
        public string ControllerName { get; set; }
        public int ParentID { get; set; }
    }

在HomeController索引中ActionResult我有一个代码来填充ViewBag.MenuList属性

public ActionResult Index()
    {
        DataAccess da = new DataAccess();
        ViewBag.MenusList =   da.ConvertToGeneratedMenus(da.getUserMenus("MyUserID")).ToList();
        return View();
    } 

DataAccess是ConvertToGeneratedMenus()和getUserMenus所在的类。我正在使用经典的ADO.NET ConnectionString进行SQL Server数据库连接。

最后一部分是_Layout.cshtml部分视图,我依次使用以下C#Razor代码分别显示MainMenus和SubMenus

@if (ViewBag.MenusList != null)
                {                                                                   
                    foreach (MainMenu  mainMenu in ViewBag.MenusList)
                    {
                        <li class="dropdown">
                            <a class="dropdown-toggle" data-toggle="dropdown">
                                @mainMenu.MenuName
                            </a>

                            <ul class="dropdown-menu">
                                @foreach (SubMenu subMenu in ViewBag.MenuList)
                                {
                                    if (subMenu.ParentID == mainMenu.MainMenuID)
                                    {
                                      <li>
                                      @Html.ActionLink(
                                      @subMenu.MenuName, 
                                      @subMenu.ActionName, 
                                      @subMenu.ControllerName)
                                      </li>
                                    }

                                }
                            </ul>
                        </li>
                    }

                }

我收到的错误是: - 无法将类型'DataAccess.GeneratedMenus'转换为'MainMenu' 那么,问题是我的代码出了什么问题?或者,您能告诉我更好的想法修改我的代码来完成这项工作吗? 任何建议将受到高度赞赏。

注意:MainMenu,SubMenu,UserPermission是EDMX(实体数据模型)数据库生成Wizzard时的生成模型类,但GeneratedMenus是Custom类我声明了我的自我。

2 个答案:

答案 0 :(得分:1)

您需要创建一个代表您要显示的内容的模型

public class Menu
{
  public Menu()
  {
    Children = new List<Menu>();
  }
  public int MenuID { get; set; }
  public string MenuName { get; set; }
  public string ActionName { get; set; }
  public string ControllerName { get; set; }
  // The collection of sub menus associated with the menus
  public List<Menu> Children { get; set; } 
}

并在视图中

@model List<Menu>
....
<ul>
  @foreach(Menu main in Model)
  {
    <li class="dropdown">
      <a class="dropdown-toggle" data-toggle="dropdown">@main.MenuName</a>

      <ul class="dropdown-menu">
        @foreach (Menu sub in main.Children)
        {
          <li>@Html.ActionLink(sub.MenuName, subMenu.ActionName, subMenu.ControllerName)</li>
        }
      </ul>
    </li>
  }
</ul>

在控制器中

public ActionResult Index()
{
  List<Menu> model = new List<Menu>();
  // populate the collection (i.e. where parentID is null)
  // populate the sub menus for each menu item
    return View(model);
} 

答案 1 :(得分:-1)

我通过修改一些代码解决了上述问题 在HomeController索引操作

public ActionResult Index()
    {
        DataAccess da = new DataAccess();
        //Getting all generated Menus and SubMenus
        var AllMenus = da.ConvertToGeneratedMenus(da.generateUserMenus("UserID")).ToList();
        //Getting MainMenus (where ParentID==0 in my case)
        var mainMenus = AllMenus.Where(mm => mm.ParentID == 0).ToList();
        //Getting SubMenus (where ParentID != 0 in my case)
        var subMenus = AllMenus.Where(sm => sm.ParentID != 0).ToList();

        //Assigning my MainMenus and SubMenus to two ViewBag properties(MainMenusList,SubMenuList) respectively 
        ViewBag.MainMenusList = mainMenus;
        ViewBag.SubMenuList = subMenus;

        return View();
    }

在我的_Layout.cshtml文件中

@if (ViewBag.MainMenusList != null)
                {
                    foreach (DataAccess.GeneratedMenus mainMenu in ViewBag.MainMenusList)
                    {
                        <li class="dropdown">
                            <a class="dropdown-toggle" data-toggle="dropdown">
                                @mainMenu.MenuName
                            </a>

                            <ul class="dropdown-menu">
                             @foreach (DataAccess.GeneratedMenus subMenu in ViewBag.SubMenuList)
                                {
                                    if (subMenu.ParentID == mainMenu.MenuID)
                                    {
                                      <li>
                                      @Html.ActionLink(
                                      @subMenu.MenuName, 
                                      @subMenu.ActionName, 
                                      @subMenu.ControllerName)
                                      </li>
                                    }

                                }
                            </ul>
                        </li>
                    }

                }

虽然我的内循环进行了不必要的重复,但仍会产生所需的结果。