我有一个视图,其模型是ViewModel,用于显示一些数据。对于以这种方式显示的每一行,用户可以从DropDownList中选择一个值,然后单击一个按钮以将其选择保存到数据库中。 每次单击按钮都可以通过这种方式处理多个“选择”。
为此,我使用了Html.BeginForm方法,就像这样(命名已更改):
@using (Html.BeginForm("DatabaseSave", "Save", new { attr = Model.attributedList }, FormMethod.Post))
我在控制器中的方法是:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult DatabaseSave(AttributionViewModel attr)
{
// Data processing.
}
但是当我使用它时,attr为空。我仍然可以通过使用Request.Form和正确的索引来获取数据,但这不是我宁愿使用的解决方案。我有一个准备好执行此操作的模型,并且专门使用了ViewModel,因此不必询问Request.Form。但我只是看不到我所缺少的。有人可以帮我吗?
为了快速找到答案,您将在下面找到所有相关类和视图的伪代码。
包含数据的类:
public class Attribution
{
public Attribution()
{
listToAttribute = new List<SelectListItem>();
}
public string Title { get; set; }
public int ID { get; set; }
public string Description { get; set; }
public int? Number { get; set; }
public IEnumerable<SelectListItem> listToAttribute { get; set; }
public int AttributedNumber { get; set; } // Mostly used internally to properly send dropdownlist data.
// Other methods that are not relevant.
}
视图中使用的ViewModel:
public class AttributionViewModel : Attribution
{
public AttributionViewModel()
{
}
public IPagedList<Attribution> attributedList { get; set; }
}
视图的相关部分:
@model Project.ViewModels.AttributionViewModel
@using PagedList.Mvc
@using PagedList
// Some code later...
@using (Html.BeginForm("DatabaseSave ", "Save", new { attr = Model.attributedList }, FormMethod.Post))
{
@Html.ValidationSummary(false, "", new { @class = "text-danger" })
@Html.AntiForgeryToken()
<table class="contentTable contentTable-evo fixedTableHeader">
<thead>
// Headers are not relevant.
</thead>
<tbody id="processingTable">
@{
int i = 0;
}
@foreach (var item in Model.attributedList)
{
<tr>
<text>@Html.EditorFor(modelItem => Model.attributedList[i].ID, new { htmlAttributes = new { @class = "form-control", @hidden = "hidden", @style = "width:0px display:none", @type = "hidden" } })</text>
<td class="noWrap width1percent tri">@item.Title</td>
<td class="noWrap width1percent tri">@item.ID</td>
<td class="noWrap width1percent tri">@item.Description</td>
<td class="noWrap width1percent tri">@item.Number</td>
<td class="noWrap width1percent tri">
<text>@Html.DropDownListFor(modelItem => Model.attributedList[i].AttributedNumber, Model.attributedList[i].listToAttribute , "" , new { htmlAttributes = new { @class = "form-control", @style = "width:90px" } })</text>
</td>
</tr>
i++;
}
</tbody>
</table>
<br />
<center>
<input value="Processing" class="add" type="submit" onclick="javascript:return ShowConfirm();" >
</center>
Page @(Model.attributedList.PageCount < Model.attributedList.PageNumber ? 0 : Model.attributedList.PageNumber) out of @Model.attributedList.PageCount | @Model.attributedList.TotalItemCount <br />
<text>@Resources.Views.PaginationResource.GoToPage </text>@Html.DropDownList("PageChanger", new SelectList(Enumerable.Range(1, Model.attributedArticles.PageCount), "", ""), new { onchange = "PageChangedFromDropDown()" })
@Html.PagedListPager(Model.attributedList, page => Url.Action("Attribute", new { page, searchString = Session["Search"], currentFilter = ViewBag.CurrentFilter, sortColumn = ViewBag.sortAttr }), new PagedListRenderOptions { LiElementClasses = new[] { "needsLoading" }, DisplayEllipsesWhenNotShowingAllPageNumbers = false })
答案 0 :(得分:0)
多亏了斯蒂芬·穆克(Stephen Muecke),我才发现自己在做错什么。
问题出在ViewModel中:
public IPagedList<Attribution> attributedList { get; set; }
我需要使用它,因为ViewModel通常无法使用PagedList。
但是,这并不意味着它可以用于包含和解析数据。为此,我需要一个单独的列表,并添加以下内容:
public IPagedList<Attribution> attributedList { get; set; }
public List<Attribution> parsableListOfAttributed { get; set; } // Otherwise passing to the controller WILL NOT WORK.
对于任何与PagedList有关的操作(例如,在上面的示例中,我需要它来计算页面数),我可以引用attributedList。但这在将其传递给Controller时仍然不起作用,后者仍将其视为PagedList,因此不能用于该目的。
更正的视图:
@using (Html.BeginForm("DatabaseSave", "Save", FormMethod.Post))
{
@Html.ValidationSummary(false, "", new { @class = "text-danger" })
@Html.AntiForgeryToken()
<table class="contentTable contentTable-evo fixedTableHeader">
<thead>
// Headers are still not relevant.
</thead>
<tbody id="processingTable">
@{
int i = 0;
}
@foreach (var item in Model.attributedArticles)
{
<tr>
<text>@Html.EditorFor(modelItem => Model.parsableListOfAttributed[i].ID, new { htmlAttributes = new { @class = "form-control", @hidden = "hidden", @style = "width:0px display:none", @type = "hidden" } })</text>
<td class="noWrap width1percent tri">@item.GTIN</td>
<td class="noWrap width1percent tri">@item.SMP</td>
<td class="noWrap width1percent tri">@item.DescriptionFr</td>
<td class="noWrap width1percent tri">@item.AuthorisationNumber</td>
<td class="noWrap width1percent tri">
<text>@Html.DropDownListFor(modelItem => Model.parsableListOfAttributed[i].AttributedNumber, Model.parsableListOfAttributed[i].listToAttribute, "" , new { htmlAttributes = new { @class = "form-control", @style = "width:90px"} })</text>
</td>
</tr>
i++;
}
</tbody>
</table>
<br />
<center>
<input value="Processing"" class="add" type="submit" onclick="javascript:return ShowConfirm();" >
</center>
}
使用此方法可以正确传递模型。