如何确保ASP.NET MVC控制器方法由Ajax调用而非普通POST请求?
问题分析与解决方案
首先,你遇到的核心问题是:提交按钮同时触发了Ajax请求和表单的默认POST提交,所以不管你修改Ajax的URL或元素ID,表单都会默认提交到TestModels/Create方法,这就导致你误以为Ajax的修改没生效。下面一步步解决你的问题:
1. 先解决表单默认提交的冲突
你的提交按钮嵌套在Html.BeginForm()表单内部,点击按钮时浏览器会优先触发表单的默认POST行为,完全覆盖了你写的Ajax逻辑。要让Ajax单独生效,需要阻止表单的默认提交:
修改你的Ajax点击事件代码,添加event.preventDefault():
$(document).ready(function () { $('#btn_submit').click(function (event) { event.preventDefault(); // 关键:阻止表单默认提交行为 var testModel = { FirstName: $('#First_Name').val(), LastName: $('#LastName').val(), Gender: $("input[name='Gender']:checked").val(), Contact: $('#Contact').val(), Faculty: $('#Faculty').val(), RegNepaliDate: $('#inp_date').val() }; alert(JSON.stringify(testModel)); // 先获取防伪令牌(因为控制器有[ValidateAntiForgeryToken],必须带上) var token = $('input[name="__RequestVerificationToken"]').val(); $.ajax({ type: 'POST', url: '@Url.Action("Edit", "TestModels")', headers: { "RequestVerificationToken": token // 添加防伪令牌请求头 }, data: JSON.stringify(testModel), contentType: 'application/json;charset=utf-8', dataType: 'json', success: function (data) { if (data.success) { // 注意这里是data不是response(你之前的代码写错了) alert(data.responseText); } }, error: function (req, status, error) { console.log(error); } }) }) })
加上这段代码后,点击按钮就只会执行Ajax请求,不会触发表单的默认提交了。此时你修改Ajax的URL到Edit,就能看到控制器的Edit方法被调用,而不是Create。
2. 如何验证请求是Ajax而非普通POST?
有两种可靠的验证方式:
后端验证(最准确)
在控制器方法里检查请求的特殊标识:
- ASP.NET MVC(非Core):直接使用
Request.IsAjaxRequest()方法:
[HttpPost] [ValidateAntiForgeryToken] public JsonResult Create(TestModel testModel, string LastName, string RegNepaliDate) { bool isAjax = Request.IsAjaxRequest(); if (isAjax) { // 处理Ajax请求的逻辑 if (ModelState.IsValid) { return Json(new { success = true, responseText = "这是Ajax请求:数据提交成功!" }, JsonRequestBehavior.AllowGet); } return Json(new { success = false, responseText = "Ajax请求:数据验证失败!" }, JsonRequestBehavior.AllowGet); } else { // 处理普通POST请求的逻辑 return Json(new { success = false, responseText = "这是普通POST请求!" }, JsonRequestBehavior.AllowGet); } }
- ASP.NET Core:
Request.IsAjaxRequest()被移除,需要手动检查请求头:
bool isAjax = Request.Headers["X-Requested-With"] == "XMLHttpRequest";
前端验证(辅助排查)
打开浏览器开发者工具(F12),切换到Network标签:
- Ajax请求的请求头里会包含
X-Requested-With: XMLHttpRequest - 普通POST请求则没有这个头
你可以通过观察这个请求头,快速判断当前请求是否为Ajax发起的。
额外提示:修复Ajax的小错误
你之前的Ajaxsuccess回调里用了response变量,但实际参数是data,这个小错误会导致你看不到成功提示,已经在上面的代码里修正了。
内容的提问来源于stack exchange,提问作者user4221591
相关产品推荐
相关产品推荐

