ASP.NET MVC表单验证异常:正确输入仍报错且输入框清空
ASP.NET MVC表单提交问题排查与修复
问题现象
提交符合要求的表单内容时,系统仍提示输入错误;提交后返回视图时输入框内容为空;希望输入正确内容后错误提示自动消失。
现有代码
视图代码
<form method="post"> <!--form validations--> <div class="row mb-2"> <h2 class="display-4 c-title">Send Us a Message</h2> <hr class="my-4"> <!--Gets the first name--> <div class="col-lg-6 col-sm-12"> <label asp-for="@Model.Name" class="form-label">First Name</label> <input type="text" asp-for="@Model.Name" class="form-control" id="firstNm" name="firstNmLabel" placeholder="First Name"> <span class="text-danger" asp-validation-for="@Model.Name"></span> </div> <div class="col-lg-6 col-sm-12"> <label asp-for="@Model.LastName" class="form-label">Last Name</label> <input type="text" asp-for="@Model.LastName" class="form-control" id="lastNm" name="LastNmLabel" placeholder="Last Name"> <span class="text-danger" asp-validation-for="@Model.LastName"></span> </div> <!--Get--> </div> <div class="row mb-3"> <div class="col-lg-6 col-sm-12"> <label asp-for="@Model.PhoneNumber" class="form-label">Phone</label> <!--as for help in the input--> <input type="text" asp-for="@Model.PhoneNumber" class="form-control" id="phoneNum" name="phoneNum" placeholder="111-111-1111"> <span class="text-danger" asp-validation-for="@Model.PhoneNumber"></span> </div> <div class="col-lg-6 col-sm-12"> <label for="inputEmail" class="form-label">Email address</label> <input type="email" asp-for="@Model.Email" class="form-control" id="inputEmail" name="inputEmail" aria-describedby="emailHelp" placeholder="Enter email"> <span class="text-danger" asp-validation-for="@Model.Email"></span> </div> </div> <!--Collects address--> <div class="row mb-3"> <div> <label asp-for="@Model.Address" class="form-label">Stree Address</label> <input type="text" asp-for="@Model.Address" class="form-control" id="street" name="street"> <span class="text-danger" asp-validation-for="@Model.Address"></span> </div> </div> <div class="row mb-3"> <div class="col-md-6 mb-3"> <label asp-for="@Model.City" class="form-label">City</label> <input type="text" asp-for="@Model.City" class="form-control" id="city" name="city" placeholder="City"> <div class="invalid-feedback"> Please provide a valid city. </div> </div> <div class="col-md-3 mb-3"> <label asp-for="@Model.State" class="form-label">State</label> <input type="text" asp-for="@Model.State" class="form-control" id="state" name="state" placeholder="State" /> <div class="invalid-feedback"> Please provide a valid state. </div> </div> <div class="col-md-3 mb-3"> <label asp-for="@Model.PostalCode" class="form-label">Zip</label> <input type="text" asp-for="@Model.PostalCode" class="form-control" id="zip" name="zip" placeholder="Zip"> <div class="invalid-feedback"> Please provide a valid zip. </div> </div> </div> <!--try to put a line here so it separates.--> <!--Collects information about us--> <div class="row mb-3"> <div class="col-md-6 mb-3"> <label asp-for="@Model.Service" class="form-label">What service are you requesting?</label> <!--check if I can add the asp-for in here.--> <select class="form-select" id="services" name="services" asp-for="@Model.Service"> <option value="">Please chose a service</option> <option value="Inspection">Inspection</option> <option value="New Roofing">New Roofing</option> <option value="Roof Repair">Roof Repair</option> <option value="Siding">Siding</option> <option value="Gutters">Gutters</option> <option value="Soffit and Fascia">Soffit and Fascia</option> <option value="Commercial roof">Commercial roof</option> </select> <span class="text-danger" asp-validation-for="@Model.Service"></span> </div> <div class="col-md-6 mb-3"> <label asp-for="@Model.HearAboutUs" class="form-label">How did you hear about us?</label> <select class="form-select" id="hearUs" name="hearUs" asp-for="@Model.HearAboutUs"> <option value="">-Select-</option> <option value="Internet Search">Internet Search</option> <option value="Internet Ad">Internet Ad</option> <option value="Direct Mail">Direct Mail</option> <option value="Yard Sign">Yard Sign</option> <option value="Social Media">Social Media</option> <option value="Referral">Referral</option> </select> </div> </div> <!--This get a lot of text--> <div class="row mb-3"> <div class="form-group"> <label asp-for="@Model.Message" class="form-label">Message</label> <textarea class="form-control" asp-for="@Model.Message" id="message" rows="5" name="message"></textarea> </div> </div> <!--Button to submit information------------------------------------------------------------------> <div class="row mb-3"> <div class="col-12"> <input type="submit" name="submit" value="Submit" class="btn btn-primary" /> </div> </div> </form>
模型代码
using System.ComponentModel.DataAnnotations; namespace NewOriginConstruction.Models { public class SendMail { [Required] public string? Name { get; set; } public string? LastName { get; set; } [Required, EmailAddress] public string? Email { get; set; } [Required] [RegularExpression(@"^\d{3}-\d{3}-\d{4}$", ErrorMessage = "Please enter a valid phone number in the format XXX-XXX-XXXX.")] public string? PhoneNumber { get; set; } [Required] public string? Address { get; set; } public string? City { get; set; } public string? State { get; set; } public int PostalCode { get; set; } [Required] public string? Service { get; set; } public string? HearAboutUs { get; set; } public string? Message { get; set; } } }
控制器代码
[HttpPost] public ActionResult Contact(SendMail sendMail) { if (!ModelState.IsValid) return View(); // return View(); }
问题根源与修复方案
1. 表单控件name属性与模型字段不匹配
ASP.NET MVC模型绑定依赖控件的name属性对应模型字段名。你手动指定的多个控件name(如firstNmLabel、LastNmLabel)与模型字段名不一致,导致提交后模型无法接收值,触发验证错误,同时返回视图时无法回显内容。
修复: 移除所有手动设置的name属性,让asp-for标签助手自动生成正确的name。例如:
<!-- 修改前 --> <input type="text" asp-for="@Model.Name" class="form-control" id="firstNm" name="firstNmLabel" placeholder="First Name"> <!-- 修改后 --> <input type="text" asp-for="@Model.Name" class="form-control" id="firstNm" placeholder="First Name">
对所有表单控件(包括select、textarea)执行同样修改。
2. 邮政编码字段类型不匹配
模型中PostalCode为int类型,但视图是文本输入框,若用户输入非数字内容会导致绑定失败;空值提交时int无法接收null,触发验证错误。
修复: 将模型中PostalCode改为可空字符串类型,或添加验证确保输入纯数字:
// 方案一:改为可空字符串 public string? PostalCode { get; set; } // 方案二:保留int并添加验证(需确保用户输入纯数字) [Required] [RegularExpression(@"^\d{5}$", ErrorMessage = "请输入有效的5位邮政编码")] public int PostalCode { get; set; }
3. 控制器返回视图时未传递模型
验证通过后直接返回View(),未传递sendMail模型,导致输入框内容清空。
修复: 验证失败时传递模型确保回显;验证成功后可选择保留内容或跳转重置:
[HttpPost] public ActionResult Contact(SendMail sendMail) { if (!ModelState.IsValid) return View(sendMail); // 错误时传递模型回显内容 // 执行邮件发送等业务逻辑 // 方案一:保留表单内容并显示成功提示 ViewBag.SuccessMessage = "表单提交成功!"; return View(sendMail); // 方案二:跳转至GET页面清空表单 // return RedirectToAction("Contact"); }
4. 客户端验证优化(可选)
要实现输入正确内容后错误提示实时消失,需启用客户端验证:
- 在视图底部添加验证脚本引用:
@section Scripts { @{await Html.RenderPartialAsync("_ValidationScriptsPartial");} }
确保项目已引入jquery.validate和jquery.validate.unobtrusive脚本。
内容的提问来源于stack exchange,提问作者NOC
相关产品推荐
相关产品推荐

