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

HttpPost未跳转至View问题:模态框局部视图提交异常

问题描述

我有一个打开模态框编辑名称的按钮,代码如下:

<button type="button" data-toggle="modal" 
        OnClick="showInPopup('@Url.Action("EditName", "ChangeRequest", new { Id = sf.Id }, Context.Request.Scheme)', 'Edit Name9')" 
        data-target="#modalDiv" class="btn btn-sm btn-info">
    <i class="fas fa-pencil-alt"></i>
</button>

模态框代码:

<!-- Edit Folder Modal -->
<div class="modal fade" id="editModal" tabindex="-1" role="dialog" aria-labelledby="editModalLabel" aria-hidden="true">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-header">
                <h5 class="modal-title" id="exampleModalLabel">Edit Name</h5>
            </div>
            <div class="modal-body" id="modalContent">
                ...
            </div>
        </div>
    </div>
</div>

打开模态框的AJAX脚本:

showInPopup = (url, title) => {
    $.ajax({
        type: 'GET',
        url: url,
        success: function (res) {
            $('#editModal .modal-body').html(res);
            $('#editModal .modal-title').html(title);
            $('#editModal').modal('show');
            // to make popup draggable
            //$('.modal-dialog').draggable({
            //    handle: ".modal-header"
            //});
        }
    })
}

模态框内的局部视图代码:

@model RequestViewModel

@{
    Layout = null;
}

<div class="row">
    <form asp-action="EditName" asp-route-id="@Model.SharedFile.Id" onsubmit="return jQueryAjaxPost(this);">
        <fieldset>
            <div class="form-group py-3">
                @Html.HiddenFor(x => x.SharedFile.Id)
                <h3>New Folder Name</h3>
                @* <label for="txtNewFoldName" class="form-label mt-4">New Folder Name</label> *@
@*                 <input asp-for="SharedFile.FileName" class="form-control" name="fileName"/> *@
                <input class="form-control" id="=txtNewFoldName" name="fileOrFolderName" value="@Model.SharedFile.FileName">
            </div>
        </fieldset>
        <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Close</button>
            <button type="submit" class="btn btn-primary">Save changes</button>
        </div>
    </form>
</div>

表单提交的AJAX脚本:

jQueryAjaxPost = form => {
    try {
        $.ajax({
            type: 'POST',
            url: form.action,
            data: new FormData(form),
            contentType: false,
            processData: false,
            success: function (res) {
                if (res.isValid) {
                    $('#editModal .modal-body').html('');
                    $('#editModal .modal-title').html('');
                    $('#editModal').modal('hide');
                }
                else
                    $('#form-modal .modal-body').html(res.html);
            },
            error: function (err) {
                console.log(err)
            }
        })
        //to prevent default form submit event
        return false;
    } catch (ex) {
        console.log(ex)
    }
}

后端HttpPost控制器方法:

[HttpPost]
public ActionResult EditName(int id, string fileOrFolderName, BaseViewModel bvm)
{
    RequestViewModel rvm = ChangeRequest.SubmitEditFileOrFolderNameRequest(bvm.SharedFile, fileOrFolderName, User.Identity.Name, _memoryCache);
    rvm.SharedFile = DAL.GetFolderContents(id);

    return View("Confirmation", rvm);
}

目前所有流程正常执行,POST方法能正确接收数据,控制器已执行到return View("Confirmation", rvm)断点,但页面并未跳转至确认页,尝试RedirectToAction也无效。而页面上非局部视图的按钮可以正常跳转至确认页,请问是否是模态框内的局部视图导致的问题?


问题原因

核心问题不是模态框或局部视图,而是表单提交使用了AJAX异步请求:

  • 非模态框的按钮是普通表单提交(未通过AJAX拦截),浏览器会直接处理服务器返回的跳转或视图响应,因此能正常跳转。
  • 模态框内的表单通过jQueryAjaxPost函数用AJAX提交,AJAX默认会异步接收服务器返回的响应内容,不会自动触发页面跳转——哪怕控制器返回View或RedirectToAction,结果都会被传到AJAX的success回调里,而不是让浏览器加载新页面。

解决方案

根据需求选择以下方案之一:

方案1:AJAX成功后手动跳转(直接跳转到确认页)

修改控制器方法,返回确认页的URL,然后在AJAX回调中执行页面跳转:

控制器修改:

[HttpPost]
public ActionResult EditName(int id, string fileOrFolderName, BaseViewModel bvm)
{
    RequestViewModel rvm = ChangeRequest.SubmitEditFileOrFolderNameRequest(bvm.SharedFile, fileOrFolderName, User.Identity.Name, _memoryCache);
    rvm.SharedFile = DAL.GetFolderContents(id);

    // 返回JSON数据,包含跳转URL和验证状态
    return Json(new 
    { 
        isValid = true, 
        redirectUrl = Url.Action("Confirmation", "ChangeRequest", new { /* 传递确认页需要的参数 */ }) 
    });
}

AJAX脚本修改:

jQueryAjaxPost = form => {
    try {
        $.ajax({
            type: 'POST',
            url: form.action,
            data: new FormData(form),
            contentType: false,
            processData: false,
            success: function (res) {
                if (res.isValid) {
                    $('#editModal').modal('hide');
                    // 手动跳转到确认页
                    window.location.href = res.redirectUrl;
                }
                else
                    $('#editModal .modal-body').html(res.html);
            },
            error: function (err) {
                console.log(err)
            }
        })
        return false;
    } catch (ex) {
        console.log(ex)
    }
}

方案2:在模态框中显示确认页内容

如果不需要跳转页面,而是在模态框内展示确认信息,可以保持控制器返回View("Confirmation", rvm),然后修改AJAX回调:

success: function (res) {
    if (res.isValid) {
        // 替换模态框内容为确认页
        $('#editModal .modal-body').html(res);
        $('#editModal .modal-title').html('操作确认');
    }
    else
        $('#editModal .modal-body').html(res.html);
}

注意:确认页视图需要设置Layout = null;,避免加载完整布局。

方案3:放弃AJAX,使用普通表单提交

如果不需要异步提交的体验,可以移除onsubmit="return jQueryAjaxPost(this);",让表单以普通方式提交:

<form asp-action="EditName" asp-route-id="@Model.SharedFile.Id">
    <!-- 表单内容不变 -->
</form>

这种方式下,控制器返回View或RedirectToAction都会正常触发页面跳转,和非模态框的按钮行为一致。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 04:57:03