ASP.NET Core 8 MVC控制器表单提交URL错误问题求助
解决ASP.NET Core 8 MVC表单提交URL带/api前缀的问题
问题根源
你存在两个同名的ProjectsController:一个继承ControllerBase(API控制器,通常配置了[Route("api/[controller]")]路由属性),另一个继承Controller(MVC控制器)。路由系统自动生成表单action时,错误匹配到了API控制器的路由模板,导致URL被加上/api前缀。
解决方案
1. 给MVC控制器显式指定路由
在MVC的ProjectsController上添加路由属性,明确其路由前缀为/Projects,与API控制器的/api/Projects彻底区分:
[Route("[controller]")] public class ProjectsController : Controller { // GET: Projects/Delete/5 [HttpGet("Delete/{id}")] public async Task<IActionResult> Delete(string id) { // 你的现有代码逻辑 } // POST: Projects/Delete/5 [HttpPost("Delete/{id}")] [ValidateAntiForgeryToken] public ActionResult Delete(string id, IFormCollection? collection) { // 你的现有代码逻辑 } }
2. 在视图中强制生成正确的MVC路由
不要依赖表单action的自动生成,用ASP.NET Core的Tag Helper或Url.Action明确指定目标控制器和方法:
方法一:使用Tag Helper(推荐)
<form asp-controller="Projects" asp-action="Delete" asp-route-id="@Model.Id" method="post" asp-antiforgery="true"> <input type="text" data-val="true" data-val-required="The Title field is required." id="Title" name="Title" value="@Model.Title"> <input type="text" data-val="true" data-val-required="The ProjectNumber field is required." id="ProjectNumber" name="ProjectNumber" value="@Model.ProjectNumber"> <input type="text" data-val="true" data-val-required="The ProjectClientNumber field is required." id="ProjectClientNumber" name="ProjectClientNumber" value="@Model.ProjectClientNumber"> <input type="text" data-val="true" data-val-required="The ProjectContractNumber field is required." id="ProjectContractNumber" name="ProjectContractNumber" value="@Model.ProjectContractNumber"> <input type="submit" value="Delete" class="btn btn-danger"> | <a href="/Projects">Back to List</a> </form>
Tag Helper会自动生成正确的action URL,并自动添加防伪令牌。
方法二:使用Url.Action
<form action="@Url.Action("Delete", "Projects", new { id = Model.Id })" method="post"> @Html.AntiForgeryToken() <input type="text" data-val="true" data-val-required="The Title field is required." id="Title" name="Title" value="@Model.Title"> <input type="text" data-val="true" data-val-required="The ProjectNumber field is required." id="ProjectNumber" name="ProjectNumber" value="@Model.ProjectNumber"> <input type="text" data-val="true" data-val-required="The ProjectClientNumber field is required." id="ProjectClientNumber" name="ProjectClientNumber" value="@Model.ProjectClientNumber"> <input type="text" data-val="true" data-val-required="The ProjectContractNumber field is required." id="ProjectContractNumber" name="ProjectContractNumber" value="@Model.ProjectContractNumber"> <input type="submit" value="Delete" class="btn btn-danger"> | <a href="/Projects">Back to List</a> </form>
3. 确认API控制器的路由配置
确保API控制器的路由模板明确带有/api前缀,避免与MVC路由混淆:
[ApiController] [Route("api/[controller]")] public class ProjectsController : ControllerBase { // 示例API方法 [HttpGet("{id}")] public IActionResult GetProject(string id) { // API逻辑代码 } }
额外检查
检查Program.cs中的路由注册顺序,确保MVC路由(app.MapControllerRoute)和API路由(app.MapControllers)的配置不存在模糊匹配。只要控制器路由明确,一般无需调整顺序。
内容的提问来源于stack exchange,提问作者mustafa.salaheldin
相关产品推荐
相关产品推荐

