我尝试将列表< item> 类型的多个项传递给我的控制器,但是,当我提交数据时,它显示为null我的控制员。
我希望发生的是我有一份费用列表'在视图中,以及每个费用旁边。或item是我的模型中已提交布尔属性的复选框。当我检查物品时,我想要检查物品清单'要在数据库中更新的已提交和 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
显示为空,因此,我的joined
查询出现错误:
值不能为空。参数名称:内部
答案 0 :(得分:3)
有两种方法可以做到这一点 -
1。
您可能需要这个非常好且可扩展的扩展 - MvcCheckBoxList - 看到此网站已关闭:)请参阅选项2
2。
@for (int i = 0; i < Model.Count; i++)
{
<tr>
<td class="submitCheck">
<input type="checkbox" value="@Model[i].Id" name="Expense[@i].Id">
<input type="hidden" value="0" name="Expense[@i].Id">
</td>
<td>
@Html.DisplayFor(modelItem => item.Company)
</td>
</tr>
}
btw:如果你使用第二种方式:在你的控制器中,过滤费用对象的Id的零值;如果没有被选中,则将零发送到控制器(作为元素的ID),以便在上面的代码中看到“隐藏”字段。
答案 1 :(得分:2)
我无法找到直接从View传递给项目列表的方法,所以我决定使用AJAX。
我将控制器的参数从列表&lt;&gt; 类型更改为 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复选框:
@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,因此每个选中的复选框都会将input元素的id添加到数组中,整数数组将 POST 添加到 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);
}
}
});
})
答案 2 :(得分:0)
1)将FormMethod.Post
添加到@using (Html.BeginForm()) {}
@using (Html.BeginForm("nameAction", "nameController", FormMethod.Post))
{
//Your code
}
2)你应该为这样的输入添加名称:
<input type="text" name="someName"/>