2013-10-08 74 views
6

我是.NET新手,如果我有任何愚蠢的错误,请耐心等待。Master-Detail使用Razor,ASP.NET MVC 3和.NET 4.0创建视图

我使用ASP.NET MVC 3与.NET 4.0

我想有一个“创建”视图有子模型的模型。这种观点应该包括子模型的部分“创建”的看法,我会用下面这个简单的例子用于说明目的:

  • 模型

    class Person 
    { 
        public string Name { get; set; } 
        public Address { get; set; } 
    } 
    
  • The Address model

    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 
         } 
        } 
    
  • 视图层次结构的我想有:

Person Create View Hierarchy

,我为了尝试这些解决方案来实现这个是以下:

第一种方法:使用@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为空。一点在谷歌搜索后,我发现,为了让地址栏的提交工作,生成的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> 

第二种方法:使用EditorTemplate为地址机型


我所做的:

  • 我移动到文件夹中的地址局部视图查看/共享/ EditorTemplates确保它具有相同的名称作为PersonAddress财产型号,即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属性h告诉我,由于某种原因,控制器动作中的预初始化的Address对象不会传递给局部视图。

第三种方法:把所有地址域在Person模型


这种方法适用于没有问题,但我不希望使用它,因为我不想,如果有多余的代码,我曾经想要在另一个模型中创建地址的创建视图。

综上所述


我应该怎么才能有,我可以用我的防空火炮应用可重复使用的部分创建视图吗?

回答

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

+0

作为答案创建一个完整的项目非常慷慨,谢谢。就我而言,我确实应该像我应该那样填充CityDropDown。奇怪的是,在调试时的父视图中,我可以看到Model.Address已正确初始化并且CityDropDown已填充,但当光标移至部分视图时,模型为null。这不是在你所做的项目中发生的,而只在我的项目中发生。 – snajahi

+0

@ K-SaMa:你是否在EditorTemplate中提供了'@ model'指令(对于'Address')? –

+0

是的,当然,我现在真的完全丧失了什么可能是问题。 – snajahi