我试图将 List *类型的多个 项目 传递给控制器,但是,当我提交数据时,它在控制器中显示为null。 *
我想发生的是,我在视图中有一个“费用”列表,并且每个“费用”或项目旁边都有一个来自模型中“已 提交 布尔值”属性的复选框。当我检查项目时,我希望在数据库中更新检查项目的属性 Submitted 和 DateSubmitted 列表。
视图中的@ Html.DisplayFor(modelItem = > item.Submitted)产生复选框。
我究竟做错了什么?
这是我的观点:
@model IEnumerable<Expenses.Models.Expense> @{ ViewBag.Title = "Submit Expenses"; Layout = "~/Views/Shared/_Layout.cshtml"; DateTime today = DateTime.Today; string formattedDate = today.ToString("MM/dd/yyyy"); } <link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css"> <script src="//code.jquery.com/jquery-1.10.2.js"></script> <script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script> <h2>Submit Expenses</h2> @using (Html.BeginForm()) { @Html.AntiForgeryToken() <div class="form-inline"> <div class="form-group"> <h4>Start Date:</h4> <div class="col-md-10"> @Html.TextBox("expenseDate", formattedDate, htmlAttributes: new { @class = "form-control" }) </div> </div> <div class="form-group"> <h4>End Date:</h4> <div class="col-md-10"> @Html.TextBox("expenseDate2", formattedDate, htmlAttributes: new { @class = "form-control" }) </div> </div> <div class="form-group"> @if (User.IsInRole("admin")) { <h4>Username:</h4> <div class="editor-field"> @Html.DropDownList("UserId", String.Empty) </div> } </div> <br /> <br /> <div class="form-group"> <div class="col-md-2"> <input type="submit" value="Retrieve Expenses" class="btn btn-default" /> </div> </div> </div> <br /> <br /> <p> @Html.ActionLink("Create New", "Create") </p> <table style="margin-bottom: 20px;"> <tr> <th> @Html.DisplayNameFor(model => model.Company) </th> <th> @Html.DisplayNameFor(model => model.Category) </th> <th> @Html.DisplayNameFor(model => model.Province) </th> <th> @Html.DisplayNameFor(model => model.ReceiptName) </th> <th> @Html.DisplayNameFor(model => model.Comment) </th> <th> @Html.DisplayNameFor(model => model.GrossAmount) </th> <th> @Html.DisplayNameFor(model => model.TaxAmount) </th> <th> @Html.DisplayNameFor(model => model.NetAmount) </th> <th> @Html.DisplayNameFor(model => model.Mileage) </th> <th> @Html.DisplayNameFor(model => model.TravelStatus) </th> <th> @Html.DisplayNameFor(model => model.LunchLearnStatus) </th> <th> @Html.DisplayNameFor(model => model.WithClientStatus) </th> <th> @Html.DisplayNameFor(model => model.DateEntered) </th> <th> @Html.DisplayNameFor(model => model.DateSubmitted) </th> <th> @Html.DisplayNameFor(model => model.ExpenseDate) </th> <th> @Html.DisplayNameFor(model => model.ImageName) </th> @if (User.IsInRole("admin")) { <th> @Html.DisplayNameFor(model => model.UserProfile.UserName) </th> } <th></th> </tr> <tr> <td> <b>Select All:</b> <br /> <input type="checkbox" name="expense" value="Expense" id="selectAllCheckboxes" class="expenseCheck"> </td> </tr> @foreach (var item in Model) { <tr> <td class="submitCheck"> @Html.EditorFor(modelItem => item.Submitted) </td> <td> @Html.DisplayFor(modelItem => item.Company) </td> <td> @Html.DisplayFor(modelItem => item.Category) </td> <td> @Html.DisplayFor(modelItem => item.Province) </td> <td> @Html.DisplayFor(modelItem => item.ReceiptName) </td> <td> @Html.DisplayFor(modelItem => item.Comment) </td> <td> @Html.DisplayFor(modelItem => item.GrossAmount) </td> <td> @Html.DisplayFor(modelItem => item.TaxAmount) </td> <td> @Html.DisplayFor(modelItem => item.NetAmount) </td> <td> @Html.DisplayFor(modelItem => item.Mileage) </td> <td> @Html.DisplayFor(modelItem => item.TravelStatus) </td> <td> @Html.DisplayFor(modelItem => item.LunchLearnStatus) </td> <td> @Html.DisplayFor(modelItem => item.WithClientStatus) </td> <td> @Html.DisplayFor(modelItem => item.DateEntered) </td> <td> @Html.DisplayFor(modelItem => item.DateSubmitted) </td> <td> @Html.DisplayFor(modelItem => item.ExpenseDate) </td> <td> @if (item.ImageName != null) { <a href="~/Images/@Html.DisplayFor(modelItem => item.UserProfile.FullName)/@Html.DisplayFor(modelItem => item.ImageName)" class="imageClick" target="_blank"><img src="~/Images/@Html.DisplayFor(modelItem => item.UserProfile.FullName)/@Html.DisplayFor(modelItem => item.ImageName)" alt="Image" style="width:80%" /></a> } </td> @if (User.IsInRole("admin")) { <td> @Html.DisplayFor(modelItem => item.UserProfile.UserName) </td> } <td> @Html.ActionLink("Edit", "Edit", new { id = item.ExpenseId }) | @Html.ActionLink("Details", "Details", new { id = item.ExpenseId }) | @if (User.IsInRole("admin")) { @Html.ActionLink("Delete", "Delete", new { id = item.ExpenseId }) } </td> </tr> } </table> @Html.ActionLink("Submit Expenses", "SubmitExpenses", "Expenses", null, new { @class = "submitLink", @style = "background-color: #d3dce0; border: 1px solid #787878; cursor: pointer; font-size: 1.5em; font-weight: 600; margin-right: 8px; padding: 7px; width: auto; text-decoration: none; font-weight:bold;"}) <div class="ExportSection" style="margin-top:30px;"> @*<a href="javascript:void(0)">Export To CSV</a>*@ @Html.ActionLink("Export To CSV", "ExportExpensesListToCSV") </div> } @section scripts { <script type="text/javascript"> $("#selectAllCheckboxes").click(function () { $('.submitCheck input:checkbox').not(this).prop('checked', this.checked); }); $(function () { $("#expenseDate").datepicker(); }); $(function () { $("#expenseDate2").datepicker(); }); </script> }
这是我的Controller方法:
public ActionResult SubmitExpenses(List<Expense> expenses, DateTime? expenseDate = null, DateTime? expenseDate2 = null, int? userId = 0) { expenseDate = (DateTime)Session["FirstDate"]; expenseDate2 = (DateTime)Session["SecondDate"]; if (expenseDate == null || expenseDate2 == null) { expenseDate = DateTime.Now.AddMonths(-1); expenseDate2 = DateTime.Today; } string currentUserId = User.Identity.Name; var query = from e in db.Expenses join user in db.UserProfiles on e.UserId equals user.UserId where e.ExpenseDate >= expenseDate && e.ExpenseDate <= expenseDate2 && e.DateSubmitted == null orderby e.ExpenseDate descending select new { e, user }; if (User.IsInRole("admin") && userId != 0) { query = query.Where(x => x.user.UserId == userId); } else if (!User.IsInRole("admin")) { query = query.Where(x => x.user.UserName == currentUserId); } var expensesFromView = expenses; var joined = from dbExpense in query.Select(x => x.e).AsEnumerable() join localExpense in expenses on dbExpense.ExpenseId equals localExpense.ExpenseId where localExpense.Submitted select dbExpense; foreach (Expense exp in joined) { exp.DateSubmitted = DateTime.Today; } try { db.SaveChanges(); return RedirectToAction("Index"); } catch (Exception e) { Console.WriteLine(e); return RedirectToAction("Submit"); } }
这是我的模型:
[Key] [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)] public int ExpenseId { get; set; } [Required] public string Company { get; set; } [Required] public string Category { get; set; } [Required] [Display(Name = "Receipt Name")] public string ReceiptName { get; set; } public string Comment { get; set; } [Required] public string Province { get; set; } [Required] [Display(Name = "Gross Amount")] public decimal GrossAmount { get; set; } [Required] [Display(Name = "GST/HST Amount")] public decimal TaxAmount { get; set; } [Required] [Display(Name = "Net Amount")] public decimal NetAmount { get; set; } [Display(Name = "Mileage (in Kilometers)")] public int Mileage { get; set; } [Display(Name = "Travelling?")] public bool TravelStatus { get; set; } [Display(Name = "Lunch & Learn?")] public bool LunchLearnStatus { get; set; } [Display(Name = "With Clients?")] public bool WithClientStatus { get; set; } [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")] [Required] [Display(Name = "Date Entered")] public DateTime? DateEntered{ get; set; } [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")] [Display(Name = "Date Submitted")] public DateTime? DateSubmitted { get; set; } [DisplayFormat(DataFormatString = "{0:MM/dd/yyyy}")] [Required] [Display(Name = "Expense Date")] public DateTime? ExpenseDate { get; set; } [Display(Name = "Image")] public string ImageName { get; set; } [Display(Name = "Submitted?")] public bool Submitted { get; set; } [Required] [Display(Name = "Name")] public int UserId { get; set; } [ForeignKey("UserId")] public virtual UserProfile UserProfile { get; set; }
我的变量expensesFromView显示为null,结果,我的joined查询出现错误,提示:
expensesFromView
joined
值不能为空。 参数名称:内部
我真的找不到直接从View向Controller传递项目列表的方法,因此我决定使用AJAX。
我将控制器的参数从 List <>更改为 int [], 以获取项目ID的数组:
public ActionResult SubmitExpenses(int[] expenseIDs, DateTime? expenseDate = null, DateTime? expenseDate2 = null, int? userId = 0) { expenseDate = (DateTime)Session["FirstDate"]; expenseDate2 = (DateTime)Session["SecondDate"]; if (expenseDate == null || expenseDate2 == null) { expenseDate = DateTime.Now.AddMonths(-1); expenseDate2 = DateTime.Today; } string currentUserId = User.Identity.Name; var query = from e in db.Expenses join user in db.UserProfiles on e.UserId equals user.UserId where e.ExpenseDate >= expenseDate && e.ExpenseDate <= expenseDate2 && e.DateSubmitted == null orderby e.ExpenseDate descending select new { e, user }; if (User.IsInRole("admin") && userId != 0) { query = query.Where(x => x.user.UserId == userId); } else if (!User.IsInRole("admin")) { query = query.Where(x => x.user.UserName == currentUserId); } //var localExpenseIDs = expenseIDs; var joined = from dbExpense in query.Select(x => x.e).AsEnumerable() join localExpense in expenseIDs on dbExpense.ExpenseId equals localExpense where localExpense == dbExpense.ExpenseId select dbExpense; foreach (Expense exp in joined) { exp.DateSubmitted = DateTime.Today; exp.IsSubmitted = true; } try { db.SaveChanges(); return RedirectToAction("Index"); } catch (Exception e) { Console.WriteLine(e); return RedirectToAction("Submit"); } }
在我看来,我将每个项目的ID分配给它自己的HTML复选框的ID:
@foreach (var item in Model) { <tr> <td class="checkbox-td"> @Html.CheckBox("isSubmitted", new { @id = @Html.DisplayFor(modelItem => item.ExpenseId), @class = "submitBox" }) </td> </tr> } <div> @Html.ActionLink("Submit Expenses", "", "", null, new { @id = "submitExpensesLink" }) </div>
我写了一些jQuery,以便选中的每个复选框都将输入元素的ID添加到数组中,并且整数数组将被过 帐 到 SubmitExpenses 操作中:
var checkedArray = []; $(':checkbox[name=isSubmitted]').on('change', function () { checkedArray = $(':checkbox[name=isSubmitted]:checked').map(function () { return this.id; }) .get(); //alert(checkedArray); }); $('#submitExpensesLink').click(function () { $.ajax({ type: "POST", traditional: true, url: "@Url.Action("SubmitExpenses", "Expenses")", data: { expenseIDs: checkedArray }, success: function () { alert("Success!"); }, error: function (XMLHttpRequest, textStatus, errorThrown) { if (debug) { alert(XMLHttpRequest.responseText); alert(textStatus); alert(errorThrown); } } }); })