【问题标题】:ASP.NET MVC Populate DropDown thru ViewBagASP.NET MVC 通过 ViewBag 填充 DropDown
【发布时间】:2017-07-07 03:03:08
【问题描述】:

我是 ASP.NET MVC 技术的初学者。 在我的视图页面中,我有一个绑定到从控制器传递的数据的 WebGrid。我还想用数据库中的表列表填充下拉列表。我从辅助方法中检索表列表。我正在尝试将列表发送到 ViewBag 并希望填充下拉列表;但无法得到它。只是出现一些语法错误或无法访问列表。

我的控制器类:

        [Authorize]
    public ActionResult Index(int page = 1, string sort = "FirstName", string sortdir = "asc", string search = "")
    {
        int pageSize = 10;
        int totalRecord = 0;
        if (page < 1)
            page = 1;
        int skip = (page * pageSize) - pageSize;
        var data = GetUsers(search, sort, sortdir, skip, pageSize, out totalRecord);

        // Get Tables List
        ViewBag.TableList = DataFiller.GetTableNames();
        ViewBag.TotalRows = totalRecord;

        return View(data);
    }

查看文件:

@model List<DataStudio.Models.User>

@{
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_MemberLayout.cshtml";

<!-- data is used for grid -->
var grid = new WebGrid(canPage: true, rowsPerPage: 10);
grid.Bind(source: Model, rowCount: ViewBag.TotalRows, autoSortAndPage: false);   
}

<!-- ERROR LINE   -->
@Html.DropDownList("tableName", @ViewBag.TableList, "Select Table")

错误

Error   CS1973  'HtmlHelper<List<User>>' has no applicable method named 'DropDownList' but appears to have an extension method by that name. Extension methods cannot be dynamically dispatched. Consider casting the dynamic arguments or calling the extension method without the extension method syntax.    1_Views_Member_Index.cshtml Index.cshtml    82  Active

User 模型不包含任何 List 或任何 DropDownList。下拉列表是一个完全独立的组合框,我想用列表项填充它;它只包含数据库中的表名列表。

我无法了解如何使用 SelectLiteItem 项绑定或填充下拉列表。我用谷歌搜索了很多,但在这种情况下找不到任何例子。我不想在我的模型中添加我的列表。而且,我只想填充表格列表下拉一次。

任何人都可以帮助我并指导我如何实现目标。非常感谢任何帮助。

谢谢

汤姆

更新: DataFilter.GetTableNames() 方法

       public static List<SelectListItem> GetTableNames()
    {
        List<SelectListItem> tablesList = new List<SelectListItem>();

        string sql = "SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_TYPE = 'BASE TABLE'";
        string conStr = System.Configuration.ConfigurationManager.ConnectionStrings["DMSDbConnectionString"].ToString();

        using (SqlConnection con = new SqlConnection(conStr))
        {
            using (SqlCommand com = new SqlCommand(sql, con)) {
                con.Open();
                using(SqlDataReader sdr = com.ExecuteReader() )
                {
                    while (sdr.Read())
                    {
                        tablesList.Add(new SelectListItem
                        {
                            Text = sdr["TABLE_NAME"].ToString(),
                            Value = sdr["TABLE_NAME"].ToString()
                        });
                    }
                }

                /*
                SqlDataAdapter da = new SqlDataAdapter(com);
                DataSet ds = new DataSet();
                da.Fill(ds);

                DataTable dt = ds.Tables[0];

                tablesList = (from DataRow dr in dt.Rows
                              select new TablesInfo()
                              {
                                  TableCatalog = dr["TABLE_CATALOG"].ToString(),
                                  TableName = dr["TABLE_NAME"].ToString(),
                                  TableSchema = dr["TABLE_SCHEMA"].ToString(),
                                  TableType = dr["TABLE_TYPE"].ToString(),
                              }).ToList();

                    */
                con.Close();
            }
        }
        return tablesList;
    }

我还创建了一个类TablesInfo 来填充其中的数据并使用强类型对象。但是,由于找不到填充它的方法,所以使用了SelectListItem。 由于它只包含表格列表,所以我不希望在每次刷新页面时都填充它。

【问题讨论】:

    标签: c# asp.net-mvc dropdown populate viewbag


    【解决方案1】:

    您不能将包含List&lt;User&gt;ViewBag 动态对象直接用于DropDownList HTML 助手,您需要将其转换为SelectList

    @Html.DropDownList("tableName", (SelectList)ViewBag.TableList, "Select Table")
    

    另外,DataFiller.GetTableNames() 方法调用应该返回SelectList 实例:

    class DataFiller
    {
        public SelectList GetTableNames()
        {
            // set select list items here
        }
    }
    

    注意:我非常喜欢使用强类型视图模型,而不是使用 ViewBagViewData 将列表传递给 HTML 助手,如下所示:

    @Html.DropDownListFor(model => model.tableName, Model.TableList as SelectList, "Select Table")
    

    相关问题:

    MVC3 DropDownList + ViewBag issue

    【讨论】:

    • 谢谢。我有点困惑——你们都建议使用强类型视图模型而不是 ViewBag。我的要求是只列出数据库中的表名。所以我正在通过静态类方法检索。使用模型方法,它不会在每次调用/刷新页面时检索表列表吗?如果是这样,那将是不必要的。所以我想到了这个选项。 DataFilter 返回 List GetTableNames()。我已经为表格数据创建了一个类,但也无法通过它来填充。在我的问题中添加了方法。谢谢
    • 谢谢@Tetsuya。正如您所建议的,我选择了强类型视图模型方法。实际上,我只是在 View 中有 @Html.DropDownListFor(model => model.TableName, Model.TableList, "Select Table", new { class= "form-control" }) 代码来绑定它。 Model.TableList 属于 SelectList 并且它们也不需要进行类型转换。正如我认为我对模型有点困惑,并且正如亚历山大展示了模型,我选择他的解决方案作为答案。非常感谢。我非常感谢。
    【解决方案2】:

    正如 Tetsuya 所说,您应该使用强类型视图模型。

    您可以像这样构建模型:

     public class MyUserCollection
        {
            public List<MyUser> Users { get; set; }
            public SelectList TableList { get; set; }
            public int TotalRows { get; set; }
    
            public MyUserCollection(string search, string sort, string sortdir, int skip, int pageSize)
            {
                TableList = DataFiller.GetTableNames();
    
                Users = GetUsers(search, sort, sortdir, skip, pageSize, out totalRecord);
            }
        }
    

    然后创建您的下拉菜单:

    @Html.DropDownListFor(model => model.tableName, Model.TableList as SelectList, "Select Table")
    

    否则,您需要投射对象:

    @Html.DropDownList("tableName", (SelectList)ViewBag.TableList, "Select Table")
    

    【讨论】:

    • 谢谢。我实现了您的解决方案,创建了一个单独的类,收集其中的所有数据并用作模型。非常感谢。
    • 由于问题被降级,我无法将您的解决方案设置为答案。
    【解决方案3】:

    请使用以下代码,希望对您的查询有所帮助。

    ViewBag.TableList = DataFiller.GetTableNames();
    
    @Html.DropDownList("ID", new SelectList(ViewBag.TableList, "ID", "Name"));
    

    【讨论】:

    • 感谢您的回复。
    • 没问题@TruptiDalia
    【解决方案4】:

    其实你也可以像下面这样:

    @Html.DropDownListFor(m => m.tableName, (IEnumerable<SelectListItem>)ViewBag.TableList ,"select table")
    

    【讨论】:

    • 谢谢。您的解决方案也有效;但我选择将其用作强类型视图模型。
    • 我猜这对于那些遇到类似问题的人来说可以替代。很高兴你也解决了你的问题。 =)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多