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
相关产品推荐
相关产品推荐

