我是.NET的新手,如果我有任何愚蠢的错误,请耐心等待。
我正在使用ASP.NET MVC 3和.NET 4.0
我希望为具有子模型的模型提供“创建”视图。此视图应包含子模型的 部分 “创建”视图,我将使用以下简单示例进行说明:
人模型
class Person
{
public string Name { get; set; }
public Address { get; set; }
}
地址模型
class Address
{
public string City { get; set; }
public string Zip { get; set; }
//A List for creating a <select/> item in the view
//containing cities fetched from the database.
//The initialization is done in the controller action returning
//the related partial view.
public IEnumerable<SelectListItem> CityDropDown { get; set; } )
}
控制器操作
class MyController : Controller
{
public ViewResult Create()
{
var person = new Person();
var address = new Address();
// initialization of address.CityDropDown omitted
person.Address = address;
return View(MyViews.CreatePersonView, person);
}
[HttpPost]
public ViewResult Create(Person person)
{
//persistance logic
}
}
我想要的视图层次结构:
我为实现这一目标而尝试的解决方案如下:
@Html.Partial(..)
或@{Html.RenderPartial(..)}
人视图
@model Person
@using(Html.BeginForm()){
@Html.EditorFor(m=>m.Name)
@Html.Partial(MyViews.AddressPartialView, @Model.Address)
}
地址部分视图
@model Address
@Html.EditorFor(m=>m.Zip)
@Html.DropDownListFor(m=>m.City, @Model.CityDropDown)
提交表单时,person.Address
为空。在Google上进行了一些搜索后,我发现为了提交地址字段,生成的HTML标记必须如下(注意Address_
前缀):
<form...>
<input type=text id="Name" />
<input type=text id="Address_Zip" />
<select id="Address_City">
<!-- options... -->
</select>
</form>
毋庸置疑,我的情况下生成的HTML标记不尽相同,而是以下内容(缺少Address_
前缀):
<form...>
<input type=text id="Name" />
<input type=text id="Zip" />
<select id="City">
<!-- options... -->
</select>
</form>
我将地址部分视图移至 View / Shared / EditorTemplates 文件夹,确保其名称与Address
模型中的Person
属性,即 Address.cshtml 。
人视图
@model Person
@using(Html.BeginForm()){
@Html.EditorFor(m=>m.Name)
@Html.EditorFor(@Model.Address) //will automatically find the Address
//partial view in the EditorTemplates folder
}
使用这种方法,生成的标记实际上具有正确的前缀(即Address_
),但是我得到 对象引用未设置为实例异常 对于Address.CityDropDown
属性,它告诉我控制器操作中的预初始化的Address对象由于某种原因没有传递给局部视图。
这种方法没有任何问题,但我不想使用它,因为我不想拥有冗余代码,如果我想在另一个模型中有地址的创建视图。
为了拥有一个可以在我的应用程序中使用的可重用部分创建视图,我该怎么做?
答案 0 :(得分:3)
您使用EditorTemplates有正确的方法,但请记住,您需要填充CityDropDown
。所以,视图应该是这样的:
Person model = new Person()
{
Address = new Address
{
CityDropDown = new SelectListItem[]{
new SelectListItem { Selected = true, Text = "Select one..." },
new SelectListItem { Text = "Anywhere", Value = "Anywhere" },
new SelectListItem { Text = "Somewhere", Value = "Somewhere" },
new SelectListItem { Text = "Nowhere", Value = "Nowhere" }
}
}
};
然后,这个视图只包括:
@Html.EditorForModel()
然后你的EditorTemplates
会从那里接起来:
〜/ Views / shared / EditorTemplates / Address.cshtml (注意:这是基于类型而不是属性名称)
@model MvcApplication.Models.Address
@Html.DropDownListFor(x => x.City, Model.CityDropDown)
@Html.EditorFor(x => x.Zip)
<强>〜/查看/共享/ EditorTemplates / Person.cshtml 强>
@model MvcApplication.Models.Person
@using (Html.BeginForm())
{
@Html.EditorFor(x => x.Name)
@Html.EditorFor(x => x.Address)
<input type="submit" value="Save" />
}
然后三个视图呈现如下:
<form action="/" method="post">
<input class="text-box single-line" id="Name" name="Name" type="text" value="" />
<select id="Address_City" name="Address.City">
<option selected="selected">Select one...</option>
<option value="Anywhere">Anywhere</option>
<option value="Somewhere">Somewhere</option>
<option value="Nowhere">Nowhere</option>
</select>
<input class="text-box single-line" id="Address_Zip" name="Address.Zip" type="text" value="" />
<input type="submit" value="Save" />
示例项目可在此处找到:https://github.com/bchristie/StackOverflow-Examples/tree/master/questions-19247958