找到一个解决方案,但是一个非常难看的解决方案,从底部看,有人可以改进解决方案吗?
所以我有一个像这样的虚拟模型
public class TestModel
{
public int TestModelID { get; set; }
public string Name { get; set; }
}
另一个像这样的人
public class Collector
{
public int CollectorID { get; set; }
public string CollectorString { get; set; }
public ICollection<TestModel> MyList { get; set; }
}
我想(以简单的CRUD风格)创建一个新对象 Collector 并填充(稍后动态添加新字段,现在只有一个)ICollection。 这是我的观点
@model TestApplication.Models.Collector
@{
ViewBag.Title = "Create";
}
<h2>Create</h2>
@using (Html.BeginForm())
{
@Html.AntiForgeryToken()
<div class="form-horizontal">
<h4>Collector</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.CollectorString, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.CollectorString, new { htmlAttributes = new { @class = "form-control" } })
@Html.ValidationMessageFor(model => model.CollectorString, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => Model.MyList.ToList()[0].Name)
<div class="col-md-10">
@Html.EditorFor(model => model.MyList.ToList()[0].Name, new { htmlAttributes = new { @class = "form-control" } })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
}
<div>
@Html.ActionLink("Back to List", "Index")
</div>
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
}
和控制器
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Collector collector)
{
if (ModelState.IsValid)
{
db.Collectors.Add(collector);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(collector);
}
这是生成的HTML代码(我希望只是相关部分)
<div class="form-group">
<label for="">Name</label>
<div class="col-md-10">
<input class="form-control text-box single-line" name="[0].Name" type="text" value="" />
</div>
</div>
但是,创建时控制器中的MyList
始终为空,为什么? (是的,我知道Haackeds博客条目,仍然无法弄清楚为什么它不起作用)
所以问题是,这一行
@Html.EditorFor(model => model.MyList.ToList()[0].Name, new { htmlAttributes = new { @class = "form-control" } })
虽然非常推荐在MVC中使用,但在此处生成
<input class="form-control text-box single-line" name="[0].Name" type="text" value="" />
显然不起作用。如何让剃须刀将[0].Name
更改为MyList[0].Name
?
**更新:** 所以我找到了一个解决方案,如果这里的硬代码
<input class="form-control text-box single-line" name="MyList[0].Name" type="text" value="" />
控制器理解它,我没有得到null
。如何用剃刀解决它?
答案 0 :(得分:2)
ICollection<T>
没有索引器。 IList<T>
确实
public class Collector {
public Collector() {
MyList = new List<TestModel>();
}
public int CollectorID { get; set; }
public string CollectorString { get; set; }
public IList<TestModel> MyList { get; set; }
}
这将允许
@Html.EditorFor(model => model.MyList[0].Name, new { htmlAttributes = new { @class = "form-control" } })
在视图中生成所需的标记
<input class="form-control text-box single-line" name="MyList[0].Name" type="text" value="" />
也可以在多个项目的循环中使用
<div class="form-group">
@for(int i = 0; i < Model.MyList.Count; i++) {
@Html.LabelFor(model => Model.MyList[i].Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.MyList.ToList()[i].Name, new { htmlAttributes = new { @class = "form-control" } })
</div>
}
</div>
从控制器初始调用返回模型时,只需确保对模型的集合索引的调用有一个项目。
[HttpGet]
public ActionResult Create() {
var model = new Collector();
model.MyList.Add(new TestModel());
return View(model);
}
答案 1 :(得分:0)
尝试更改收集器类以包含初始化。
public class Collector
{
public Collector()
{
set MyList = new Collection<TestModel>();
}
public int CollectorID { get; set; }
public string CollectorString { get; set; }
public ICollection<TestModel> MyList { get; set; }
}
答案 2 :(得分:0)
你可以使用剃刀语法
来做到这一点<div class="form-group">
@for(int i = 0; i < Model.MyList.Count; i++) {
@Html.LabelFor(model => Model.MyList[i].Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.MyList[i].Name, new { htmlAttributes = new { @class = "form-control" } })
</div>
}
</div>