简体   繁体   English

将 JavaScript 对象数组传递给控制器

[英]Passing JavaScript Array of Objects to Controller

I have a dynamic form that I'm needing to submit to my Controller.我有一个动态表单,需要提交给我的控制器。 I'm attempting to do this using an ajax request after building my Javascript Array of Objects.在构建我的 Javascript 对象数组后,我试图使用ajax请求来做到这一点。 When I try to send only a string value to the controller, my model is constantly null .当我尝试仅向控制器发送一个string值时,我的模型始终为null However when I'm trying to send my Javascript array , I'm getting a 400 (Bad Request) reponse.但是,当我尝试发送我的 Javascript array ,我收到了400 (Bad Request)响应。

My dynamic form is used to create an overall Ticket .我的动态表单用于创建整体Ticket The Ticket is made up of Entries which can be as many as the End-User is needing as they are able to add a new row to the form table.TicketEntries组成, Entries可以与最终用户需要的数量一样多,因为他们能够向表单表中添加新行。 The inputs for the form: AccountNumber , AccountDescription , DebitAmount , CreditAmount , PostingDescription , PostDate .表单的输入: AccountNumberAccountDescriptionDebitAmountCreditAmountPostingDescriptionPostDate

The form table : table

@model Areas.TicketEntry.Models.FormTicketSubmissionModel
...
<div class="postDate">
    <label asp-for="PostDate" class="control-label"></label>
    <input id="PostDateInput" autocomplete="off" />
    <span asp-validation-for="PostDate" class="text-danger"></span>
</div>

<form action="Create" method="post" class="ticketForm">
    <div class="ticketTable">
        <table class="table" id="inputTable">
            <thead>
                <tr>
                    <th>
                        @Html.DisplayNameFor(model => model.AccountNumber)
                    </th>
                    <th>
                        @Html.DisplayNameFor(model => model.AccountDescription)
                    </th>
                    <th>
                        @Html.DisplayNameFor(model => model.DebitAmount)
                    </th>
                    <th>
                        @Html.DisplayNameFor(model => model.CreditAmount)
                    </th>
                    <th>
                        @Html.DisplayNameFor(model => model.PostingDescription)
                    </th>
                    <th>
                        <input type="checkbox" id="checkAllCheckBox" class="allRowCheckBox" value="all" />
                    </th>
                </tr>
            </thead>
            <tbody>
                @for (int i = 0; i < 2; i++)
                {
                    <tr>
                        <td class="tableAccountNumber">
                            <input id="@($"form{i}AccountInfo")" list="AccountList" class="AccountInfo">
                        </td>
                        <td class="tableAccountDescription">
                            <input id="@($"form{i}AccountDescription")" class="AccountDescription" />
                            <span asp-validation-for="AccountDescription" class="text-danger"></span>
                        </td>
                        <td class="tableDebitAmount">
                            <input type="text" data-type="currency" id="@($"form{i}DebitAmount")" class="debitAmount" asp-for="DebitAmount" asp-format="{0:C}" value="0.00" />
                            <span asp-validation-for="DebitAmount" class="text-danger"></span>
                        </td>
                        <td class="tableCreditAmount">
                            <input type="text" data-type="currency" id="@($"form{i}CreditAmount")" class="creditAmount" asp-for="CreditAmount" asp-format="{0:C}" value="0.00" />
                            <span asp-validation-for="CreditAmount" class="text-danger"></span>
                        </td>
                        <td class="tablePostingDescription">
                            <input type="text" id="@($"form{i}PostingDescription")" class="postDescrip" value="" />
                            <span asp-validation-for="PostingDescription" class="text-danger"></span>
                        </td>
                        <td class="tableSelectBox">
                            <input type="checkbox" id="@($"form{i}CheckBox")" class="rowCheckBox" value="selected" />
                        </td>
                    </tr>
                }
            </tbody>
        </table>
        <div class="tableModifyButtons">
            <button id="addRow" type="button">Add Row</button>
            <button id="deleteRow" type="button">Delete Row</button>
        </div>
    </div>

    <div class="formButtons">
        <button id="submitButton" type="button" class="btn btn-primary">Submit Ticket</button>
    </div>
</form>

My Javascript is triggered by my #submitButton being clicked.我的 Javascript 是由我的#submitButton被点击触发的。 This iterates over the Ids of the #inputTable and adds the row values to and returns an array .这将遍历#inputTable的 Id 并将行值添加到并返回一个array I can print the array of objects to console and all the values are as expected.我可以将对象array打印到控制台,并且所有值都符合预期。 I'm currently attempting to stringify the array using JSON to pass it to my controller.我目前正在尝试使用JSON将数组字符串化以将其传递给我的控制器。

My Javascript for submitting the form:我用于提交表单的 Javascript:

// Function for submitting data to controller
function submitTickets() {
    // Iterate through table and generate type array for ticket submission
    // - Add to array of tickets
    // - using JSON and stringify it
    // - Pass to controller with AJAX

    let tickets = getTableTickets('inputTable');
    
    let authToken = $('input[name="__RequestVerificationToken"]');

    if (!validateTickets(tickets)) {
        setWarningMessage('Invalid Ticket Entries detected. Please review your entries and try again.', 'block');
        return;
    }

    let jsonTickets = JSON.stringify({ "tickets": tickets });

    // Ajax it to server
    // How to send JSON to server?
    $.ajax({
        url: "/TicketEntry/Tickets/Create",
        type: "POST",
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        traditional: true,
        data: {
            __RequestVerificationToken: authToken,
            model: jsonTickets
        },
        success: function (data, textStatus, jqXHR) {
            setMessage('SUCCESS: ' + data.Message, 'block');
        },
        error: function (jqXHR, textStatus, errorThrown) {
            setWarningMessage('Error: ' + jqXHR.statusText + ' - ' + textStatus + ' - ' + errorThrown, 'block');
        }
    });

    console.log(jsonTickets);
    console.log('ticket input length: ' + tickets.length);
}

JSON.Stringified array output: JSON.Stringified数组输出:

{"model":[{"AccountNumber":"0000000","AccountDescription":"TEST ACCOUNT","DebitAmount":"25.00","CreditAmount":"0.00","PostingDescription":"TEST","PostDate":"07/15/2021"},{"AccountNumber":"0000001","AccountDescription":"TEST ACCOUNT 2","DebitAmount":"25.00","CreditAmount":"0.00","PostingDescription":"TEST","PostDate":"07/15/2021"},{"AccountNumber":"0000002","AccountDescription":"TEST ACCOUNT 3","DebitAmount":"0.00","CreditAmount":"50.00","PostingDescription":"TEST","PostDate":"07/15/2021"}]}

My current View Model:我当前的视图模型:

public class FormTicketSubmissionModel
    {
        [Display(Name = "Account Number")]
        public string AccountNumber { get; set; }

        [DataType(DataType.Text)]
        [StringLength(29, ErrorMessage = "Description is too long!")]
        [RegularExpression(@"^[a-zA-Z0-9+&.""/'\s-]*$")]
        [Display(Name = "Account Description")]
        public string AccountDescription { get; set; }

        [Display(Name = "Posting Description")]
        [StringLength(29, ErrorMessage = "Posting Description is too long!")]
        [RegularExpression(@"^[a-zA-Z0-9+&.""/'\s-]*$")]
        public string PostingDescription { get; set; }

        [Display(Name = "Post Date")]
        [DataType(DataType.Date)]
        public DateTime PostDate { get; set; }

        [Display(Name = "Debit Amount")]
        [DataType(DataType.Currency)]
        [Column(TypeName = "decimal(18,2)")]
        [Required]
        public decimal DebitAmount { get; set; } = 0.00m;

        [Display(Name = "Credit Amount")]
        [DataType(DataType.Currency)]
        [Column(TypeName = "decimal(18,2)")]
        [Required]
        public decimal CreditAmount { get; set; } = 0.00m;
    }

I've tried passing only string values using my Ajax, but my model was consistantly null .我尝试使用我的 Ajax 只传递字符串值,但我的模型始终为null Here is my current Action Method:这是我目前的操作方法:

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([FromBody]List<FormTicketSubmissionModel> model)
{
    if (ModelState.IsValid)
    {
        // Validate data within models and save them to database 
        // ...
        
        return RedirectToAction(nameof(Index));
    }
    
    return View(model);
}

How can I pass an Array of Objects from Javascript to my Controller?如何将对象数组从 Javascript 传递到我的控制器?

Thank you in advance for any help!预先感谢您的任何帮助!

After revisiting @Llama 's shared link, I re-designed my model(s) and form.重新访问@Llama 的共享链接后,我重新设计了我的模型和表格。 Also, in my View's Form, I had <form action="Create" .../> instead of <form asp-action="Create" .../> .另外,在我的视图表单中,我有<form action="Create" .../>而不是<form asp-action="Create" .../> This caused my form's submission to respond with a 400 .这导致我的表单提交响应400 My solution no longer needs JavaScript / Ajax .我的解决方案不再需要JavaScript / Ajax

New models:新型号:

    public class FormTicketSubmissionModel
    {
        [HiddenInput]
        public int Id { get; set; }

        // Stores the values of the entries 
        public FormTicketEntryModel[] TicketEntries { get; set; }

        [Display(Name = "Post Date")]
        [DataType(DataType.Date)]
        public DateTime PostDate { get; set; }

        [DataType(DataType.Text)]
        [RegularExpression(@"^[a-zA-Z0-9]*$")]
        public string UserName { get; set; }
    }

    public class FormTicketEntryModel
    {
        [HiddenInput]
        public int Id { get; set; }

        [Display(Name = "Account Number")]
        public string AccountNumber { get; set; }

        [DataType(DataType.Text)]
        [StringLength(29, ErrorMessage = "Description is too long!")]
        [RegularExpression(@"^[a-zA-Z0-9+&.""/'\s-]*$")]
        [Display(Name = "Account Description")]
        public string AccountDescription { get; set; }

        [Display(Name = "Posting Description")]
        [StringLength(29, ErrorMessage = "Posting Description is too long!")]
        [RegularExpression(@"^[a-zA-Z0-9+&.""/'\s-]*$")]
        public string PostingDescription { get; set; }

        [Display(Name = "Debit Amount")]
        [DataType(DataType.Currency)]
        [Column(TypeName = "decimal(18,2)")]
        [Required]
        public decimal DebitAmount { get; set; } = 0.00m;

        [Display(Name = "Credit Amount")]
        [DataType(DataType.Currency)]
        [Column(TypeName = "decimal(18,2)")]
        [Required]
        public decimal CreditAmount { get; set; } = 0.00m;
    }

My new View:我的新观点:

<form asp-action="Create" method="post" class="ticketForm">
    <input asp-for="Id" />
    <div class="ticketTable">
        <table class="table" id="inputTable">
            <thead>
                <tr>
                    <th>
                        <label>Account Number</label>
                    </th>
                    <th>
                        <label>Account Description</label>
                    </th>
                    <th>
                        <label>Debit Amount</label>
                    </th>
                    <th>
                        <label>Credit Amount</label>
                    </th>
                    <th>
                        <label>Posting Description</label>
                    </th>
                    <th>
                        <input type="checkbox" id="checkAllCheckBox" class="allRowCheckBox" value="all" />
                    </th>
                </tr>
            </thead>
            <tbody>
                @for (int i = 0; i < 2; i++)
                {
                    <tr>
                        <td class="tableAccountNumber">
                            <input id="@($"form{i}AccountInfo")" asp-for="@Model.TicketEntries[i].AccountNumber" list="AccountList" class="AccountInfo">
                        </td>
                        <td class="tableAccountDescription">
                            <input id="@($"form{i}AccountDescription")" asp-for="@Model.TicketEntries[i].AccountDescription" class="AccountDescription" />
                            <span asp-validation-for="@Model.TicketEntries[i].AccountDescription" class="text-danger"></span>
                        </td>
                        <td class="tableDebitAmount">
                            <input type="text" data-type="currency" id="@($"form{i}DebitAmount")" class="debitAmount" asp-for="@Model.TicketEntries[i].DebitAmount" asp-format="{0:C}" value="0.00" />
                            <span asp-validation-for="@Model.TicketEntries[i].DebitAmount" class="text-danger"></span>
                        </td>
                        <td class="tableCreditAmount">
                            <input type="text" data-type="currency" id="@($"form{i}CreditAmount")" class="creditAmount" asp-for="@Model.TicketEntries[i].CreditAmount" asp-format="{0:C}" value="0.00" />
                            <span asp-validation-for="@Model.TicketEntries[i].CreditAmount" class="text-danger"></span>
                        </td>
                        <td class="tablePostingDescription">
                            <input type="text" id="@($"form{i}PostingDescription")" asp-for="@Model.TicketEntries[i].PostingDescription" class="postDescrip" value="" />
                            <span asp-validation-for="@Model.TicketEntries[i].PostingDescription" class="text-danger"></span>
                        </td>
                        <td class="tableSelectBox">
                            <input type="checkbox" id="@($"form{i}CheckBox")" class="rowCheckBox" value="selected" />
                        </td>
                    </tr>
                }
            </tbody>
        </table>
        <div class="tableModifyButtons">
            <button id="addRow" type="button">Add Row</button>
            <button id="deleteRow" type="button">Delete Row</button>
        </div>
    </div>

    <div class="formButtons">
        <button id="submitButton" type="submit" class="btn btn-primary">Submit Ticket</button>
    </div>
</form>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM