You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 5 MVC提交表单至Action时出现404错误求助

提交患者评估数据时出现404错误问题

我有一个基于SPEPatientEvalVM视图模型的患者评估数据提交页面,页面显示正常,但填写完必填字段点击提交按钮时出现404错误,请求地址为https://localhost:5001/SPE/AddSPEPatientEval/18659/15129/235/4。已尝试为HttpPost添加路由、确保模型字段非空等操作,问题仍未解决。以下是相关代码:

SPEPatientEvalVM 视图模型

public class SPEPatientEvalVM
{
    public int Id { get; set; }
    public int ApptId { get; set; }
    public int ActivityID { get; set; }
    public int VendorID { get; set; }
    public int PatientID { get; set; }
    [Required(ErrorMessage ="A selection is required.")]
    public int OverallRating { get; set; }
    [Required(ErrorMessage = "A selection is required.")]
    public int AppearProfessComp { get; set; }
    [Required(ErrorMessage = "A selection is required.")]
    public int EffGatheredInfo { get; set; }
    [Required(ErrorMessage = "A selection is required.")]
    public int ListenActively { get; set; }
    [Required(ErrorMessage = "A selection is required.")]
    public int EstabPersRapport { get; set; }
    [Required(ErrorMessage = "A selection is required.")]
    public int AppropExploreMyFeelings { get; set; }
    [Required(ErrorMessage = "A selection is required.")]
    public int AddressedMyFeelings { get; set; }
    [Required(ErrorMessage = "A selection is required.")]
    public int MetMyNeeds { get; set; }
    public string PatientComments { get; set; } = String.Empty;
    public DateTime DateSubmitted { get; set; }
}

该ViewModel通过IMapper与实体模型双向映射。

Controller 代码

[HttpGet("[controller]/[action]/{IDAppt}/{ActivityID}/{VendorID}/{PatientID}")]
public async Task<IActionResult> AddSPEPatientEval(int IDAppt, int ActivityID, int VendorID, int PatientID)
{
    var patientChoice = GetPatientChoiceList();
    patientChoice[0].Selected = true;
    ViewBag.PatientChoice = patientChoice;

    var evalParams = await _speRepo.GetOpenPatientEval(IDAppt);

    ViewBag.Patient = evalParams.SPEPatient;

    var speEval = new SPEPatientEvalVM
    {
        ApptId = IDAppt,
        ActivityID = ActivityID,
        VendorID = VendorID,
        PatientID = PatientID
    };

    return View(speEval);
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddSPEPatientEval(SPEPatientEvalVM model)
{
    var patientChoice = GetPatientChoiceList();
    patientChoice[0].Selected = true;
    ViewBag.PatientChoice = patientChoice;

    model.DateSubmitted = DateTime.Now;

    if (ModelState.IsValid)
    {
        var spePatientEval = _mapper.Map<SPEPatientEval>(model);

        var success = await _speRepo.AddSPEPatientEval(spePatientEval);
        if (!success)
        {
            return View(model);
        }
        return View("Index");
    }
    return View(model);
}

View (AddSPEPatientEval.cshtml) 代码

@model SPEPatientEvalVM

@{
    ViewData["Title"] = "AddSPEPatientEval";
}

<div class="col-md-8 m-auto">
    <h1 class="text-center">Patient SPE Evaluation</h1>
    <hr />
</div>

<div class="col-md-8 m-auto">
    <div class="row">
        <div class="col-md-12">
            <form asp-controller="SPE" asp-action="AddSPEPatientEval" method="post">
                <div asp-validation-summary="ModelOnly" class="text-danger"></div>
                <input type="hidden" asp-for="ApptId" />
                <input type="hidden" asp-for="ActivityID" />
                <input type="hidden" asp-for="VendorID" />
                <input type="hidden" asp-for="PatientID" />
                <input type="hidden" asp-for="DateSubmitted" value="@String.Format("{0:MM/dd/yyyy}", DateTime.Now)" />
                <div class="row">
                    <div class="col-md-8 m-auto">
                        <div class="form-group">
                            <label asp-for="OverallRating" class="control-label">As @ViewBag.Patient, rate your overall level of satisfaction with this encounter.</label>
                            <select asp-for="OverallRating" class="form-control"
                                    asp-items="@(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
                            <span asp-validation-for="OverallRating" class="text-danger"></span>
                        </div>
                        <br />
                        <hr />
                    </div>
                </div>
                <br />
                <div class="row">
                    <div class="col-md-8 m-auto">
                        <div class="form-group">
                            <label asp-for="AppearProfessComp" class="control-label">Appeared professional competent - seemed to know what s/he was
                                doing; inspired my comfidence; appeared to have my interests at heart.
                            </b></label>
                            <select asp-for="AppearProfessComp" class="form-control"
                                    asp-items="@(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
                            <span asp-validation-for="AppearProfessComp" class="text-danger"></span>
                        </div>
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-8 m-auto">
                        <div class="form-group">
                            <label asp-for="EffGatheredInfo" class="control-label">Effectively gathered information - collected information in a way that
                                seemed organized; began with several open-ended questions and progressed through interview using a balanced ratio of open- 
                                to closed-ended questions; summarized periodically.
                            </label>
                            <select asp-for="EffGatheredInfo" class="form-control"
                                    asp-items="@(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
                            <span asp-validation-for="EffGatheredInfo" class="text-danger"></span>
                        </div>
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-8 m-auto">
                        <div class="form-group">
                            <label asp-for="ListenActively" class="control-label">Listened actively - paid attention to both my verbal and non-verbal 
                                cues; used facial expressions/body language to express encouragement; avoided interruptions; asked questions to make sure 
                                s/he understood what I said.
                            </label>
                            <select asp-for="ListenActively" class="form-control"
                                    asp-items="@(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
                            <span asp-validation-for="ListenActively" class="text-danger"></span>
                        </div>
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-8 m-auto">
                        <div class="form-group">
                            <label class="control-label">Established personal rapport - introduced self warmly; verbally/non-verbally showed interest 
                                in me as a person, not just my condition; avoided technical jargon.
                            </label>
                            <select asp-for="EstabPersRapport" class="form-control"
                                    asp-items="@(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
                            <span asp-validation-for="EstabPersRapport" class="text-danger"></span>
                        </div>
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-8 m-auto">
                        <div class="form-group">
                            <label asp-for="AppropExploreMyFeelings" class="control-label">Appropriately explored my perspective - encouraged me to 
                                identify everything that I needed to say.
                            </label>
                            <select asp-for="AppropExploreMyFeelings" class="form-control"
                                    asp-items="@(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
                            <span asp-validation-for="AppropExploreMyFeelings" class="text-danger"></span>
                        </div>
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-8 m-auto">
                        <div class="form-group">
                            <label asp-for="AddressedMyFeelings" class="control-label">Addressed my feelings - acknowledged and demonstrated interest in my 
                                expressed and/orunexpressed feelings and experience.
                            </label>
                            <select asp-for="AddressedMyFeelings" class="form-control"
                                    asp-items="@(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
                            <span asp-validation-for="AddressedMyFeelings" class="text-danger"></span>
                        </div>
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-8 m-auto">
                        <div class="form-group">
                            <label asp-for="MetMyNeeds" class="control-label">Met my needs - worked toward a plan which addressed both the diagnosis and 
                                my concerns about my illness.
                            </label>
                            <select asp-for="MetMyNeeds" class="form-control"
                                    asp-items="@(new SelectList(ViewBag.PatientChoice, "Value", "Text"))"></select>
                            <span asp-validation-for="MetMyNeeds" class="text-danger"></span>
                        </div>
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-8 m-auto">
                        <div class="form-group">
                            <label asp-for="PatientComments" class="control-label"></label>
                            <textarea asp-for="PatientComments" class="form-control"
                                      placeholder="Please add any additional comments you would like to express about this examination."></textarea>
                        </div>
                    </div>
                </div>
                <div class="row">
                    <div class="col-md-8 m-auto">
                        <div class="form-group">
                            <input type="submit" value="Submit" class="btn btn-primary" />
                        </div>
                    </div>
                </div>
            </form>
        </div>
    </div>
</div>

<div class="row">
    <div class="col-md-8 m-auto">
        <div class="text-center">
            <a asp-action="Index">Back to List</a>
        </div>
    </div>
</div>

@section Scripts {
    @{
        await Html.RenderPartialAsync("_ValidationScriptsPartial");
    }
}

问题原因及解决方案

原因

表单提交时生成的URL携带了Get方法的路由参数(/18659/15129/235/4),但Post方法没有匹配该带参数路由的配置,导致请求找不到对应的处理方法,触发404错误。

解决方案

方案1:给Post方法添加匹配参数的路由

修改Post方法的路由属性,让它能接收带参数的请求,同时不影响模型绑定:

[HttpPost("[controller]/[action]/{IDAppt:int?}/{ActivityID:int?}/{VendorID:int?}/{PatientID:int?}")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> AddSPEPatientEval(SPEPatientEvalVM model)
{
    // 原有逻辑保持不变
    var patientChoice = GetPatientChoiceList();
    patientChoice[0].Selected = true;
    ViewBag.PatientChoice = patientChoice;

    model.DateSubmitted = DateTime.Now;

    if (ModelState.IsValid)
    {
        var spePatientEval = _mapper.Map<SPEPatientEval>(model);

        var success = await _speRepo.AddSPEPatientEval(spePatientEval);
        if (!success)
        {
            return View(model);
        }
        return View("Index");
    }
    return View(model);
}

这里给路由参数添加int?标记为可选,确保不带参数的Post请求也能匹配。

方案2:修改表单,提交到不带参数的地址

调整form标签,明确指定提交地址为不带参数的路由,避免沿用Get方法的参数格式:

<form asp-controller="SPE" asp-action="AddSPEPatientEval" method="post" 
      asp-route-IDAppt="" asp-route-ActivityID="" asp-route-VendorID="" asp-route-PatientID="">

或者直接手动指定action属性:

<form action="/SPE/AddSPEPatientEval" method="post">

这样表单提交时会发送到/SPE/AddSPEPatientEval,匹配现有的Post方法路由。

额外优化

View中手动给DateSubmitted隐藏字段赋值了格式化日期,但控制器里又重新设置了model.DateSubmitted = DateTime.Now;,建议删除View中的该隐藏字段赋值,统一由控制器处理,避免逻辑冲突。

内容的提问来源于stack exchange,提问作者Chris Woodard

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 04:01:07