Я не могу понять почему, иногда отправка объекта с помощью ajax работает, а иногда нет. У меня есть пример - все происходит в 1 представлении, где у меня есть 2 компонента вида
1-й - вид компонента вида
@model ShippingViewModel
<input type="hidden" name="step" value="@ShoppingCartHelper.TokenShipping" />
<input type="hidden" asp-for="CustomerId" />
<div class="form-group">
<label asp-for="FirstName" class="m-1"></label>
<div><span asp-validation-for="FirstName" class="text-danger"></span></div>
<input asp-for="FirstName" class="form-control" />
</div>
<div class="form-group">
<label asp-for="LastName" class="m-1"></label>
<div><span asp-validation-for="LastName" class="text-danger"></span></div>
<input asp-for="LastName" class="form-control" />
</div>
<div class="form-group">
<label asp-for="Email" class="m-1"></label>
<div><span asp-validation-for="Email" class="text-danger"></span></div>
<input asp-for="Email" class="form-control" />
</div>
<div class="form-group">
<label asp-for="Address" class="m-1"></label>
<div><span asp-validation-for="Address" class="text-danger"></span></div>
<input asp-for="Address" class="form-control" />
</div>
<div class="form-group">
<label asp-for="AddressNumber" class="m-1"></label>
<div><span asp-validation-for="AddressNumber" class="text-danger"></span></div>
<input asp-for="AddressNumber" class="form-control" />
</div>
<div class="form-group">
<label asp-for="City" class="m-1"></label>
<div><span asp-validation-for="City" class="text-danger"></span></div>
<input asp-for="City" class="form-control" />
</div>
<div class="form-group">
<label asp-for="ZipCode" class="m-1"></label>
<div><span asp-validation-for="ZipCode" class="text-danger"></span></div>
<input asp-for="ZipCode" class="form-control" />
</div>
<div class="form-group form-check">
<input type="checkbox" class="form-check-input" id="isTheSame">
<label class="form-check-label" for="isTheSame">Czy dane płatnika mają być takie same jak dane wysyłki?</label>
</div>
<button class="btn" id="save-shipping">Dalej <i class="fa fa-level-down" aria-hidden="true"></i></button>
<script type="text/javascript">
$(document).ready(function () {
$('#save-shipping').on('click', function () {
var ShippingViewModel = {
CustomerId: $('input[name="CustomerId"]').val(),
FirstName: $('input[name="FirstName"]').val(),
LastName: $('input[name="LastName"]').val(),
Email: $('input[name="Email"]').val(),
Address: $('input[name="Address"]').val(),
AddressNumber: $('input[name="AddressNumber"]').val(),
City: $('input[name="City"]').val(),
ZipCode: $('input[name="ZipCode"]').val(),
IsTheSame: $('input[id="isTheSame"]').is(':checked'),
};
$.ajax({
type: "POST",
url: '/koszyk/cs',
data: JSON.stringify(ShippingViewModel),
contentType: "application/json; charset=utf-8",
dataType: "json",
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val());
},
error: function (xhr) {
if (xhr.status != 200) window.location.href = "/home/error/" + xhr.status;
},
complete: function (xhr) {
if (xhr.responseText.includes('@ShoppingCartHelper.TokenShipping')) {
$('#ShoppingCartCustomerShipping').html(xhr.responseText);
} else if (xhr.responseText.includes('@ShoppingCartHelper.TokenBilling')) {
$('#ShoppingCartCustomerShipping').hide();
$('#ShoppingCartCustomerBilling').html(xhr.responseText);
}
}
});
});
});
</script>
1-й - действие вконтроллер
[HttpPost]
[ValidateAntiForgeryToken]
[Route(RouteUrl.ShoppingCart + "/cs")]
public IActionResult Shippping([FromBody] ShippingViewModel svm)
и выше, код работает отлично - я получаю ShippingViewModel
и затем на том же виде у меня есть 2-й компонент вида
2-й - вид компонента вида / тот же подход
@model BillingViewModel
@if ((Model.BillingSteps != (int)CustomerModel.StepEnum.None) && (Model.BillingSteps == (int)CustomerModel.StepEnum.Shipping))
{
@Html.Raw("<div style=\"display:block;\">")
}
else
{
@Html.Raw("<div style=\"display:none;\">")
}
<input type="hidden" value="@ShoppingCartHelper.TokenBilling" />
<input type="hidden" asp-for="BillingCustomerId" />
<div class="form-group">
<label asp-for="BillingFirstName" class="m-1"></label>
<div><span asp-validation-for="BillingFirstName" class="text-danger"></span></div>
<input asp-for="BillingFirstName" class="form-control" />
</div>
<div class="form-group">
<label asp-for="BillingLastName" class="m-1"></label>
<div><span asp-validation-for="BillingLastName" class="text-danger"></span></div>
<input asp-for="BillingLastName" class="form-control" />
</div>
<div class="form-group">
<label asp-for="BillingEmail" class="m-1"></label>
<div><span asp-validation-for="BillingEmail" class="text-danger"></span></div>
<input asp-for="BillingEmail" class="form-control" />
</div>
<div class="form-group">
<label asp-for="BillingAddress" class="m-1"></label>
<div><span asp-validation-for="BillingAddress" class="text-danger"></span></div>
<input asp-for="BillingAddress" class="form-control" />
</div>
<div class="form-group">
<label asp-for="BillingAddressNumber" class="m-1"></label>
<div><span asp-validation-for="BillingAddressNumber" class="text-danger"></span></div>
<input asp-for="BillingAddressNumber" class="form-control" />
</div>
<div class="form-group">
<label asp-for="BillingCity" class="m-1"></label>
<div><span asp-validation-for="BillingCity" class="text-danger"></span></div>
<input asp-for="BillingCity" class="form-control" />
</div>
<div class="form-group">
<label asp-for="BillingZipCode" class="m-1"></label>
<div><span asp-validation-for="BillingZipCode" class="text-danger"></span></div>
<input asp-for="BillingZipCode" class="form-control" />
</div>
<button class="btn" id="save-billing">Dalej <i class="fa fa-level-down" aria-hidden="true"></i></button>
<script type="text/javascript">
$(document).ready(function () {
$('#save-billing').on('click', function () {
var BillingViewModel = {
BillingCustomerId: $('input[name="BillingCustomerId"]').val(),
BillingFirstName: $('input[name="BillingFirstName"]').val(),
BillingLastName: $('input[name="BillingLastName"]').val(),
BillingEmail: $('input[name="BillingEmail"]').val(),
BillingAddress: $('input[name="BillingAddress"]').val(),
BillingAddressNumber: $('input[name="BillingAddressNumber"]').val(),
BillingCity: $('input[name="BillingCity"]').val(),
BillingZipCode: $('input[name="BillingZipCode"]').val(),
};
console.log(BillingViewModel);
$.ajax({
type: "POST",
url: '/koszyk/cb',
data: JSON.stringify(BillingViewModel),
contentType: "application/json; charset=utf-8",
dataType: "json",
beforeSend: function (xhr) {
xhr.setRequestHeader("XSRF-TOKEN", $('input:hidden[name="__RequestVerificationToken"]').val());
},
error: function (xhr) {
if (xhr.status != 200) window.location.href = "/home/error/" + xhr.status;
},
complete: function (xhr) {
if (xhr.responseText.includes('@ShoppingCartHelper.TokenBilling')) {
$('#ShoppingCartCustomerBilling').html(xhr.responseText);
} else if (xhr.responseText.includes('@ShoppingCartHelper.TokenPayment')) {
$('#ShoppingCartCustomerBilling').hide();
$('#ShoppingCartCustomerPayment').html(xhr.responseText);
}
}
});
});
});
</script>
@Html.Raw("</div>")
2-й - действие в контроллере
[HttpPost]
[ValidateAntiForgeryToken]
[Route(RouteUrl.ShoppingCart + "/cb")]
public IActionResult Billing([FromBody] BillingViewModel bvm)
и вот - яполучение BillingViewModel - null
и я не понимаю WHY
первый вызов ajax, отправляющий модель, и второе отправление
Я нашел обходной путь - вставил [FromBody] BillingViewModel bvm
я звонил [FromBody] object bvm
и тогда я звоню deserialized bvm
- и он работает
Вопрос
Что именно я делаю не так? Оказывается, я не понимаю, как работает AJAX в ядре ASP. Я не вижу ошибок в своем коде.
РЕДАКТИРОВАТЬ: Модель
public int BillingCustomerId { get; set; }
public string BillingFirstName { get; set; }
public string BillingLastName { get; set; }
public string BillingAddress { get; set; }
public string BillingAddressNumber { get; set; }
public string BillingZipCode { get; set; }
public string BillingCity { get; set; }
public string BillingEmail { get; set; }
public int BillingSteps { get; set; }
отправка данных экран отправки данных