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

NopCommerce 4.3开发Widget调用Action时路由匹配到商品页问题

问题根因分析

1. 为什么会命中Nop.Web.Controllers.ProductController.ProductDetails方法?

这是核心问题:你没有阻止form表单的默认提交行为。你的提交按钮是type="submit"类型,点击后会优先触发form的原生提交逻辑,你的form没有指定action属性,默认就会提交到当前页面的URL(也就是你日志里的产品详情页地址/aliento-de-ogro),所以路由直接匹配到了产品详情的Action,你的AJAX逻辑甚至可能还没执行就已经触发了原生提交。

2. 为什么后端收到的是application/x-www-form-urlencoded类型?

这个格式是原生表单提交的默认Content-Type,你在AJAX里设置的contentType根本没有生效,因为当前生效的请求是表单的原生提交,不是你写的AJAX请求。

修复步骤

  • 第一步:阻止表单默认提交行为,将AJAX逻辑绑定到表单提交事件上,第一行增加阻止默认行为的代码:
$('#AjaxForm').on('submit', function(e) {
  // 关键:阻止原生表单提交
  e.preventDefault();
  
  // 此处放入你原来的AJAX代码,同时修正下面几个参数错误
  $.ajax({
    type: "post",
    // 如果你的Widget是插件开发,需要指定area参数为你的插件名称,否则Url.Action会找不到控制器
    url: "@Url.Action("TakePhoto", "Photo", new { area = "你的插件名称" })",
    // dataType是期望后端返回的数据格式,填"json"即可,不需要写完整MIME类型
    dataType: "json",
    // 去掉选择器里多余的冒号,否则拿不到正确的防伪token
    headers: { "RequestVerificationToken": $('input[name="__RequestVerificationToken"]').val() },
    data: JSON.stringify({
      ProductId: $("#productId").val(),
      Role: role,
      ExpressionName: expressionName,
      Photo: $("#photo").attr('src') 
    }),
    contentType: "application/json; charset=utf-8"
  }).done(function (result) {                    
    alert(result.Message);
  }).fail(function (xhr, status, error) { 
    console.log(error);
  });
})
  • 第二步:确认Photo控制器的路由配置。如果是NopCommerce插件的控制器,需要放在插件的Controllers目录下,并且插件要正确注册区域路由,否则系统会默认去根站点的Controllers目录下查找PhotoController,找不到就会继续匹配其他路由,最终落到产品详情页的路由规则上。
  • 第三步:控制器的Action方法需要加上[HttpPost]特性,如果接收JSON格式的参数,需要给参数添加[FromBody]标记,示例:
[HttpPost]
public IActionResult TakePhoto([FromBody] TakePhotoRequest request)
{
    // 业务逻辑处理
    return Json(new { Message = "处理成功" });
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.08 14:57:01