ASP.Net Core MVC how to post unknown number of fields against strongly-typed model
完全被这件事难住了。我有一个页面,用户可以在其中单击"添加步骤"按钮,并且一些 javascript 将带有来自
我查看了以下帖子,但这里的答案似乎都没有帮助(不确定是不是因为我正在使用 .Net 核心 - 可能不是):
在 ASP MVC 中获取未知数量变量的发布数据
使用可变数量的输入从表单传递数据 - MVC 5
模型(Procedure.cs)
1 2 3 4 5 6 7 8 | public class Procedure { public int Id { get; set; } public string Name { get; set; } public string Type { get; set; } public int MinNumber { get; set; } public int MaxNumber { get; set; } } |
控制器 (ProceduresController.cs)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | [HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> Create([FromForm]List<Procedure> model) { if (ModelState.IsValid) { foreach(var field in model) { // Database things will happpen eventually, but at this point the Count = 0 } } return View(model); } |
目前
还有视图 (Create.cshtml)
我删除了很多 UI 和 javascript 以使内容更易于阅读
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 | @model List<Procedure> /* also tried @model Procedure */ @{ ViewData["Title"] ="Create Procedure"; ViewData["Sidebar"] ="App"; } <form asp-action="Create" enctype="multipart/form-data"> <label class="field-label">Instruction Name</label> <input type="text" name="Name" class="field type:text" placeholder="Enter an instruction name" /> <label for="Type" class="field-label">Instruction Type</label> <select id="Type" name="Type" class="field type:select stretch"> /* removing for brevity */ </select> <label class="field-label">Minimum Number</label> <input type="number" name="MinNumber" class="field type:number" /> <label class="field-label">Maximum Number</label> <input type="number" name="MaxNumber" class="field type:number" /> Add Step <input type="submit" value="Submit Procedures" class="button button-submit" /> </form> <template id="template"> <details class="accordion" open> <summary>Procedure Step</summary> <label class="field-label">Instruction Name</label> <input type="text" name="Name" class="field type:text" placeholder="Enter an instruction name" /> <label for="Type" class="field-label">Instruction Type</label> <select id="Type" name="Type" class="field type:select stretch"> /* removing for brevity */ </select> <label class="field-label">Minimum Number</label> <input type="number" name="MinNumber" class="field type:number" /> <label class="field-label">Maximum Number</label> <input type="number" name="MaxNumber" class="field type:number" /> </details> </template> @section Scripts { @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } const modal = new Modal(); function getParent(element, selector) { for (; element && element !== document; element = element.parentNode) { if (element.classList.contains(selector)) { return element; } } return null; } this.Builder = function () { this.template = document.querySelector('#template'); this.builder = document.querySelector('.builder'); this.addStep = document.querySelector('.add-step'); this.clone = null; this.counter = 0; this.addStep.addEventListener('click', this.add.bind(this)); }; Builder.prototype = { add: function () { this.counter++; this.clone = document.importNode(this.template.content, true); this.builder.appendChild(this.clone); // i'm doing things here to set the new field attribute values - removed for brevity } }; let builder = new Builder(); builder.add(); } |
我是否需要在 javascript 中以特定方式设置新字段
我都尝试了,但回发时计数仍然为 0。我几乎碰壁了,所以我很感激任何和所有的帮助。
.NET 对复杂类型的模型绑定需要更多的努力。元素的命名很重要。
1 2 3 4 | <input name="model[index].Name" /> <input name="model[index].Type" /> <input name="model[index].MinNumber" /> <input name="model[index].MaxNumber" /> |
要绑定的命名约定是:控制器(模型)中的参数名称、索引、属性名称。这会将所有对象正确传递到您的列表。
如果您将对象传递给模型内的列表,情况也是如此。
例如
1 2 3 4 | public class Example { public int Id { get; set; } public List<Procedure> Procedures { get; set; } } |
在这种情况下,我们只需要告诉 .NET 你也在映射什么属性。
1 | <input name="model.Procedures[index].Name" /> |
在某些情况下,您可能还需要为索引添加隐藏字段:https://www.red-gate.com/simple-talk/dotnet/asp-net/model-binding-asp-net-core /