MVC局部视图表单提交至Controller时出现500错误求助
局部视图表单提交MVC控制器返回500错误排查
提交局部视图表单至https://localhost:44383/WIZ/Form/CreateTicketForm时返回500错误,未使用AJAX或JavaScript,所有必填字段已填写。控制器动作断点从未触发,事件查看器无错误记录,开发者工具仅显示表单载荷已传递但无后续动作。
表单代码
@model TicketWizard.ViewModels.FormViewModel @addTagHelper*, Microsoft.AspNetCore.Mvc.TagHelpers @{ ViewData["Title"] = "Create New Ticket";} <form method="post" id="formBody" enctype="multipart/form-data" asp-action="CreateTicketForm" asp-controller="Form"> <input asp-for="User.CAC_EDIPI" id="userEDIPI" hidden /> <div class="row"> <div class="col-12"> <div class="form-group bg-light row pb-3"> <div class="col-3"> <label class="fw-bold" asp-for="Ticket.Priority" tabindex="-1"></label><b style="color:red;"> *</b> <select asp-for="Ticket.Priority" asp-items="@ViewBag.PriorityDropDown" class="form-select" id="priorityId" data-toggle="tooltip" data-placement="top" title="Select the impact best fitting the scope of the opportunity"> <option value="" selected>Choose...</option> </select> <span asp-validation-for="Ticket.Priority" class="text-danger" id="priorityValid"></span> </div> <div class="col-3"> <label class="fw-bold" asp-for="Ticket.NumUsers" tabindex="-1"></label><b style="color:red;"> *</b> <input class="form-control" type="number" id="numUsers" /> <span asp-validation-for="Ticket.NumUsers" class="text-danger" id="numUsersValid"></span> </div> <div class="col-3"> <label asp-for="Ticket.RoomNumber" class="fw-bold" tabindex="-1"> </label><b style="color:red;"> *</b> <input class="form-control" type="number" asp-for="Ticket.RoomNumber" id="roomNumber" data-toggle="tooltip" title="A room number is required if you work in the GCC." /> <span asp-validation-for="Ticket.RoomNumber" class="text-danger"></span> </div> <div class="col-3"> <label asp-for="Ticket.CubeNumber" class="fw-bold" tabindex="-1"> </label><b style="color:red;"> *</b> <input class="form-control" type="number" asp-for="Ticket.CubeNumber" id="cubeNumber" data-toggle="tooltip" title="A cube number is required if you work in the GCC." /> <span asp-validation-for="Ticket.CubeNumber" class="text-danger"></span> </div> </div> <div class="form-group row pb-3"> <div class="col-12"> <p class="col-6 fw-bold" tabindex="-1">Is this issue causing a workstoppage?<b style="color:red;"> *</b></p> <div class="col-6 btn-group" role="group"> <input type="checkbox" asp-for="Ticket.WorkStoppageYes" class="btn-check" id="yesCheck" onclick="workStoppageRequired()" autocomplete="off"> <label class="btn btn-outline-primary" for="yesCheck">Yes</label> <input type="checkbox" asp-for="Ticket.WorkStoppageYes" class="btn-check" id="noCheck" onclick="workStoppageNotRequired()" autocomplete="off"> <label class="btn btn-outline-primary" for="noCheck">No</label> </div> <div class="row"> <span class="text-danger" id="workStoppageWarning" style="display: none;">Please select an option.</span> </div> </div> </div> <div class="form-group row bg-light pb-3"> <div class="col-6"> <label class="fw-bold" asp-for="Ticket.SubmitterEDIPI" tabindex="-1"></label> <input asp-for="Ticket.SubmitterName" id="submitterName" class="form-control unaccessible" type="text" readonly> <input asp-for="Ticket.SubmitterEDIPI" id="submitterEDIPI" hidden> </div> <div class="col-6"> <label class="fw-bold" asp-for="Ticket.AlternateEDIPI" tabindex="-1"></label> <div class="autocomplete" data-toggle="tooltip" title="Only add name if the Submitter will not be the point of contact."> <input asp-for="Ticket.AltPocName" id="altPOCInput" class="form-control" placeholder="Enter name..." type="text" data-toggle="tooltip" data-placement="top" title="Find RCC-C users by last name"> <input asp-for="Ticket.AlternateEDIPI" id="altPocEDIPI" hidden> </div> </div> </div> <div class="form-group row pb-3"> <div class="col-6"> <label asp-for="Ticket.ServiceId" class="fw-bold" tabindex="-1">Services</label> <select asp-for="Ticket.ServiceId" class="form-select" asp-items="@ViewBag.ServiceAreasDown" data-toggle="tooltip" title="Select the service that can assist with this issue" id="ticketService"> <option value="" selected>Choose...</option> </select> </div> <div class="col-6"> <label asp-for="Ticket.TeamId" class="fw-bold" tabindex="-1">Teams</label> <select asp-for="Ticket.TeamId" class="form-select" asp-items="@ViewBag.TeamDropDown" data-toggle="tooltip" title="Select the team that can assist with this issue" id="ticketTeam"> <option value="" selected>Choose...</option> </select> </div> <div class="row"> <span class="text-danger" id="teamServicesWarning" style="display: none;">Please select either a service or a team.</span> </div> </div> <div class="form-group row bg-light pb-3"> <div class="col-12"> <label asp-for="Ticket.Details" class="fw-bold" tabindex="-1">Details<b style="color:red;"> *</b></label> <textarea asp-for="Ticket.Details" class="form-control" data-toggle="tooltip" title="Provide a detailed description of the issue." id="ticketDetails"> </textarea> <span asp-validation-for="Ticket.Details" class="text-danger" id="detailsValid"></span> </div> </div> </div> <hr /> <div class="row"> <div class="col"> <div class="btn-group float-right" role="group"> <button type="submit" class="btn btn-success mr-1" id="submitFormBtn">Submit</button> <button type="button" class="btn btn-danger" data-bs-dismiss="modal">Close</button> </div> </div> </div> </div> </form> @*//Client-side validation*@ @section Scripts { @{ <partial name="_ValidationScriptsPartial" /> } }
控制器代码
//POST-Submit Form [HttpPost] [ValidateAntiForgeryToken] public IActionResult CreateTicketForm(FormViewModel formViewModel) { UserVO userVO = this.cookieAuthenticationService.GetUser(HttpContext, out bool edipiFound, true); string fullName = HomeController.CapitalizeFirstLetter(userVO.lastName) + ", " + HomeController.CapitalizeFirstLetter(userVO.firstName) + " " + HomeController.CapitalizeFirstLetter(userVO.mi) + " " + HomeController.FindAcronym(userVO.rank.rank); string WorkStoppage = "No"; if (!ModelState.IsValid) { return View(); } try { using (SqlConnection con = HomeController.OpenConnection(WizConnString)) { SqlCommand sqlCmd = new SqlCommand("usp_CreateTicket", con); sqlCmd.CommandType = CommandType.StoredProcedure; sqlCmd.Parameters.AddWithValue("SubmitterEDIPI", (int)userVO.edipi); sqlCmd.Parameters.AddWithValue("SubmitterName", fullName); sqlCmd.Parameters.AddWithValue("Details", formViewModel.Ticket.Details); sqlCmd.Parameters.AddWithValue("Priority", formViewModel.Ticket.Priority); sqlCmd.Parameters.AddWithValue("NumUsers", formViewModel.Ticket.NumUsers); if (formViewModel.Ticket.WorkStoppageYes == "true") { WorkStoppage = "Yes"; } else if(formViewModel.Ticket.WorkStoppageNo == "true") { WorkStoppage = "No"; } sqlCmd.Parameters.AddWithValue("WorkStoppage", WorkStoppage); sqlCmd.Parameters.AddWithValue("RoomNumber", formViewModel.Ticket.RoomNumber); sqlCmd.Parameters.AddWithValue("CubeNumber", formViewModel.Ticket.CubeNumber); sqlCmd.Parameters.AddWithValue("ServiceId", formViewModel.Ticket.ServiceId); sqlCmd.Parameters.AddWithValue("TeamId", formViewModel.Ticket.TeamId); if (formViewModel.Ticket.AlternateEDIPI != null) { sqlCmd.Parameters.AddWithValue("AltEDIPI", formViewModel.Ticket.AlternateEDIPI); sqlCmd.Parameters.AddWithValue("AltPocName", formViewModel.Ticket.AltPocName); } sqlCmd.ExecuteNonQuery(); } return RedirectToAction("Index","Home"); } catch (Exception ex) { PortalLogger.WriteLog("Error. Unable to create ticket for " + (int)userVO.edipi + ". " + ex.ToString()); throw new Exception("Error. Unable to create ticket for " + (int)userVO.edipi + ". " + ex.ToString()); } }
Ticket模型代码
public class Ticket { //Required [Key] [DisplayName("POC/Submitter")] public long SubmitterEDIPI { get; set; } public string SubmitterName { get; set; } public string SubmitterPhone { get; set; } public string SubmitterEmail { get; set; } [DisplayName("Alternative POC")] public string AlternateEDIPI { get; set; } public string AltPocName { get; set; } public string AltPOCPhone { get; set; } public string AltPOCEmail { get; set; } public string Details { get; set; } [Required(ErrorMessage = "A priority must be provided.")] public int Priority { get; set; } public int ServiceId { get; set; } public int TeamId { get; set; } public int NumUsers { get; set; } public string WorkStoppageYes { get; set; } public string WorkStoppageNo { get; set; } [DisplayName("Room Number")] [Required(ErrorMessage = "A room number must be provided if the user works in the GCC.")] public string RoomNumber { get; set; } [DisplayName("Cube Number")] [Required(ErrorMessage = "A cube number must be provided if the user works in the GCC.")] public string CubeNumber { get; set; } }
排查思路与解决方案
- 检查防伪造令牌:控制器启用了
[ValidateAntiForgeryToken],需确认表单是否生成了__RequestVerificationToken字段。局部视图可能需要手动添加<input asp-antiforgery="true" />,或者查看页面源码确认该字段存在。 - 修复模型绑定错误:
Ticket.NumUsers的输入框缺少asp-for="Ticket.NumUsers"属性,导致提交时无对应值,而模型中NumUsers为非可空int,触发绑定异常。需添加该属性。- 工作停滞选项使用了两个复选框绑定到同一个
Ticket.WorkStoppageYes,逻辑错误,应改为单选按钮(radio),并分别绑定到对应字段或使用单个布尔字段。
- 处理模型验证失败场景:当
ModelState.IsValid为false时,直接返回View会导致局部视图缺少ViewBag.PriorityDropDown等必要数据,引发视图渲染异常。需重新填充ViewBag数据后再返回,或返回JSON/PartialView。 - 排查用户认证异常:
cookieAuthenticationService.GetUser可能抛出未处理异常(如用户未登录、cookie无效),需添加异常捕获,或先判断edipiFound是否为true,避免后续代码报错。 - 修正模型字段可空性:
ServiceId和TeamId允许未选择,但模型中为非可空int,绑定失败会引发异常。需改为int? ServiceId { get; set; }和int? TeamId { get; set; },并在存储过程中处理空值。 - 开启详细错误信息:在开发环境中,设置
app.UseDeveloperExceptionPage()或修改appsettings.json的DetailedErrors为true,获取500错误的详细堆栈,定位具体异常点。 - 检查存储过程参数匹配:确认存储过程
usp_CreateTicket的参数类型、数量与代码中添加的一致,比如RoomNumber为string类型,表单提交的数字字符串需能被存储过程接受。
内容的提问来源于stack exchange,提问作者NerdyDriod
相关产品推荐
相关产品推荐

