我的模特
public class ActivityModel
{
public int Id { get; set; }
public String Nick { get; set; }
public String TripName { get; set; }
[DisplayFormat(DataFormatString = "{0:hh\\:mm}", ApplyFormatInEditMode = true)]
public TimeSpan? FromTime { get; set; }
[DisplayFormat(DataFormatString = "{0:hh\\:mm}", ApplyFormatInEditMode = true)]
public TimeSpan? ToTime { get; set; }
public String FromPlace { get; set; }
public String ToPlace { get; set; }
public String activityType { get; set; }
[DisplayFormat(DataFormatString = "{0:dd.MM.yyyy}", ApplyFormatInEditMode = true)]
public DateTime? Timestamp { get; set; }
public String Weather { get; set; }
public int Difficulty { get; set; }
public bool Reviewed { get; set; }
}
我的视图行如下所示
@model IList<ActivityModel>
@for (int i = 0; i < Model.Count; i++)
{
if (!(bool)Model[i].Reviewed)
{
<tr>
@using (Html.BeginForm("Accept", "Overview", FormMethod.Post, new { activityModel = Model }))
{
@Html.AntiForgeryToken()
<td>
@Html.DisplayFor(m => Model[i].Timestamp)
@Html.HiddenFor(m => Model[i].Timestamp)
</td>
<td>
@Html.DisplayFor(m => Model[i].Nick)
@Html.HiddenFor(m => Model[i].Nick)
</td>
<td>
@Html.DisplayFor(m => Model[i].TripName)
@Html.HiddenFor(m => Model[i].TripName)
</td>
<td>
@Html.DisplayFor(m => Model[i].FromTime)
@Html.HiddenFor(m => Model[i].FromTime)
</td>
<td>
@Html.DisplayFor(m => Model[i].FromPlace)
@Html.HiddenFor(m => Model[i].FromPlace)
</td>
<td>
@Html.DisplayFor(m => Model[i].ToTime)
@Html.HiddenFor(m => Model[i].ToTime)
</td>
<td>
@Html.DisplayFor(m => Model[i].ToPlace)
@Html.HiddenFor(m => Model[i].ToPlace)
</td>
<td>
@Html.TextBoxFor(m => Model[i].Difficulty, new { id = "Difficulty" })
<--!@Html.HiddenFor(m => Model[i].Difficulty)--!>
<div style="visibility:hidden">
@Html.HiddenFor(m => Model[i].Id)
@Html.HiddenFor(m => Model[i].Reviewed)
@Html.HiddenFor(m => Model[i].activityType)
@Html.HiddenFor(m => Model[i].Weather)
</div>
</td>
<td>
<input type="submit" name="btn_accept" value="Accept" />
</td>
}
</tr>
}
}
我的控制器就是这个
public ActionResult Index()
{
List<ActivityModel> activities_web = new List<ActivityModel>();
//someLogicForFilling
return View(activities_web);
}
[HttpPost]
[ValidateAntiForgeryToken()]
public ActionResult Accept(ActivityModel activityModel)
{
return RedirectToAction("Index");
}
问题是在ActionResult中是AcceptModel总是NULL空0 ... 我现在真的花了一整天时间,而且我不知道问题出在哪里,我尝试了近20个解决方案,对我来说没什么用。
渲染页面并显示所有值是正常的,但是当我尝试发布它们时,就像没有发布任何内容一样。
答案 0 :(得分:0)
当发布的数据与您用作HttpPost操作方法参数的类的属性结构匹配时,模型绑定将起作用。
您当前的视图代码正在生成这样的HTML代码
<input name="[0].Id" type="hidden" value="101">
<input name="[1].Id" type="hidden" value="202">
假设您在集合中有2个项目,则传递给视图。
您可以看到name
属性值为[0].Id
和[1].Id
。但是,您的Accept
操作方法的参数是单个ActivityModel
对象,属性名称类似于Id
,FromPlace
等。对于模型绑定工作,名称您的输入和属性名称应匹配。
您可以重写视图代码,为隐藏的输入生成正确的name
属性值。您可以简单地使用纯HTML代码创建隐藏输入并设置模型项中的值或使用Html.HiddenFor
辅助方法。
@foreach (var item in Model.Where(a => a.Reviewed == false))
{
<input type="hidden" name="FromPlace" value="@item.FromPlace" />
@Html.Hidden("ToPlace", item.ToPlace)
@Html.Hidden(nameof(ActivityModel.Id), item.Id)
}
以下是完整代码(排除了一些节省空间的属性)。
@model IList<ActivityModel>
<table class="table table-striped">
@foreach (var item in Model.Where(a => a.Reviewed == false))
{
using (Html.BeginForm("Accept", "Process", FormMethod.Post))
{
@Html.AntiForgeryToken()
<tr>
<td>
@Html.DisplayFor(m => item.FromPlace)
@Html.Hidden("FromPlace", item.FromPlace)
</td>
<td>
@Html.DisplayFor(m => item.ToPlace)
@Html.Hidden("ToPlace", item.ToPlace)
</td>
<td>
@Html.Hidden(nameof(ActivityModel.Id),item.Id)
<input type="submit" name="btn_accept" value="Accept" />
</td>
</tr>
}
}
</table>
但理想情况下,如果您尝试更新单个实体/记录的状态,则只需要该记录的Id
(主键)。这意味着,您确实不需要填充所有属性。在这种情况下,您需要Id
属性值的隐藏输入元素。如果需要,您始终可以使用此Id
查询数据库以获取完整实体。 (绝不相信来自客户的数据)