View Component not detecting/returning Ajax request on 2nd submit

一个人想着一个人 提交于 2020-01-05 04:07:12

问题


I've got a really strange problem where my ajax post request works fine the first time after the page has loaded but if I submit my form again without doing a page refresh then the contents are returned to the whole page instead of just updating the DIV. I've spent days on this looking for answers and through trial and error and I suspect the issue relates to Request.Headers["X-Requested-With"] being empty on 2nd submit. Note that I am returning a View Component to the ajax request and my ajax code is in a separate js file.

View Component (this contains the form that gets submitted and gets replaced when the ajax request returns. It works correctly after the page has been loaded or refreshed)

@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 Request located in separate JS file (when debugging this everything runs through as expected the first time however after the View Component is returned and the form is submitted the 2nd time the success, error, complete functions never fire and the returned data loads in the whole page)

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);
            }
        });
    });
}

Action Method (I suspect the issue may be related to the Request.Headers["X-Requested-With"] being Empty on the 2nd submit and therefore MVC does not realise this is an ajax request hence returns the result to the page instead of returning it to the ajax request)

[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);
    }

}

If my assumption is correct why is the ajax request not sending the the correct headers when it is submitted the 2nd time and how can i fix it? If not what else could be going wrong?


回答1:


I think the problem was the form submit event was being lost when the data/view component returned. I solved the problem by changing my ajax post to below...

$(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);
        }
    });
});


来源:https://stackoverflow.com/questions/40954683/view-component-not-detecting-returning-ajax-request-on-2nd-submit

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!