ASP.Net 核心 Razor 页面动态列表
ASP.Net Core Razor Pages dynamic list
我想创建一个带有 Razor 页面的网站来维护 spaces 和相应的房间。
所以,在我的模型中,space 有一个房间列表。
public class Space
{
public int Id { get; set; }
public string SpaceName { get; set; }
public List<Room> Rooms { get; set; }
public Space()
{
this.Rooms = new List<Room>();
}
}
在create.cshtml我想动态添加和删除房间
<h1>Create New Space</h1>
<form method="post">
<div class="form-group">
<label for="Space.SpaceName">Space Name</label>
<input type="text" class="form-control" asp-for="Space.SpaceName" placeholder="Enter space name">
<span asp-validation-for="Space.SpaceName" ></span>
</div>
@if(Model.Space != null){
for (int i = 0; i < Model.Space.Rooms.Count; i++)
{
<input asp-for="@i" type="hidden" />
<div class="form-group">
<label for="SpaceName">Room Name</label>
<input type="text" class="form-control" asp-for="Space.Rooms[i].Name" placeholder="Enter space name">
<span asp-validation-for="Space.Rooms[i].Name" ></span>
</div>
<button type="submit" asp-page-handler="removeroom" asp-route-index="@i">Remove Room</button>
}
}
<button type="submit" asp-page-handler="addroom">Add Room</button>
<button type="submit" asp-page-handler="submit" class="btn btn-primary">Submit</button>
</form>
PageModel 如下所示:
public class CreateModel : PageModel
{
readonly SpaceRepository spaceRepository;
public CreateModel(SpaceRepository spaceRepository)
{
this.spaceRepository = spaceRepository;
}
[BindProperty]
public Space Space { get; set; }
public async Task<IActionResult> OnPostSubmitAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
spaceRepository.Create(Space);
return RedirectToPage("./Index");
}
public async Task OnPostAddRoomAsync()
{
Space.Rooms.Add(new Room());
}
public async Task OnPostRemoveRoomAsync(int index)
{
Space.Rooms.RemoveAt(index);
}
}
到目前为止它按预期工作,但是当我创建例如 3 个房间并删除第一个或第二个房间时,它总是删除最后一个。
页面似乎没有收到处理程序后的操作列表post。
知道缺少什么吗?
感谢您的帮助!
我知道你可能不再需要它了,但我对此也有疑问,所以我在 github 上开了一个问题,我得到了你问题的答案:https://github.com/aspnet/Mvc/issues/8373
所以基本上 MVC 是往返模型,所以字段可以保持填充状态。因此,页面模型使用最后已知的模型状态来填充每个字段。您可以在删除项目后使用 Modelstate.Clear()
来解决此问题。由于这一点,您在从列表中删除项目后也不会显示任何验证消息。
索引必须按顺序排列,不能有间隙。如果您有这样的数组或列表:
rooms[0] = "Room 1"
rooms[1] = "Room 2"
rooms[2] = "Room 3"
它将 post 正确。但是,如果您删除 rooms[1]
,它只会 post rooms[0]
并跳过 rooms[2]
。
这可以通过使用 GUID 作为索引来解决,这就是 BeginCollectionItem 或带有隐藏索引 GUID 的 EditorForMany 如何以正确的顺序跟踪它。
我想创建一个带有 Razor 页面的网站来维护 spaces 和相应的房间。 所以,在我的模型中,space 有一个房间列表。
public class Space
{
public int Id { get; set; }
public string SpaceName { get; set; }
public List<Room> Rooms { get; set; }
public Space()
{
this.Rooms = new List<Room>();
}
}
在create.cshtml我想动态添加和删除房间
<h1>Create New Space</h1>
<form method="post">
<div class="form-group">
<label for="Space.SpaceName">Space Name</label>
<input type="text" class="form-control" asp-for="Space.SpaceName" placeholder="Enter space name">
<span asp-validation-for="Space.SpaceName" ></span>
</div>
@if(Model.Space != null){
for (int i = 0; i < Model.Space.Rooms.Count; i++)
{
<input asp-for="@i" type="hidden" />
<div class="form-group">
<label for="SpaceName">Room Name</label>
<input type="text" class="form-control" asp-for="Space.Rooms[i].Name" placeholder="Enter space name">
<span asp-validation-for="Space.Rooms[i].Name" ></span>
</div>
<button type="submit" asp-page-handler="removeroom" asp-route-index="@i">Remove Room</button>
}
}
<button type="submit" asp-page-handler="addroom">Add Room</button>
<button type="submit" asp-page-handler="submit" class="btn btn-primary">Submit</button>
</form>
PageModel 如下所示:
public class CreateModel : PageModel
{
readonly SpaceRepository spaceRepository;
public CreateModel(SpaceRepository spaceRepository)
{
this.spaceRepository = spaceRepository;
}
[BindProperty]
public Space Space { get; set; }
public async Task<IActionResult> OnPostSubmitAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
spaceRepository.Create(Space);
return RedirectToPage("./Index");
}
public async Task OnPostAddRoomAsync()
{
Space.Rooms.Add(new Room());
}
public async Task OnPostRemoveRoomAsync(int index)
{
Space.Rooms.RemoveAt(index);
}
}
到目前为止它按预期工作,但是当我创建例如 3 个房间并删除第一个或第二个房间时,它总是删除最后一个。
页面似乎没有收到处理程序后的操作列表post。
知道缺少什么吗?
感谢您的帮助!
我知道你可能不再需要它了,但我对此也有疑问,所以我在 github 上开了一个问题,我得到了你问题的答案:https://github.com/aspnet/Mvc/issues/8373
所以基本上 MVC 是往返模型,所以字段可以保持填充状态。因此,页面模型使用最后已知的模型状态来填充每个字段。您可以在删除项目后使用 Modelstate.Clear()
来解决此问题。由于这一点,您在从列表中删除项目后也不会显示任何验证消息。
索引必须按顺序排列,不能有间隙。如果您有这样的数组或列表:
rooms[0] = "Room 1"
rooms[1] = "Room 2"
rooms[2] = "Room 3"
它将 post 正确。但是,如果您删除 rooms[1]
,它只会 post rooms[0]
并跳过 rooms[2]
。
这可以通过使用 GUID 作为索引来解决,这就是 BeginCollectionItem 或带有隐藏索引 GUID 的 EditorForMany 如何以正确的顺序跟踪它。