Phi*_*ray 8 c# asp.net-mvc asp.net-mvc-4
我有一个MVC控制器,其中post方法上的模型总是返回null.我不确定这是因为我在表单中使用了局部视图.
知道为什么模型没有返回控制器吗?
模型
加载模型
public List<Group> GetStaticMeasures(int businessUnitID)
{
List<Group> groups = ctx.Groups
.Include("Datapoints")
.Where(w => w.BusinessUnitID.Equals(businessUnitID))
.OrderBy(o => o.SortOrder).ToList();
groups.ForEach(g => g.Datapoints = g.Datapoints.OrderBy(d => d.SortOrder).ToList());
return groups;
}
Run Code Online (Sandbox Code Playgroud)
调节器
public ActionResult Data()
{
ViewBag.Notification = string.Empty;
if (User.IsInRole(@"xxx\yyyyyy"))
{
List<Group> dataGroups = ctx.GetStaticMeasures(10);
return View(dataGroups);
}
else
{
throw new HttpException(403, "You do not have access to the data.");
}
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Data(List<Group> model)
{
ViewBag.Notification = string.Empty;
if (User.IsInRole(@"xxx\yyyyyy"))
{
if (ModelState.IsValid)
{
ctx.SaveChanges(model);
ViewBag.Notification = "Save Successful";
}
}
else
{
throw new HttpException(403, "You do not have access to save the data.");
}
return View(model);
}
Run Code Online (Sandbox Code Playgroud)
主要观点
@model List<Jmp.StaticMeasures.Models.Group>
<div class="row">
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
@Html.ValidationSummary(true)
<div class="large-12">
<div class="large-8 large-centered columns panel">
@foreach (var g in @Model)
{
<h2>@g.Name</h2>
foreach (var d in g.Datapoints)
{
@Html.Partial("Measures", d)
}
<hr />
}
<input type="submit" class="button" value="Save Changes"/>
</div>
</div>
}
</div>
Run Code Online (Sandbox Code Playgroud)
局部视图
@model Jmp.StaticMeasures.Models.Datapoint
@Html.HiddenFor(d => d.ID)
@Html.HiddenFor(d => d.Name)
@Html.HiddenFor(d => d.SortOrder)
@Html.DisplayTextFor(d => d.Name)
@Html.EditorFor(d => d.StaticValue)
@Html.ValidationMessageFor(d => d.StaticValue)
Run Code Online (Sandbox Code Playgroud)
呈现显示连续ID的Html
Joh*_*n H 14
正如你正确指出的那样,这是因为你使用的是偏爱的.这种情况正在发生,因为Html.Partial
它不知道它在一个集合上运行,所以它不会为你的表单元素生成你想要绑定到集合的名称.
但是,您的案例中的修复似乎相当简单.而不是使用Html.Partial
,你可以简单地改变你的部分为EditorTemplate
,并调用Html.EditorFor
,而不是该模板. Html.EditorFor
非常聪明,可以知道它何时处理集合,因此它将为集合中的每个项目调用模板,在表单上生成正确的名称.
所以要做你需要的,请按照下列步骤操作:
EditorTemplates
在视图的当前文件夹中创建一个文件夹(例如,如果您的视图是Home\Index.cshtml
,则创建该文件夹Home\EditorTemplates
).名称很重要,因为它遵循查找模板的惯例.Shared\EditorTemplates
文件夹中.Datapoint.cshtml
(这很重要,因为模板名称基于类型名称的约定).现在相关的视图代码变为:
// Note: I removed @ from Model here.
@foreach (var g in Model)
{
<h2>@g.Name</h2>
@Html.EditorFor(m => g.DataPoints)
<hr />
}
Run Code Online (Sandbox Code Playgroud)
这可以确保您的视图分离,就像您最初的预期一样.
好吧,正如我在下面提到的,现在的问题是模型绑定器无法将a DataPoint
与正确关联Group
.简单的解决方法是将视图代码更改为:
for (int i = 0; i < Model.Count; i++)
{
<h2>@Model[i].Name</h2>
@Html.EditorFor(m => m[i].DataPoints)
<hr />
}
Run Code Online (Sandbox Code Playgroud)
这将正确生成名称,并应解决模型绑定问题.
OP的附录
按照John的回答,我还将Group表中缺少的属性包含在HiddenFor中,然后将模型重新发布在帖子上.
@for (int i = 0; i < Model.Count(); i++)
{
@Html.HiddenFor(t => Model[i].ID)
@Html.HiddenFor(t => Model[i].BusinessUnitID)
@Html.HiddenFor(t => Model[i].SortOrder)
@Html.HiddenFor(t => Model[i].Name)
<h2>@Model[i].Name</h2>
@Html.EditorFor(m => Model[i].Datapoints)
<hr />
}
Run Code Online (Sandbox Code Playgroud)
我EditorTemplate
对每个使用a的建议DataPoint
也适用于每个Group
.而不是需要for
循环,再次在视图中喷洒逻辑,您可以完全通过设置EditorTemplate
for 来避免这种情况Group
.在放置模板的位置方面,上述步骤同样适用.
在这种情况下,模板将是Group.cshtml
,并将看起来如下:
@model Jmp.StaticMeasures.Models.Group
<h2>@Model.Name</h2>
@Html.EditorFor(m => m.DataPoints)
<hr />
Run Code Online (Sandbox Code Playgroud)
如上所述,这将为集合中的每个项调用模板,这也将为每个项生成正确的索引Group
.您的原始视图现在可以简化为:
@model List<Jmp.StaticMeasures.Models.Group>
@using (Html.BeginForm())
{
// Other markup
@Html.EditorForModel();
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
14036 次 |
最近记录: |