Просмотр компонента, не обнаруживающего / не возвращающего Ajax-запрос при 2-й передаче
У меня действительно странная проблема, когда мой запрос на публикацию ajax нормально работает в первый раз после загрузки страницы, но если я снова отправляю свою форму без обновления страницы, то содержимое возвращается на всю страницу, а не просто обновляется DIV, Я потратил несколько дней на поиск ответов и методом проб и ошибок, и я подозреваю, что проблема связана с Request.Headers["X-Requested-With"]
будучи пустым на 2-й подаче. Обратите внимание, что я возвращаю View View в запрос ajax, и мой код ajax находится в отдельном файле js.
Компонент View (содержит форму, которая отправляется и заменяется при возврате 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 (при отладке все выполняется, как и ожидалось, в первый раз, однако после того, как компонент View возвращен и форма отправлена во 2-й раз, когда успех, ошибка, завершенные функции никогда не запускаются, а возвращаемые данные загружаются в вся страница)
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);
}
});
});
}
Метод действия (Я подозреваю, что проблема может быть связана с Request.Headers["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 ответ
Я думаю, что проблема заключалась в том, что событие отправки формы было потеряно при возврате компонента data/view. Я решил проблему, изменив мой пост 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);
}
});
});