【问题标题】:How to properly display checkbox form controls in ASP.NET Core Views?如何在 ASP.NET Core 视图中正确显示复选框表单控件?
【发布时间】:2021-10-07 03:01:39
【问题描述】:

我有一个带有布尔属性的模型,它将在我的视图中显示为复选框:

public class SomeModel
{
    public bool SomeProperty { get; set; }
}

我正在创建这样的视图:

<div class="form-check">
    <input asp-for="TestProperty" value="true" class="form-check-input" />
    <label class="form-check-label" asp-for="TestProperty"></label>
</div>

以下是浏览器中的 HTML 输出:

<div class="form-check">
    <input value="true" class="form-check-input" type="checkbox" data-val="true" data-val-required="The TestProperty field is required." id="TestProperty" name="TestProperty">
    <label class="form-check-label" for="TestProperty">TestProperty</label>
</div>

我可以看到下面的隐藏元素附加在表单的末尾:

<input name="TestProperty" type="hidden" value="false">

当我提交表单时,这是请求正文:

TestProperty: true
TestProperty: false

第一行中的值是复选框元素中的值,第二行是隐藏元素的值,当在控制器中接收到时会覆盖第一行值。我注意到,当我单击复选框时,隐藏输入的值不会改变。

想到的第一个解决方案是在输入值更改时通过 JavaScript 更新隐藏元素,这是不必要的。有什么办法可以摆脱这些隐藏的元素?或者我没有正确显示表单控件。我不确定。

更新

隐藏的输入元素由剃刀视图本身自动添加。虽然我使用的是控制器/视图而不是 razor 视图,但我测试了 Enrico 的解决方案,结果是一样的。它仍然为复选框附加了一个隐藏的输入元素:

【问题讨论】:

    标签: c# asp.net asp.net-core razor


    【解决方案1】:

    您无需手动添加隐藏输入字段,也无需通过客户端 Javascript 代码与之交互。使用 ASP.NET 核心和 Razor 的方法是使用标签助手,让 Razor 自己完成实际的 HTML 生成。

    这是在页面输入模型中使用 Razor 页面和单个布尔值的示例。我在 Visual Studio 2019 中使用了 ASP.NET Core 3.1 和常用的 ASP.NET Core Web 应用程序模板。

    这是页面模型:

    public class TestFormModel : PageModel
      {
        private readonly ILogger _logger;
    
        public TestFormModel(ILogger<TestFormModel> logger)
        {
          _logger = logger;
        }
    
        [BindProperty]
        public InputModel Input { get; set; }
    
        public IActionResult OnGet()
        {
          this.Input = new TestFormModel.InputModel
          {
            ShowUsername = false
          };
    
          return this.Page();
        }
    
        public IActionResult OnPost() 
        {
          if (!this.ModelState.IsValid) 
          {
            return this.Page();
          }
    
          _logger.LogInformation("The posted value is: {Value}", this.Input.ShowUsername);
    
          return this.RedirectToPage("Index");
        }
    
        public class InputModel 
        {
          [Display(Name = "Show User Name")]
          public bool ShowUsername { get; set; }
        }
      }
    

    这是关联的 Razor 视图:

    @page
    @model StackoverflowTest.Pages.TestFormModel
    @{
      ViewData["Title"] = "How to build a form with a checkbox";
    }
    
    <h1>@ViewData["Title"]</h1>
    
    <form asp-page="TestForm">
      <div class="form-check">
        <input class="form-check-input" asp-for="Input.ShowUsername">
        <label class="form-check-label" asp-for="Input.ShowUsername"></label>
      </div>
      <button type="submit" class="btn btn-primary">Submit</button>
    </form>
    

    就是这样。您无需在表单中手动添加隐藏输入。您只需要使用正确的标签帮助,ASP.NET 核心就会为您生成正确的表单和表单输入。

    2021 年 8 月 2 日更新

    有关工作示例,请参阅 this github repository

    作为旁注,请考虑隐藏输入字段是由 ASP.NET 核心自动添加的,并且当表单中的复选框为未选中。

    在生成的 HTML 页面源代码中,Input.ShowUsername 基本上有 两个 表单输入。其中一个是具有type="checkbox" 的HTML 输入,另一个是具有type="hidden" 的HTML 输入。 name 属性 (name="Input.ShowUsername") 的值相同,而 value 属性对于复选框输入是 true,对于隐藏输入是 false

    这是表单的 HTML 页面源代码(与 ASP.NET core 3.1 生成的方式完全相同):

    <form action="/TestForm" method="post">
      <div class="form-check">
        <input class="form-check-input" type="checkbox" data-val="true" data-val-required="The Show User Name field is required." id="Input_ShowUsername" name="Input.ShowUsername" value="true">
        <label class="form-check-label" for="Input_ShowUsername">Show User Name</label>
      </div>
      <button type="submit" class="btn btn-primary">Submit</button>
      <input name="__RequestVerificationToken" type="hidden" value="CfDJ8AHG4SVs1BBFruMHNiza3QNKvHNf96d_oiz5J6n3eYuncnlFKqvL4x3G6jbAOmNfJjrwk_crqFN99kjZiBVoboFGd0VQIBlrvmp9fL6p8CMbiZ4f6Cf4rm3OpGZEZ_04UQQ5iuUi3nVjfIgfb5-vctw" />
      <input name="Input.ShowUsername" type="hidden" value="false">
    </form>
    

    当表单中的复选框被选中时,值true 被发送到名称Input.ShowUsername 的服务器,当取消选中复选框时,值false 被发送到名称Input.ShowUsername 的服务器上: 这是可行的,因为未选中复选框的值不会发布到服务器

    使用type="hidden" 添加输入是在复选框未选中时发布默认值的常见模式,请参阅here 了解有关 HTML 复选框工作方式的说明。

    同样,所有这些都是由 ASP.NET 核心自动为您生成的:您只需定义页面输入模型并使用适当的 Razor 标签助手。

    【讨论】:

    • 谢谢恩里科。我使用与您的答案相同的剃须刀页面对此进行了测试。但隐藏的元素仍然存在。我用您的答案的表单 HTML 输出的屏幕截图更新了我的答案。
    • @mfshujaie 这是一个实现细节。老实说,我没有检查生成的页面源。这个解决方案对你有用吗?我已经在本地进行了测试,它按我的预期工作。如果选中该复选框,则在 OnPost 方法中可以使用 True 值,如果未选中该复选框,则会发布 False 值。这对你有用吗?
    • 不,它不起作用。当我提交表单时,隐藏输入的值会覆盖复选框的值。我必须从输入中删除 asp-for 并自己填充名称和值,然后它才能工作。
    • @mfshujaie 您是否尝试在您的应用程序中复制并粘贴完全相同的代码?我觉得它对你不起作用真的很奇怪。您使用的是 ASP.NET 核心 3.1 吗?
    • @mfshujaie 我会将我的工作示例推送到 github。我将使用指向工作示例的 URL 更新答案,以便您可以下载它并将其与您的解决方案进行比较。
    猜你喜欢
    • 2011-08-17
    • 2011-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多