【问题标题】:Select TagHelper Using List from ViewBag使用 ViewBag 中的列表选择 TagHelper
【发布时间】:2015-10-26 13:46:04
【问题描述】:

我目前正在尝试在 asp.net 5 中使用 taghelper。我想使用带有 ViewBag 列表的 select tag helper。我在 asp-for 字段中输入的任何内容都会给我一个错误,因为它试图从 IEnumerable 而不是视图包的模型中提取它。

我想替换这个:

@model IEnumerable<InvoiceIT.Models.Invoice>
@using (Html.BeginForm())
{
    <p>            
        @Html.DropDownList("Companies", String.Empty)       
        <input type="submit" value="Filter" class="btn btn-default" />
    </p>
}

用这个:

@model IEnumerable<InvoiceIT.Models.Invoice>
<form asp-controller="Invoice" asp-action="Index" method="post" class="form-horizontal" role="form">
    <select asp-for="????" asp-items="ViewBag.Companies" class="form-control">
    </select>
    <input type="submit" value="Save" class="btn btn-default" />
</form>

这是我在控制器中填充选择列表的方式:

ViewBag.Companies = new SelectList(await DbContext.Company.ToListAsync(), "CompanyID", "Name");

【问题讨论】:

    标签: c# asp.net-core asp.net-core-mvc tag-helpers


    【解决方案1】:

    如果您不希望 asp-for 属性直接从 Model 中提取,您可以通过提供 @ 来覆盖该行为。

    又名:

    <select asp-for="@ViewBag.XYZ">
        ...
    </select>
    

    因此,根据你所说的,我相信你的位会变成:

    @model IEnumerable<InvoiceIT.Models.Invoice>
    <form asp-controller="Invoice" asp-action="Index" method="post" class="form-horizontal" role="form">
    @{
        SelectList companies = ViewBag.Companies;
        var currentlySelectedIndex = 0; // Currently selected index (usually will come from model)
    }
        <select asp-for="@currentlySelectedIndex" asp-items="companies" class="form-control">
        </select>
        <input type="submit" value="Save" class="btn btn-default" />
    </form>
    

    希望这会有所帮助!

    【讨论】:

    • 使用您的确切代码我在 asp-for 字段上得到一个编译错误:“表达式树可能不包含动态操作”。
    • 啊,好点子。更新响应以反映正确用法(请参阅 @{ } 中的添加位)。
    • 这似乎在编译时越来越接近,但是它添加了一个列表框类型控件而不是下拉列表,并且它是空的数据。如果我将其更改为asp-for="@companies" asp-items="@ViewBag.Companies",那么我会得到相同的列表框,但其中包含正确的数据。如何获得下拉菜单?
    • 对不起@Reafidy,我的反应太快了,而且手指发胖了一些东西。更新了答案以反映正确的用法。至于它为什么起作用的细节。如果提供给asp-for 的值恰好是IEnumerable(而不是string),则它不会呈现为下拉列表。否则它会:)
    • 谢谢,这行得通,现在它变得比只使用老式的要冗长得多:@Html.DropDownList
    【解决方案2】:

    asp-for 只需要是当前选中值的属性,asp-items 需要是一个

    IEnumerable<SelectListItem>
    

    这个 sn-p 来自我项目中的工作代码:

    <select id="CompanyCountry" asp-for="CompanyCountry"
               asp-items="Model.AvailableCountries" class="form-control"></select>
    

    在我使用的模型中

    IList<SelectListItem> 
    

    适用国家/地区

    【讨论】:

    • 所以你的例子看起来像 ViewBag.CompanyID 应该在 asp-for 和 asp-items 应该是代表公司的选择列表项的列表
    • 嘿乔,我已经更新了这个问题。当我将 companyID 放在 asp-for 字段中时,我收到一个错误:'IEnumerable 不包含 companyID 的定义'。我相信这是因为我试图将 viewbag 用作源,而 companyid 仅存在于 viewbag 源中,而不存在于模型中。
    • 您尝试过使用@ViewBag.companyID 吗?我确实认为 asp-for 用于模型绑定,而 viewbag 用于显示。 asp-for 应该是模型的一个属性,它包含一个与 selectlistitems 中的值相对应的值。想法是获取属性的当前值将被选中,如果用户选择不同的值并提交表单,新选择的值将在表单发布时自动绑定到模型属性,以便您保存具有新选定值的模型
    • 是的,我做到了,但出现编译错误:“表达式树可能不包含动态操作”。我要使用的选择列表是 pages 表的过滤器下拉列表。它与编辑模型无关,因此 companyid 不应该在模型中。
    • 在那种情况下你可能根本不需要设置 asp-for,只需要设置 asp-items。
    【解决方案3】:

    你可以这样试试……

    @Html.DropDownListFor(model => model.Id_TourCategory, new SelectList(ViewBag.TourCate, "Value", "Text"))
    
     public ActionResult TourPackage()
        {
            List<TourCategory> lst = new List<TourCategory>();
            lst = db.TourCategories.ToList();
            ViewBag.TourCate = new SelectList(lst, "Id", "CategoryName");          
            return View();
        }
    

    【讨论】:

    • 嗯,谢谢,但我的代码适用于 DropDownList,关键是我正在尝试使用 taghelper。
    猜你喜欢
    • 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
    相关资源
    最近更新 更多