我想使用 .net mvc 创建一个嵌套表单,就像在 ruby on Rails form_for 上一样,用于我的视图。
我有一个具有一对多关系的模型。
// Principal (parent)
public class Blog
{
public int Id { get; set; }
public int Name { get; set; }
public ICollection<Post> Posts { get; set;}
}
// Dependent (child)
public class Post
{
public int Id { get; set; }
public int Title { get; set; }
public int BlogId { get; set; }
public Blog Blog { get; set; }
}
我有这个视图模型:
public class CreateBlogVM
{
public int Name { get; set; }
public ICollection<Post> Posts { get; set;}
}
以及初始化帖子的 GET 请求操作
[HttpGet]
public ActionResult<CreateBlogVM> Create()
{
var vm = new CreateBlogVM()
{
Posts = [new Posts { Title = "" }]
};
return View(vm);
}
在我看来,我想为 posts 属性创建一个嵌套表单,就像在 ruby on Rails 中一样
@model CreateBlogVM
<form asp method="post" asp-action="Create">
<div class="form-group col-4">
<label asp-for="Name" class="control-label">Name:</label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
@foreach (var post in @Model.Posts)
{
<div class="form-group col-4">
<label asp-for="@post.Title" class="control-label">Title:</label>
<input asp-for="@post.Title" class="form-control" />
<span asp-validation-for="@post.Title" class="text-danger"></span>
</div>
}
</form>
正在验证
POST
请求,我没有看到任何帖子。我错过了什么吗?我试图寻找有关嵌套表单或嵌套视图模型的文档。
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Create(CreateBlogVM model)
{
System.Console.WriteLine($"{string.Join("-", model.Posts)}"); <--- throws an error because Posts here is null
if (ModelState.IsValid)
{
await _blogService.Create(model);
return RedirectToAction(nameof(Index));
}
return View(model);
}
也许您错过了来自
Include
的模型加载中的 DbContext
语句?
例如:
var model = _context.Blogs
.Include(x => x.Posts) // <-- that line
.AsNoTracking()
.FirstOrDefault(x => x.Id == request.id);
或者,如果您确实在没有
DbContext
的情况下在控制器中构造对象,请尝试将 Dto
用作具有 View Model
属性的 List<Post>
。
例如:
public sealed record BlogDto
{
public int Id { get; set; }
public int Name { get; set; }
public List<PostDto> Posts { get; set;}
}
public sealed record PostDto
{
public int Id { get; set; }
public int Title { get; set; }
public int BlogId { get; set; }
}
并配置
AutoMapper
,文档在这里。