无法将类型列表 () 转换为自定义 Class 在 C# Razor foreach 语句中键入

Cannot Convert Type List() to Custom Class Type in C# Razor foreach statement

我有一个由 MainMenus 和 SubMenus 组成的数据列表,其中 ParentID =0 的 MainMenus 如下例所示:-

我已经使用存储过程和连接三个表读取了以上数据 主菜单 子菜单 用户权限

首先选择MainMenus并将它们加入到UserPermission中,只过滤当前用户有权限的MainMenus。 然后合并(Union) 选择 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 是 class 我创建的用来保存 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 是 class ConvertToGeneratedMenus() 和 getUserMenus 所在的位置。我正在为 SQL 服务器数据库连接使用 classic ADO.NET ConnectionString。

最后一部分是 _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(实体数据模型)数据库生成向导时是生成模型 类,但 GeneratedMenus 是自定义的 class 我声明了我的自我。

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

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

我已经通过修改我的一些代码解决了上面的问题 在 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>
                    }

                }

虽然我的内部循环进行了不必要的重复,但它仍然产生了预期的结果。