.NET 6迁移后Html.BeginForm控制器路径斜杠转%2F问题排查
问题描述
将应用从.NET Framework 4.8迁移到.NET 6后,Html.BeginForm出现异常行为:会将控制器路径中的斜杠转换为%2F,导致对应的接口无法访问。
原本应生成的form标签为:
<form action="/Admin/Report/DownloadReport" enctype="multipart/form-data" method="post">
现在生成的form标签变为:
<form action="/Admin%2FReport/DownloadReport" enctype="multipart/form-data" method="post">
出现该问题的代码示例:
<div class="form-container"> @using (Html.BeginForm("DownloadReport", "Admin/Report", FormMethod.Post, new { enctype = "multipart/form-data" })) { @Html.Hidden("requestReportName", "PageReport"); <span class="epi-cmsButton"> <input class="epi-cmsButton-text epi-cmsButton-tools epi-cmsButton-Export" type="submit" name="btnSubmitDownloadPageReport" id="btnSubmitDownloadPageReport" value="Download Report" /> </span> } </div>
当前路由配置如下:
endpoints.MapControllerRoute( name: "Admin", pattern: "Admin/{controller}/{action=Index}");
未找到Html.BeginForm在.NET 6中已过时的相关信息,请问该异常行为的原因是什么?
问题原因及解决方法
原因
.NET 6(ASP.NET Core)的Html.BeginForm对控制器参数的解析逻辑与.NET Framework存在本质差异:
- 在.NET Framework中,允许控制器参数包含斜杠(如
"Admin/Report"),框架会自动将其拆分为路由前缀和控制器名称; - 但在ASP.NET Core中,控制器参数会被视为单个完整的控制器名称处理,斜杠属于URL特殊字符,会被自动编码为
%2F,而ASP.NET Core路由系统无法识别编码后的路径,导致接口无法匹配访问。
结合你的路由配置Admin/{controller}/{action=Index},Admin是路由前缀,{controller}是控制器名占位符,不能将Admin/Report当作控制器参数传入。
解决方法
有两种可行的修正方式:
- 修正
Html.BeginForm参数,传入正确的控制器名
直接将控制器参数改为"Report",路由系统会自动拼接Admin前缀生成正确路径:
<div class="form-container"> @using (Html.BeginForm("DownloadReport", "Report", FormMethod.Post, new { enctype = "multipart/form-data" })) { @Html.Hidden("requestReportName", "PageReport"); <span class="epi-cmsButton"> <input class="epi-cmsButton-text epi-cmsButton-tools epi-cmsButton-Export" type="submit" name="btnSubmitDownloadPageReport" id="btnSubmitDownloadPageReport" value="Download Report" /> </span> } </div>
- 使用
Html.BeginRouteForm指定路由名称
通过路由名称直接绑定路由规则,更明确地生成URL:
<div class="form-container"> @using (Html.BeginRouteForm("Admin", new { controller = "Report", action = "DownloadReport" }, FormMethod.Post, new { enctype = "multipart/form-data" })) { @Html.Hidden("requestReportName", "PageReport"); <span class="epi-cmsButton"> <input class="epi-cmsButton-text epi-cmsButton-tools epi-cmsButton-Export" type="submit" name="btnSubmitDownloadPageReport" id="btnSubmitDownloadPageReport" value="Download Report" /> </span> } </div>
内容的提问来源于stack exchange,提问作者cowefe
相关产品推荐
相关产品推荐

