仅检查剃刀页面中可见表单的属性的ModelState OnPost

时间:2018-12-11 03:24:01

标签: c# asp.net-core asp.net-core-mvc asp.net-core-2.0 razor-pages

我创建了一个具有以下属性的剃刀页面:

[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 });
}

0 个答案:

没有答案