ASP.NET Core:为 List 类型的模型属性创建表单输入

Posted

技术标签:

【中文标题】ASP.NET Core:为 List 类型的模型属性创建表单输入【英文标题】:ASP.NET Core : creating form input for model property of type List 【发布时间】:2021-12-16 05:27:49 【问题描述】:

我一直在网上搜索这个特定问题的答案,但似乎找不到。

我目前正在使用 Razor 页面创建表单,但不知道如何创建能够为表单中的一个项目获取多个值的表单输入。下面我将发布一个简单的例子来说明我的意思。

当前问题:当我以编程方式添加另一个输入时,它最多只会添加 2 个并且不会发送值

型号:

public class FormInput 

    public List<Address> Addresses  get; set; 
    public List<Category> Categories  get; set; 

剃刀页面:

public class FormPage : PageModel

    [BindProperty] public FormInput _Input  get; set; 

html 页面:

<form>
    <ul class="Category-Container">
      <li>
        <input asp-for="_Input.Addresses" type="text" />
        <button type="button" onclick="this.AddCategory">
        Add New Address
        </button>
      </li>
    </ul>
    <div>
        <input asp-for="_Input.Categories" type="text" />
        <button type="button" onclick="this.AddNewInput">
        Add New Category
        </button>
    </div>
</form>

javascript

var categoryContainer = document.getElementById("Category-Container");

 function AddCategory() 

        var input = document.createElement("input");
        input.classList.add("w-100");
        input.name = "BusinessCategory";
        var inputCol = document.createElement("div");
        inputCol.classList.add("col-8");
        inputCol.appendChild(input);

        var btn = document.createElement("button");
        btn.classList.add("btn");
        btn.classList.add("btn-primary");
        btn.innerText = "Add New Category";
        var btnCol = document.createElement("div");
        btnCol.classList.add("col");
        btnCol.appendChild(btn);

        var row = document.createElement("li");
        row.classList.add("row");
        var part1 = row.appendChild(inputCol);
        var part2 = part1.appendChild(btnCol);

        categoryContainer.appendChild(part2);
    

javascript 函数中存在一些脱节,但您可以假设 HTML 示例中的 Button 和 Input 也在 Columns 中,我认为这不会有很大的不同,但请告诉我是否会一个

【问题讨论】:

嗨@Myles Frazier,您能分享一下您的this.AddNewInput 方法吗? 已更新,并简要说明下面的细微差别 嗨@Myles Frazier,您似乎想从代码中将类别添加到地址?你的两个模型关系是什么?此外,标签助手无法将复杂模型传递给后端,因此asp-for="_Input.Addresses" 不正确。如果要将数据发布到后端,输入应为:asp-for="_Input.Addresses[0].PropertyName"。请与我们分享您的模型。 嗨@Myles Frazier,我的回答是否帮助您解决了您的问题?如果是这样,你能接受作为答案吗?如果没有,你能跟进让我知道吗?参考:How to accept as answer。谢谢。 谢谢你 【参考方案1】:

标签助手不能将复杂的模型类型数据传递给后端,它只允许简单类型。也就是说,需要在asp-for中设置模型的属性名。

然后,如果要获取列表模型,则需要特定的列表索引,例如:_Input.Categories[0].PropertyName

不确定你的整体观点是什么,这里有一个关于如何将列表模型传递给后端的简单演示:

型号:

public class FormInput

    public List<Address> Addresses  get; set; 
    public List<Category> Categories  get; set; 

public class Address

    public string Name  get; set; 

public class Category

    public string BusinessCategory  get; set; 

查看:

@page
@model IndexModel
<form method="post">
    <ul id="Category-Container">
        <li>
            <input asp-for="_Input.Categories[0].BusinessCategory" type="text" />
            <button type="button" onclick="AddCategory()">
                Add New Address
            </button>
        </li>
    </ul>
    <div>
        <input asp-for="_Input.Addresses[0].Name" type="text" />
        <button type="button" onclick="this.AddNewInput">
            Add New Category
        </button>
    </div>
    <input type="submit" value="Post"/>
</form>

JS:

@section Scripts

<script>
    var count = 1;  //add count...
    var categoryContainer = document.getElementById("Category-Container");

    function AddCategory() 

        var input = document.createElement("input");
        input.classList.add("w-100");
   //change the name here.....
        input.name = "_Input.Categories["+count+"].BusinessCategory";
        var inputCol = document.createElement("div");
        inputCol.classList.add("col-8");
        inputCol.appendChild(input);

        var btn = document.createElement("button");
        btn.classList.add("btn");
        btn.classList.add("btn-primary");
        btn.innerText = "Add New Category";
        var btnCol = document.createElement("div");
        btnCol.classList.add("col");
        btnCol.appendChild(btn);

        var row = document.createElement("li");
        row.classList.add("row");
        var part1 = row.appendChild(inputCol);
        part1.appendChild(btnCol); //change here...

        categoryContainer.appendChild(part1);  //change here...
        count++;  //add here ...
    
</script>

后端代码:

public class IndexModel: PageModel

    [BindProperty] public FormInput _Input  get; set; 

    public IActionResult OnGet()
    

        return Page();
    
    public void OnPost()
    

    

【讨论】:

以上是关于ASP.NET Core:为 List 类型的模型属性创建表单输入的主要内容,如果未能解决你的问题,请参考以下文章

Asp.net Core 模型绑定器接受布尔类型的随机整数

ASP.NET Core 中的模型绑定

ASP.Net Core MVC 如何针对强类型模型发布未知数量的字段

ASP.NET Core 的当前上下文中不存在名称“模型”

ASP.NET Core ApiAuthorizationDbContext 没有为数据模型创建表

ASP.NET Core:为所有模型生成 Razor 页面