ASP.NET Core 6 MVC 页面创建带有复杂对象列表的对象
我有以下模型,需要通过页面创建:
public class Exercise
{
public Guid Id{ get; set; }
public string Name { get; set; }
public string Description{ get; set; }
public ICollection<ExerciseCategory> Categories
...
public ICollection<Link> Links { get; set; }
}
public class ExerciseCategory
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
public class Link
{
public string Name { get; set; }
public string Value { get; set; }
}
我有一个视图,可以让我创建此对象,但我缺少属性 Exercise.Links
的表单控件:
<form id="profile-form" method="post">
<div class="row">
<div class="col-12 p-sm-2 p-md-3 p-lg-5 bg-custom-white rounded-4">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-floating mt-2 mb-2">
<input asp-for="Input.Name" class="form-control" />
<label asp-for="Input.Name" class="form-label"></label>
<span asp-validation-for="Input.Name" class="text-danger"></span>
</div>
<div class="form-floating mt-2 mb-2">
<input asp-for="Input.Description" class="form-control" />
<label asp-for="Input.Description" class="form-label"></label>
<span asp-validation-for="Input.Description" class="text-danger"></span>
</div>
<div class="form-floating mt-2 mb-2">
<select asp-for="Input.CategoryIds"
asp-items="Model.Input.Categories" class="form-control"></select>
<label asp-for="Input.Categories" class="form-label"></label>
</div>
<button id="create-exercise-button" type="submit" class="w-100 btn btn-lg btn-primary">Create</button>
</div>
</div>
</form>
属性 Exercise.Categories
很简单,因为 Category
是一个单独创建的实体,所以我只有一个列出现有类别的下拉列表。
Link
只是一个值对象,它本身并不持久。因此,用户应该能够从 Exercise
创建/编辑页面创建/删除/编辑Link
。
我已尝试以下操作:
@for (var i = 0; i < Model.Input.Links.Count; i++)
{
<div>
<input asp-for="Input.Links[i].Name">
<input asp-for="Input.Links[i].Value">
</div>
}
生成以下 HTML:
<div>
<input type="text" id="Input_Links_0__Name" name="Input.Links[0].Name" value="some link">
<input type="text" id="Input_Links_0__Value" name="Input.Links[0].Value" value="https://somelink.com">
</div>
<div>
<input type="text" id="Input_Links_1__Name" name="Input.Links[1].Name" value="some link1">
<input type="text" id="Input_Links_1__Value" name="Input.Links[1].Value" value="https://somelink1.com">
</div>
但这在回发时不会填充 Input.Links 属性。
我开始认为问题在于我的列表是 Link
列表而不是原始类型列表。为了测试这一点,我向名为 Links1
的输入模型添加了一个测试 List
,并尝试像之前一样填充该列表:
<div class="form-floating mt-2 mb-2">
<input asp-for="Input.Links1[i]" data-val="true" class="form-control" />
<label asp-for="Input.Links1[i]" class="form-label"></label>
</div>
这有效。提交表单后,我将填充的列表返回到控制器中,这证实了问题是 List
如何添加表单控件来填充属性 Exercise.链接
(这是一个List
)?
I have the following model, which needs to be created via a page:
public class Exercise
{
public Guid Id{ get; set; }
public string Name { get; set; }
public string Description{ get; set; }
public ICollection<ExerciseCategory> Categories
...
public ICollection<Link> Links { get; set; }
}
public class ExerciseCategory
{
public Guid Id { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
public class Link
{
public string Name { get; set; }
public string Value { get; set; }
}
I have a view that lets me create this object, but I miss a form control for the property Exercise.Links
:
<form id="profile-form" method="post">
<div class="row">
<div class="col-12 p-sm-2 p-md-3 p-lg-5 bg-custom-white rounded-4">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<div class="form-floating mt-2 mb-2">
<input asp-for="Input.Name" class="form-control" />
<label asp-for="Input.Name" class="form-label"></label>
<span asp-validation-for="Input.Name" class="text-danger"></span>
</div>
<div class="form-floating mt-2 mb-2">
<input asp-for="Input.Description" class="form-control" />
<label asp-for="Input.Description" class="form-label"></label>
<span asp-validation-for="Input.Description" class="text-danger"></span>
</div>
<div class="form-floating mt-2 mb-2">
<select asp-for="Input.CategoryIds"
asp-items="Model.Input.Categories" class="form-control"></select>
<label asp-for="Input.Categories" class="form-label"></label>
</div>
<button id="create-exercise-button" type="submit" class="w-100 btn btn-lg btn-primary">Create</button>
</div>
</div>
</form>
The property Exercise.Categories
is easy as Category
is an entity which is created separately, so I just have a dropdown listing the existing categories.
Link
is just a value object that is not persisted on its own. Therefore, the user should be able to create/remove/edit Link
from the Exercise
create/edit page.
I have tried the following:
@for (var i = 0; i < Model.Input.Links.Count; i++)
{
<div>
<input asp-for="Input.Links[i].Name">
<input asp-for="Input.Links[i].Value">
</div>
}
Which results in the following HTML:
<div>
<input type="text" id="Input_Links_0__Name" name="Input.Links[0].Name" value="some link">
<input type="text" id="Input_Links_0__Value" name="Input.Links[0].Value" value="https://somelink.com">
</div>
<div>
<input type="text" id="Input_Links_1__Name" name="Input.Links[1].Name" value="some link1">
<input type="text" id="Input_Links_1__Value" name="Input.Links[1].Value" value="https://somelink1.com">
</div>
But this doesn't populate the Input.Links property when posting back.
I started thinking that the problem is the fact that my list is a list of Link
rather than a list of primitive types. In order to test this, I added a test List<string>
to input model called Links1
and tried to populate that list as I did before:
<div class="form-floating mt-2 mb-2">
<input asp-for="Input.Links1[i]" data-val="true" class="form-control" />
<label asp-for="Input.Links1[i]" class="form-label"></label>
</div>
This works. I get the populated list back in the controller after submitting the form, which confirms the problem is the List<Link>
How can I add a form control for populating the property Exercise.Link
(which is a List<Link>
)?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
阅读这个答案是另一个问题,我弄清楚了问题所在:
这是由于
链接
是域模型。在这种情况下,解决方案是创建一个具有public{get;的演示层模型。设置;}
并在表单上而不是域模型上使用它。因此,要正确回答问题,这是您可以编写表单控件来编辑
list&lt; link&gt;
:After reading this answer to another question, I figured out what the problem was:
This is due to
Link
being a domain model. The solution in this case was to create a presentation layer model that has public{get; set;}
and use that on the form instead of the domain model.So, to answer the question properly, this is how you could write a form control to edit a
List<Link>
: