Umbraco中BeginUmbracoForm错误提交至非目标控制器问题
Umbraco中BeginUmbracoForm提交至错误控制器的问题分析与解决
无法确定为何Html.BeginUmbracoForm生成的表单会提交至错误的控制器,推测这与隐藏字段upfrt中的数据有关,但找不到解决方案,也无法理解其原因。具体场景流程如下:
- MainFormController(RenderController类型)返回视图MyMainView;
- MyMainView加载MyViewComponent;
- MyViewComponent返回视图MyFormView;
- MyFormView使用
Html.BeginUmbracoForm,期望提交至SecondaryFormController(SurfaceController类型)。
但表单始终提交至MainFormController,需明确问题原因,以及触发Umbraco将请求路由至MainFormController而非SecondaryFormController的机制。
精简代码示例
MainFormController
public class MainFormController: RenderController { public MainFormController() {} public override IActionResult Index() { var viewModel = new MainFormControllerViewModel() { // 省略属性赋值 }; return CurrentTemplate(viewModel); // 返回MyMainView视图 } }
MyMainView视图
@inherits UmbracoViewPage<MyApp.MainFormControllerViewModel> @(await Component.InvokeAsync<MyApp.MyViewComponent>())
MyViewComponent
public class MyViewComponent: ViewComponent { public MyViewComponent() {} public async Task<IViewComponentResult> InvokeAsync() { return View(new MyViewComponentViewModel()); } }
MyFormView视图(ViewComponent对应的视图)
@model MyApp.MyViewComponentViewModel @using(Html.BeginUmbracoForm<MyApp.SecondaryFormController>( nameof(MyApp.SecondaryFormController.MyAction), "Update", null )) { <button type="submit">Update</button> }
SecondaryFormController.MyAction
public class SecondaryFormController: SurfaceController { public SecondaryFormController() {} [HttpPost] [ValidateAntiForgeryToken] [UnsupportedOSPlatform("browser")] public async Task<IActionResult> MyAction(MyViewComponentViewModel model) { // 业务逻辑处理 return CurrentUmbracoPage(); } }
测试补充情况
- 弃用
BeginUmbracoForm改用普通表单,可提交至SecondaryFormController.MyAction,但会丢失Umbraco上下文,不可行; - 移除ViewComponent,直接在MyMainView中渲染表单,问题依旧。
问题原因与解决方法
核心原因
- 错误的特性标记:
SecondaryFormController.MyAction上的[UnsupportedOSPlatform("browser")]特性是关键问题,它会直接拒绝浏览器发起的请求,导致Umbraco无法将请求路由到该Action,转而 fallback 到当前页面的RenderController(MainFormController)处理。 BeginUmbracoForm参数误用:第二个参数"Update"指定了HttpMethod,但Action已标记[HttpPost],多余的参数可能干扰路由生成;- Umbraco路由优先级:RenderController的路由优先级高于SurfaceController,当SurfaceController的Action无法被正确匹配时,请求会被当前页面的RenderController接管。
解决步骤
移除
UnsupportedOSPlatform特性:
直接删除该特性,确保浏览器发起的POST请求能正常到达Action:[HttpPost] [ValidateAntiForgeryToken] public async Task<IActionResult> MyAction(MyViewComponentViewModel model) { // 业务逻辑处理 return CurrentUmbracoPage(); }修正
BeginUmbracoForm调用:
去掉多余的HttpMethod参数,使用正确的重载:@using(Html.BeginUmbracoForm<MyApp.SecondaryFormController>( nameof(MyApp.SecondaryFormController.MyAction), null )) { <button type="submit">Update</button> }若存在区域路由冲突,可明确指定空区域:
@using(Html.BeginUmbracoForm<MyApp.SecondaryFormController>( nameof(MyApp.SecondaryFormController.MyAction), new { area = "" } )) { <button type="submit">Update</button> }验证SurfaceController路由:
可手动指定表单action属性测试路由是否正常:<form action="/umbraco/surface/SecondaryForm/MyAction" method="post"> @Html.AntiForgeryToken() <button type="submit">Update</button> </form>若此方式有效,说明
BeginUmbracoForm生成路由时存在命名空间或类名拼写问题,需检查控制器类的命名空间是否正确。
内容的提问来源于stack exchange,提问作者monkeySeeMonkeyDo
相关产品推荐
相关产品推荐

