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

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中渲染表单,问题依旧。

问题原因与解决方法

核心原因

  1. 错误的特性标记:SecondaryFormController.MyAction上的[UnsupportedOSPlatform("browser")]特性是关键问题,它会直接拒绝浏览器发起的请求,导致Umbraco无法将请求路由到该Action,转而 fallback 到当前页面的RenderController(MainFormController)处理。
  2. BeginUmbracoForm参数误用:第二个参数"Update"指定了HttpMethod,但Action已标记[HttpPost],多余的参数可能干扰路由生成;
  3. Umbraco路由优先级:RenderController的路由优先级高于SurfaceController,当SurfaceController的Action无法被正确匹配时,请求会被当前页面的RenderController接管。

解决步骤

  1. 移除UnsupportedOSPlatform特性:
    直接删除该特性,确保浏览器发起的POST请求能正常到达Action:

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> MyAction(MyViewComponentViewModel model) {
      // 业务逻辑处理
      return CurrentUmbracoPage();
    }
    
  2. 修正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>
        }
    
  3. 验证SurfaceController路由:
    可手动指定表单action属性测试路由是否正常:

    <form action="/umbraco/surface/SecondaryForm/MyAction" method="post">
      @Html.AntiForgeryToken()
      <button type="submit">Update</button>
    </form>
    

    若此方式有效,说明BeginUmbracoForm生成路由时存在命名空间或类名拼写问题,需检查控制器类的命名空间是否正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 07:32:04