在 Razor Pages 中绑定视图组件的模型
Model Binding a View Component in Razor Pages
我正在使用 ASP.NET Core 2.1、Razor Pages 和一个视图组件(尽管如果还需要视图组件,我不会出售)
我有一个父模型 Organization
,其中包含一个子模型列表,Contacts
:
组织
public Guid Id { get; set; }
public string OrganizationName { get; set; }
public ICollection<Contact> Contacts { get; set; }
联系
public Guid Id { get; set; }
public string ContactName { get; set; }
public Guid OrganizationId { get; set; }
我想要做的是在组织中列出 n 个联系人,我可以在视图中添加和删除这些联系人,并在我点击 OnPost()
页面模型方法时反映出来
在我之前的项目中,一个 MVC5 网络应用程序:
- 我使用 Ajax 将部分视图添加到视图:
- 并且我能够将至少一级深度列表 return 发送给控制器:C# MVC, Link Together Nested Partial Views
这两者的组合看起来很像这样:
当前状态
在 ~/ViewComponents/Contact.cs
我有:
public class Contact : ViewComponent
{
private readonly ApplicationDbContext _context;
public Contact(ApplicationDbContext context)
{
_context = context;
}
public async Task<IViewComponentResult> InvokeAsync(Guid organizationId, Guid contactId)
{
var contact = new Models.Contact { Id = contactId, OrganizationId = organizationId };
return View(contact);
}
}
调用 ~/Pages/Shared/Components/Contact/Default.cshtml
, :
@model Models.Contact
@using (Html.BeginCollectionItem("Contacts"))
{
<div class="row">
<input asp-for="Id" type="hidden" />
<input asp-for="OrganizationId" type="hidden"/>
<input asp-for="ContactName" class="form-control"/>
</div>
}
然后我直接将其加载到 Organiztion 的 ~/Pages/Organizations/Create.cshtml
:
@page
@using System.Linq
@using ViewComponents
@model CreateModel
@{
ViewData["Title"] = "Create";
}
<h2>Create</h2>
<h4>Organization</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div class="form-group">
<input asp-for="Organization.OrganizationName" class="form-control" />
</div>
<div class="form-group">
<label asp-for="OrganizationContacts" class="col-form-label"></label>
<!-- HERE --> @await Component.InvokeAsync(nameof(ViewComponents.Contact), new { organizationId = Model.Organization.Id, contactId = Guid.NewGuid() })
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
当我点击“提交”按钮时,它点击了 Create.cshtml.cs
中的 OnPostAsync()
方法:
public class CreateModel : PageModel
{
private readonly ApplicationDbContext _context;
[BindProperty]
public Organization Organization { get; set; }
public CreateModel(ApplicationDbContext context, IMapper mapper)
{
_context = context;
}
public IActionResult OnGet()
{
Organization = new Organization{ Contacts = new List<Contact>() };
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
_context.Organizations.Add(Organization); // <--- Always has an empty Contacts list
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
当我点击 OnPostAsync
时,绑定的 Organization
模型的 OrganizationName
值很好,但 Contacts
列表始终为空。
如何将联系人添加到组织的 Contacts
列表中,知道以后我想添加或删除 n 个联系人?
我见过的大多数此类问题的答案都有 for
循环,但它们要求我提前知道组织中有或将有多少联系人,而这根本不是我的案例。
为了解析空 Contacts
,尝试将 Html.BeginCollectionItem("Contacts")
更改为 Html.BeginCollectionItem("Organization.Contacts")
。
由于Contacts
是Organization
的集合,所以需要传Organization.Contacts[index].Property
,否则绑定请求到模型会失败
我正在使用 ASP.NET Core 2.1、Razor Pages 和一个视图组件(尽管如果还需要视图组件,我不会出售)
我有一个父模型 Organization
,其中包含一个子模型列表,Contacts
:
组织
public Guid Id { get; set; }
public string OrganizationName { get; set; }
public ICollection<Contact> Contacts { get; set; }
联系
public Guid Id { get; set; }
public string ContactName { get; set; }
public Guid OrganizationId { get; set; }
我想要做的是在组织中列出 n 个联系人,我可以在视图中添加和删除这些联系人,并在我点击 OnPost()
页面模型方法时反映出来
在我之前的项目中,一个 MVC5 网络应用程序:
- 我使用 Ajax 将部分视图添加到视图:
- 并且我能够将至少一级深度列表 return 发送给控制器:C# MVC, Link Together Nested Partial Views
这两者的组合看起来很像这样:
当前状态
在 ~/ViewComponents/Contact.cs
我有:
public class Contact : ViewComponent
{
private readonly ApplicationDbContext _context;
public Contact(ApplicationDbContext context)
{
_context = context;
}
public async Task<IViewComponentResult> InvokeAsync(Guid organizationId, Guid contactId)
{
var contact = new Models.Contact { Id = contactId, OrganizationId = organizationId };
return View(contact);
}
}
调用 ~/Pages/Shared/Components/Contact/Default.cshtml
,
@model Models.Contact
@using (Html.BeginCollectionItem("Contacts"))
{
<div class="row">
<input asp-for="Id" type="hidden" />
<input asp-for="OrganizationId" type="hidden"/>
<input asp-for="ContactName" class="form-control"/>
</div>
}
然后我直接将其加载到 Organiztion 的 ~/Pages/Organizations/Create.cshtml
:
@page
@using System.Linq
@using ViewComponents
@model CreateModel
@{
ViewData["Title"] = "Create";
}
<h2>Create</h2>
<h4>Organization</h4>
<hr />
<div class="row">
<div class="col-md-4">
<form method="post">
<div class="form-group">
<input asp-for="Organization.OrganizationName" class="form-control" />
</div>
<div class="form-group">
<label asp-for="OrganizationContacts" class="col-form-label"></label>
<!-- HERE --> @await Component.InvokeAsync(nameof(ViewComponents.Contact), new { organizationId = Model.Organization.Id, contactId = Guid.NewGuid() })
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
</div>
</div>
当我点击“提交”按钮时,它点击了 Create.cshtml.cs
中的 OnPostAsync()
方法:
public class CreateModel : PageModel
{
private readonly ApplicationDbContext _context;
[BindProperty]
public Organization Organization { get; set; }
public CreateModel(ApplicationDbContext context, IMapper mapper)
{
_context = context;
}
public IActionResult OnGet()
{
Organization = new Organization{ Contacts = new List<Contact>() };
return Page();
}
public async Task<IActionResult> OnPostAsync()
{
_context.Organizations.Add(Organization); // <--- Always has an empty Contacts list
await _context.SaveChangesAsync();
return RedirectToPage("./Index");
}
}
当我点击 OnPostAsync
时,绑定的 Organization
模型的 OrganizationName
值很好,但 Contacts
列表始终为空。
如何将联系人添加到组织的 Contacts
列表中,知道以后我想添加或删除 n 个联系人?
我见过的大多数此类问题的答案都有 for
循环,但它们要求我提前知道组织中有或将有多少联系人,而这根本不是我的案例。
为了解析空 Contacts
,尝试将 Html.BeginCollectionItem("Contacts")
更改为 Html.BeginCollectionItem("Organization.Contacts")
。
由于Contacts
是Organization
的集合,所以需要传Organization.Contacts[index].Property
,否则绑定请求到模型会失败