我创建了一个具有以下属性的剃刀页面:
[BindProperty]
public CustomerViewModel Customer { get; set; }
[BindProperty]
public CustomerContactViewModel Contact { get; set; }
在CustomerViewModel和CustomerContactViewModel中,我有一堆数据注释,这些注释使字段成为必填项。
此页面包含3个视图。
两个标签: [客户信息] [联系方式]
[Customer Info]标签具有用于编辑客户并依赖于CustomerViewModel的表单
[联系人]选项卡最初具有网格列表,但是如果在一行上单击编辑,则用户将导航到同一页面,但带有使表格代替网格的查询参数。
这是我的问题:
我在页面上有两个单独的提交按钮,它们使用asp-page-handler属性路由到正确的PostAction或SaveCustomer或SaveContact。
当在每个操作的顶部检查ModelState是否有效时,即使页面上可见的表单有效,使用其他模型的其他表单也是无效的。
关于如何解决此问题或如何重做一些事情的任何想法,这不是问题吗?
这是我的查看代码:
@page
@model Messenger.Web.Pages.Customers.EditModel
@{
ViewData["Title"] = "Edit";
}
<ul class="nav nav-tabs" id="myTab" role="tablist">
<li class="nav-item">
<a class="nav-link@(Model.ViewType == EditModel.ViewTypes.EditCustomer ? " active" : "")" id="info-tab" data-toggle="tab" href="#info" role="tab" aria-controls="info" aria-selected="true">Info</a>
</li>
<li class="nav-item">
<a class="nav-link@(Model.ViewType == EditModel.ViewTypes.EditContact ? " active" : "")" id="contacts-tab" data-toggle="tab" href="#contacts" role="tab" aria-controls="contacts" aria-selected="false">Contacts</a>
</li>
</ul>
<div class="tab-content" id="myTabContent">
<div class="tab-pane fade @(Model.ViewType == EditModel.ViewTypes.EditCustomer ? " show active" : "")" id="info" role="tabpanel" aria-labelledby="info-tab">
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<a asp-page="Index" class="btn btn-outline-secondary">Cancel</a>
<button asp-page-handler="SaveCustomer" type="submit" class="btn btn-outline-success ml-1">Save</button>
</form>
</div>
<div class="tab-pane fade @(Model.ViewType == EditModel.ViewTypes.EditContact ? " show active" : "")" id="contacts" role="tabpanel" aria-labelledby="contacts-tab">
@if (Model.ViewType == EditModel.ViewTypes.EditCustomer)
{
<table class="table">
</table>
}
else
{
<form method="post">
<div asp-validation-summary="ModelOnly" class="text-danger"></div>
<a asp-page="./Index" asp-route-CustomerId="@Model.Customer.Id" class="btn btn-outline-secondary">Cancel</a>
<button asp-page-handler="SaveContact" type="submit" class="btn btn-outline-success ml-1">Save</button>
</form>
}
</div>
</div>
这是背后的代码:
public enum ViewTypes
{
EditCustomer = 0,
EditContact = 1
}
public ViewTypes ViewType { get; set; } = ViewTypes.EditCustomer;
[BindProperty]
public CustomerViewModel Customer { get; set; }
[BindProperty]
public CustomerContactViewModel Contact { get; set; }
public async Task<IActionResult> OnGetAsync(int? customerId, string contactId)
{
if (customerId == null && contactId == null)
{
return NotFound();
}
if (customerId != null)
{
var customerFromDb = await _customerRepository.GetByIdWithContactsAsync(customerId.Value);
if (customerFromDb == null)
{
return NotFound();
}
Customer = _mapper.Map<Customer, CustomerViewModel>(customerFromDb);
if (!string.IsNullOrEmpty(contactId))
{
ViewType = ViewTypes.EditContact;
var contactFromDb = customerFromDb.Contacts.SingleOrDefault(x => x.Id == contactId);
if (contactFromDb == null)
{
return NotFound();
}
Contact = _mapper.Map<HomeUser, CustomerContactViewModel>(contactFromDb);
}
}
return Page();
}
public async Task<IActionResult> OnPostSaveCustomerAsync()
{
if (!ModelState.IsValid)
{
CreateDropdownData();
return Page();
}
var customerFromDb = await _customerRepository.GetByIdAsync(Customer.Id);
if (customerFromDb == null)
{
return NotFound();
}
customerFromDb.FirstName = Customer.FirstName;
customerFromDb.MiddleName = Customer.MiddleName;
customerFromDb.LastName = Customer.LastName;
customerFromDb.Birthdate = Customer.Birthdate;
customerFromDb.ActiveIep = Customer.ActiveIep;
customerFromDb.Active = Customer.Active;
customerFromDb.EslLep = Customer.EslLep;
customerFromDb.Grade = Customer.Grade;
customerFromDb.Homeroom = Customer.Homeroom;
customerFromDb.Gender = Customer.Gender;
try
{
await _customerRepository.UpdateAsync(customerFromDb);
}
catch (DbUpdateConcurrencyException)
{
throw;
}
return RedirectToPage("./", new { CustomerId = Customer.Id });
}
public async Task<IActionResult> OnPostSaveContactAsync()
{
if (!ModelState.IsValid)
{
return Page();
}
var customerContactFromDb = await _homeUserRepository.GetByIdAsync(Contact.Id);
// Map View Model to Home User (Customer Contact)
customerContactFromDb.FirstName = Contact.FirstName;
customerContactFromDb.LastName = Contact.LastName;
customerContactFromDb.UserName = Contact.Email;
customerContactFromDb.Email = Contact.Email;
customerContactFromDb.PhoneNumber = Contact.PhoneNumber;
customerContactFromDb.EmailNotifications = Contact.EmailNotifications;
customerContactFromDb.TextNotifications = Contact.TextNotifications;
await _userManager.UpdateAsync(customerContactFromDb);
if (!string.IsNullOrEmpty(Contact.Password))
{
var resetToken = await _userManager.GeneratePasswordResetTokenAsync(customerContactFromDb);
await _userManager.ResetPasswordAsync(customerContactFromDb, resetToken, Contact.Password);
}
return RedirectToPage("./", new { CustomerId = customerContactFromDb.CustomerId });
}