首页 > 解决方案 > 通过 ajax 将视图模型发送到控制器 - 它是如何工作的?

问题描述

我不明白为什么,有时通过 ajax 发送对象有效,有时则无效。我有一个例子 - 一切都发生在 1 个视图中,我有 2 个视图组件

第一 - 视图组件的视图

@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&nbsp;&nbsp;&nbsp;<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>

第一 - 控制器中的动作

[HttpPost]
[ValidateAntiForgeryToken]
[Route(RouteUrl.ShoppingCart + "/cs")]
public IActionResult Shippping([FromBody] ShippingViewModel svm)

以上代码效果很好 - 我正在接受ShippingViewModel

然后在同一个视图中我有第二个视图组件

第二 - 视图组件的视图/相同的方法

@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&nbsp;&nbsp;&nbsp;<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>")

2nd - 控制器中的动作

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

发送数据 画面

标签: c#jsonajaxasp.net-core

解决方案


推荐阅读