将 Razor 页面上的下拉列表绑定到数据库表

Binding Dropdown list on Razor Page to Database Table

提问人:MelB 提问时间:6/11/2022 最后编辑:Timothy G.MelB 更新时间:6/15/2022 访问量:3598

问:

我是剃须刀页面、asp.net 和 Visual Studio 的绝对初学者。我按照 asp.net 和剃须刀页面上的精彩教程开始使用 YouTube。

然而,现在我被困住了。我正在尝试做什么:

我有一个页面 Create.cshtml,用户在其中输入数据并将其发布到数据库表 (InfoSite)。这效果很好,但我想为其中一个字段创建一个下拉列表。我可以在下拉列表中创建一个静态列表,但我想创建一个基于另一个数据库表 (ResCategory) 中的值的下拉列表,以便用户可以在需要时更新这些 ResCategory 值,然后它们将自动显示在下拉列表中。

我现在有一部分工作。Create.cshtml 页面上的下拉列表将读取 ResCategory 表中的值,但当我单击“提交”按钮添加该记录时,它不会将下拉框选择发布/绑定到 InfoSite 表。不过,它会发布/绑定该页面中的所有其他内容。

很可能,我错过了一些简单的东西,但就是无法弄清楚是什么。我现在最大的问题之一是还不知道某些代码需要“去哪里”!

这是我到目前为止所拥有的:

在 Create.cshtml 页面上,我有以下代码:

<select id="ResType" asp-items="@(new SelectList(Model.displayResCatdata,"ID","Description"))" class="form-select">  
                        <option value="" selected disabled>---Select Residence Type---</option>
</select>

在 Create.cshtml.cs 上,我有这个:

public IEnumerable<ResCategory> displayResCatdata { get; set; }

    public async Task OnGet()
    {
        displayResCatdata = await _db.ResCategory.ToListAsync();
    }

    public async Task<IActionResult> OnPost()
    {
        await _db.InfoSite.AddAsync(InfoSite);
        await _db.SaveChangesAsync();
        TempData["success"] = "Site Information added successfully.";
        return RedirectToPage("Index");
    }

然后,在我的InfoSite.cs上,我有:

    public class InfoSite
    {
        [Key]
        public int ID { get; set; }
        [Required]
        public string Name { get; set; }
        [Display(Name = "Office Type")]
        public string? Specialty { get; set; }
        [Display(Name = "Res Type")]
        public string? ResType { get; set; }
        [Display(Name = "Res Sub Type")]
        public string? ResSubType { get; set; }.....

我确定我不应该把“公共字符串?对于 Res Type { get; set; },但我不确定该使用什么。另外,我认为其他地方一定有什么不对劲。

有人可以就我可能遗漏的内容以及我可能遗漏的确切位置给出具体指示吗?

asp.net 数据绑定 实体框架核心 下拉列表 razor-pages

评论

0赞 devlin carnate 6/11/2022
我不是剃刀页面专家,但我注意到的一件事是您的元素没有 name 属性。name 属性应与模型上的属性名称匹配。可以使用 F12 开发人员工具的“网络”选项卡检查表单提交的 POST,或在接收 POST 的服务器端方法上放置断点,并检查模型在其中的填充方式。select
0赞 MelB 6/11/2022
对不起,我不明白你的意思。您能否告诉我,当您提到没有 name 属性的 select 元素时,您指的是哪里 - 以及您所说的“模型上的属性”是什么意思?正如我所说,我对此非常非常陌生。也许举一个“更正”的例子?谢谢!
0赞 devlin carnate 6/13/2022
您的标签没有属性。POST 需要 name 属性才能将标记与模型相关联。因此,例如:<select>name<select name="SomeModelPropertyName" id="ResType">
0赞 MelB 6/14/2022
我把 Id 和名字混淆了。不好意思。我在我的<选择中添加了一个名称=“ResType”...>在我的 Create.cshtml 页面上,当我提交数据时,它仍然没有填充表中的选定值。名称是否应与 InfoSite.cs 文件上的字段名称匹配?即,我想用该值填充的字段是:public string?ResType { get; set; }回到你的第一个回复,我认为以上就是你的意思。所以,我现在有 <select name=“ResType” ...匹配上述内容,但它仍然不起作用。
0赞 devlin carnate 6/14/2022
如果 Model 属性的名称为 ResType,则 select 标记的 name 属性应为 ResType。您是否使用 F12 开发人员工具中的“网络”选项卡检查了 POST 的确切内容?您应该能够确切地看到正在发布的内容。ResType 是否正在发布?如果它根本没有发布,请确保 select 标签位于表单标签内。

答:

0赞 Martin Petrov 6/11/2022 #1

您没有将数据传递到控制器中的方法。

解决方案:

public async Task<IActionResult> OnPost(InfoSite InfoSite)
{
    await _db.InfoSite.AddAsync(InfoSite);
    await _db.SaveChangesAsync();
    TempData["success"] = "Site Information added successfully.";
    return RedirectToPage("Index");
}

public IActionResult OnPost()
{
    var infoSite = new InfoSite();
    return this.View(infoSite);
}

public async Task<IActionResult> OnPost(InfoSite InfoSite)
{
    await _db.InfoSite.AddAsync(InfoSite);
    await _db.SaveChangesAsync();
    TempData["success"] = "Site Information added successfully.";
    return RedirectToPage("Index");
}

评论

0赞 MelB 6/13/2022
将“InfoSite InfoSite”添加到“public async Task<IActionResult> OnPost()”不起作用。当我提交测试条目时,除了在 ResCategory 下拉列表中选择的值之外,所有内容都发布到 InfoSite 表。同样,ELSE 的所有内容都正常发布,只是不是下拉列表中的值。
0赞 MelB 6/13/2022
还尝试了“Or”建议,但“View”产生了一个我不知道如何解决的错误。“CreateModel”不包含“View”的定义,并且找不到接受 PHECWeb “CreateModel”类型的第一个参数的可访问扩展方法“View”(是否缺少 suing 指令或程序集引用?
4赞 MelB 6/14/2022 #2

经过反复试验,阅读,阅读,阅读,我回答了自己的问题。

实际上,缺少的是我的 Create.cshtml 页面上的一件小事。

我缺少“asp-for”以绑定所选选项。所以,而不是:

<select id="ResType" asp-items="@(new SelectList(Model.displayResCatdata,"ID","Description"))" class="form-select">  
                        <option value="" selected disabled>---Select Residence Type---</option>
</select>

我应该有:

<select asp-for="InfoSite.ResType" id="Select1" class="form-select" asp-items="@(new SelectList(Model.DisplayResCatData,"ID", "Description"))"><option value="" selected disabled>---Select Residence Type---</option></select>

我唯一剩下的问题是,即使 ID 被绑定,我也希望能够绑定描述,因为这是我真正想要的 InfoSite 表,但至少它是绑定的。这将是另一个线程的问题!

评论

0赞 MelB 11/4/2022
还想出了如何绑定描述。这也是一个简单的变化。而不是:@(new SelectList(Model.DisplayResCatData,“ID”, “Description”)),我应该有:@(new SelectList(Model.DisplayResCatData,“Description”, “Description”))。第二个参数需要更改为“描述”。这就是它的全部内容!