繁体   English   中英

ASP.NET Core 2.1和Razor页面中的模态表单验证

[英]Modal form validation in asp.net core 2.1 and Razor pages

我有一个Details.cshtml页面,其中显示客户的详细信息以及customer.sites的链接列表。 在页面上,我创建了一个用于添加新站点的按钮,该按钮将打开一个包含用于输入新站点的表单的引导程序模式。

我遇到的问题是验证。 如果表单无效,则页面将重新加载,但模式会再次隐藏,这意味着除非用户再次单击添加站点按钮,否则将看不到asp-validation-for文本。 有什么方法可以使当ModelState.IsValid无效时,模式自动保持打开状态吗?

details.cshtml页面

@page "{id:int?}"
@model ServiceManager.Pages.Customers.DetailsModel

@{
    ViewData["Title"] = "Details";
}
<h2>@Html.DisplayFor(model => model.Customer.Name)</h2>
<hr />
<!-- Modal -->
<div class="modal fade" tabindex="-1" role="dialog" aria-hidden="true" id="createSiteModal">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title">Add New Customer Site</h5>
                <button type="button" class="close" data-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <div class="modal-body">
                <form method="post">
                    <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                    <div class="form-group">
                        <label asp-for="Site.Description" class="control-label"></label>
                        <input asp-for="Site.Description" class="form-control" />
                        <span asp-validation-for="Site.Description" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Site.AddressLine" class="control-label"></label>
                        <textarea asp-for="Site.AddressLine" class="form-control"></textarea>
                        <span asp-validation-for="Site.AddressLine" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Site.City" class="control-label"></label>
                        <input asp-for="Site.City" class="form-control" />
                        <span asp-validation-for="Site.City" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Site.County" class="control-label"></label>
                        <input asp-for="Site.County" class="form-control" />
                        <span asp-validation-for="Site.County" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Site.Postcode" class="control-label"></label>
                        <input asp-for="Site.Postcode" class="form-control" />
                        <span asp-validation-for="Site.Postcode" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Site.Country" class="control-label"></label>
                        <input asp-for="Site.Country" class="form-control" />
                        <span asp-validation-for="Site.Country" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Site.Telephone" class="control-label"></label>
                        <input asp-for="Site.Telephone" class="form-control" />
                        <span asp-validation-for="Site.Telephone" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <label asp-for="Site.Fax" class="control-label"></label>
                        <input asp-for="Site.Fax" class="form-control" />
                        <span asp-validation-for="Site.Fax" class="text-danger"></span>
                    </div>
                    <div class="form-group">
                        <input asp-for="Site.CommercialID" class="form-control" value="3" />
                    </div>
                    <div class="form-group">
                        <input type="button" value="Cancel" class="btn btn-danger" data-dismiss="modal" />
                        <input type="submit" value="Create" class="btn btn-success" />
                    </div>
                </form>
            </div>
        </div>
    </div>
</div>
<div class="btn-group" role="group">
    <a class="btn btn-light" data-toggle="tooltip" data-placement="top" data-delay="200" title="Back to Customer List" asp-page="./Index">
        <span class="fas fa-arrow-left fa-1x" style="color:#007bff"></span>
    </a>
    @if (Model.Customer.CustomerType == "Domestic")
    {
        <a class="btn btn-light" asp-page="./EditDom" asp-route-id="@Model.Customer.ID" data-toggle="tooltip" data-placement="top" data-delay="200" title="Edit Customer">
            <span class="fas fa-user-edit fa-1x" style="color:#0c0cbe"></span>
        </a>
    }
    else
    {
        <a class="btn btn-light" asp-page="./Edit" asp-route-id="@Model.Customer.ID" data-toggle="tooltip" data-placement="top" data-delay="200" title="Edit Customer">
            <span class="fas fa-user-edit fa-1x" style="color:#0c0cbe"></span>
        </a>
    }
        <a class="btn btn-light" asp-page="./Delete" asp-route-id="@Model.Customer.ID" data-toggle="tooltip" data-placement="top" data-delay="200" title="Delete Customer">
            <span class="fas fa-user-times fa-1x" style="color:#b01111"></span>
        </a>
</div>
<div class="row">
    <div class="col-lg-4">
        <div class="card border-info mb-3">
            <h5 class="card-header bg-info text-white">Customer Details</h5>
            <div class="card-body">
                <dl class="row">
                    <dt class="col-5">
                        @Html.DisplayNameFor(model => model.Customer.AccountRef)
                    </dt>
                    <dd class="col-7">
                        @Html.DisplayFor(model => model.Customer.AccountRef)
                    </dd>
                    <dt class="col-5">
                        @Html.DisplayNameFor(model => model.Customer.ContactDate)
                    </dt>
                    <dd class="col-7">
                        @Html.DisplayFor(model => model.Customer.ContactDate)
                    </dd>
                    <dt class="col-5">
                        @Html.DisplayNameFor(model => model.Customer.Active)
                    </dt>
                    <dd class="col-7">
                        @Html.DisplayFor(model => model.Customer.Active)
                    </dd>
                </dl>
            </div>
        </div>
    </div>
    <div class="col-lg-4">
        <div class="card border-info mb-3">
            <h5 class="card-header bg-info text-white">Customer Sites</h5>
            <table class="table table-hover fixed-table">
                <tr>
                    <th>Description</th>
                    <th>Location</th>
                    <th>Telephone</th>
                </tr>
                @foreach (var item in Model.Customer.Sites)
                {
                    <tr>
                        <td>
                            @Html.DisplayFor(modelItem => item.Description)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.City)
                        </td>
                        <td>
                            @Html.DisplayFor(modelItem => item.Telephone)
                        </td>
                        <td>
                            <a class="rowlink" asp-page="/Sites/Details" asp-route-id="@item.ID"><i class="fa fa-chevron-right"></i></a>
                        </td>
                    </tr>
                }
            </table>
            <div class="card-footer">
                <!-- Button trigger modal -->
                <button class="btn btn-link float-right" data-toggle="modal" data-target="#createSiteModal">
                    <span class="fa-stack fa-lg">
                        <i class="fas fa-circle fa-stack-2x" style="color:tomato"></i>
                        <i class="fas fa-stack-1x fa-inverse">+</i>
                    </span>
                </button>
                <div class="clearfix"></div>
            </div>
        </div>
    </div>
</div>

Details.cshtml.cs页面

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.EntityFrameworkCore;
using ServiceManager.Models;

namespace ServiceManager.Pages.Customers
{
    public class DetailsModel : PageModel
    {
        private readonly CompanyContext _context;

        public DetailsModel(CompanyContext context)
        {
            _context = context;
        }

        public Commercial Customer { get; set; }


        public async Task<IActionResult> OnGetAsync(int? id)
        {
            if (id == null)
            {
                return NotFound();
            }

            Customer = await _context.Commercial
                .Include(c => c.Sites)
                .Include(c => c.Contacts)
                .FirstOrDefaultAsync(m => m.ID == id);

            if (Customer == null)
            {
                return NotFound();
            }
            return Page();
        }

        [BindProperty]
        public Address Site { get; set; }

        public async Task<IActionResult> OnPostAsync(int? id)
        {

            if (!ModelState.IsValid)
            {
                Customer = await _context.Commercial
                .Include(c => c.Sites)
                .Include(c => c.Contacts)
                .FirstOrDefaultAsync(m => m.ID == id);

                return Page();
            }
            _context.Address.Add(Site);
            await _context.SaveChangesAsync();
            return RedirectToPage("./Index");  
        }
    }
}

解决此问题的一种方法是在提交表单之前使用jQuery执行客户端验证。 这样,模态保持打开状态,用户可以立即获得有关错误原因的反馈。

在这种情况下,另一种替代方法(可能是侵入性较小的方法)是将标志从服务器传递回客户端,并带有模型验证的状态,然后根据此类标志​​的值打开模态,例如

控制器

   public async Task<IActionResult> OnPostAsync(int? id)
    {

        if (!ModelState.IsValid)
        {
            Customer = await _context.Commercial
            .Include(c => c.Sites)
            .Include(c => c.Contacts)
            .FirstOrDefaultAsync(m => m.ID == id);
            ViewData["ModelIsValid"] = false;
            return Page();
        }
        ViewData["ModelIsValid"] = true;
        _context.Address.Add(Site);
        await _context.SaveChangesAsync();
        return RedirectToPage("./Index");  
    }

查看

<script>
    $(document).ready(function () {
        @if(!(bool)ViewData["ModelIsValid"])
        {
            $("#createSiteModal").modal('show');
        }
    });
</script>

第二种方法的主要缺点是,模态将在页面呈现后弹出而不是保持打开状态。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM