代码之家  ›  专栏  ›  技术社区  ›  OjM

视图组件在第二次提交时未检测/返回Ajax请求

  •  1
  • OjM  · 技术社区  · 9 年前

    我遇到了一个非常奇怪的问题,我的ajax post请求在页面加载后第一次运行良好,但如果我在不刷新页面的情况下再次提交表单,那么内容将返回到整个页面,而不仅仅是更新DIV。我花了数天时间寻找答案,并通过反复尝试,我怀疑问题与 Request.Headers["X-Requested-With"] 第二次提交时为空。注意,我将视图组件返回到ajax请求,我的ajax代码在单独的js文件中。

    视图组件(它包含在ajax请求返回时提交和替换的表单。在页面加载或刷新后,它可以正常工作)

    @model MSIC.Models.ClientViewModels.VisitMovementViewModel
    @{
        bool inProgress = (bool)ViewData["inProgress"];
    }
    <form asp-controller="Client" asp-action="VisitMovement" asp-route-id="@Model.VisitMovementID" id="formVisitAction" method="post" onsubmit="AjaxSubmit(this)">
        <input asp-for="VisitID" type="hidden" />
        <input asp-for="StageNo" type="hidden" />
        <input type="hidden" id="replaceID" name="replaceID" value="#ClientVisit" />
        <input type="hidden" id="submitAction" name="submitAction" />
        <div class="col-md-9 no-padding">
            <input type="text" id="visitMovementComment" name="visitMovementComment" class="form-control" placeholder="Comment..." required>
        </div>
        <div class="input-group col-md-3">
            <input type="text" id="visitMovementBoothNo" name="visitMovementBoothNo" class="form-control" placeholder="Booth..." required>
            <div class="input-group-btn">
                <button type="button" class="btn btn-success dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" @((inProgress) ? "" : "disabled")>Action <span class="caret"></span></button>
                <ul class="dropdown-menu dropdown-menu-right">
                    @if (Model.Buttons != null)
                    {
                        foreach (var item in Model.Buttons)
                        {
                            if (item.beforeDivider)
                            {
                                <li><button type="@item.Type" name="@item.Name" class="btn btn-link btn-block btn-flat" value="@item.Value" onclick="@item.OnClick">@item.Text</button></li>
                            }
                        }
                        <li role="separator" class="divider"></li>
                        foreach (var item in Model.Buttons)
                        {
                            if (!item.beforeDivider)
                            {
                                <li><button type="@item.Type" name="@item.Name" class="btn btn-link btn-block btn-flat" value="@item.Value" onclick="@item.OnClick">@item.Text</button></li>
                            }
                        }
                    }
                </ul>
            </div>
        </div>
    </form>
    

    Ajax请求位于单独的JS文件中(在调试时,一切都会按预期运行,但在视图组件返回后,表单第二次提交后,成功、错误、完整函数不会触发,返回的数据将加载到整个页面)

    function AjaxSubmit(form) {
        $form = $(form);
        var replaceID = $('input#replaceID', $form).val();
        var formData = $form.serialize();
    
        if (!$form[0].checkValidity()) {
            return false;
        }
    
        $form.submit(function (e) {
            e.preventDefault();
            $.ajax({
                url: $form.attr('action'),
                type: $form.attr('method'),
                data: formData,
                async: true,
                processData: false,
                cache: false,
                success: function (data) {
                    $(replaceID).html(data);
                },
                error: function (xhr, status, error) {
                    console.log(xhr.status + " - " + error);
                },
                complete: function (data) {
                    console.log(data);
                }
            });
        });
    }
    

    行动方法(我怀疑问题可能与 请求.标题[“X-Requested-With”] 在第二次提交时为空,因此MVC没有意识到这是一个ajax请求,因此将结果返回到页面,而不是返回到ajax请求)

    [HttpPost]
    [ValidateAntiForgeryToken]
    public async Task<IActionResult> VisitMovement(int id, int submitAction, int? visitMovementBoothNo, string visitMovementComment, VisitMovementViewModel model)
    {
        var test1 = Request.ContentType; //1ST REQUEST = "application/x-www-form-urlencoded; charset=UTF-8", 2ND REQUEST = "application/x-www-form-urlencoded"
        var test2 = Request.Headers["X-Requested-With"]; //1ST REQUEST = "XMLHttpRequest", 2ND REQUEST = Empty
    
        try
        {
            if (ModelState.IsValid)
            {
                bool complete = false;
    
                switch (submitAction)
                {
                    case 2: //Proceed to Stage 2
                        model.StageNo = 2;
                        break;
                    case 3: //Proceed to Stage 3
                        model.StageNo = 3;
                        break;
                    case 4: //Complete Visit
                        complete = true;
                        break;
                    default:
                        return BadRequest("Could not determine action.");
                }
    
                await visitAPI.VisitMovement(id, model.VisitID, submitAction, model.StageNo, visitMovementBoothNo, visitMovementComment, complete);
    
                return ViewComponent("ClientVisit", new { visitID = model.VisitID });
    
            }
            else
            {
                return BadRequest(ModelState);
            }
    
        }
        catch (Exception ex)
        {
            return StatusCode(500, ex.Message);
        }
    
    }
    

    如果我的假设是正确的,为什么ajax请求在第二次提交时没有发送正确的头,我如何修复它?如果不是,还有什么问题?

    1 回复  |  直到 8 年前
        1
  •  1
  •   OjM    9 年前

    我认为问题在于数据/视图组件返回时表单提交事件丢失。我解决了这个问题,将我的ajax文章改为如下。。。

    $(document).on('submit', 'form.ajax-form', function (e) {
        var replaceID = $('input#replaceID', $(this)).val();
        var replaceType = $('input#replaceType', $(this)).val();
        e.preventDefault();
        $.ajax({
            url: $(this).attr('action'),
            type: $(this).attr('method'),
            data: $(this).serialize(),
            async: true,
            processData: false,
            cache: false,
            success: function (data) {
                $(replaceID).html(data);
            },
            error: function (xhr, status, error) {
                AjaxOnFailure(xhr, status, error);
            }
        });
    });
    
    推荐文章