2013-11-29 66 views
2

我是ASP.NET MVC 4的新手,我正在努力应对webforms中的一个简单概念。所以,如果我有一个客户类,并且客户有一个地址,那么如何在同一个提交操作中编辑同一表单上的客户和地址?我想为地址创建一个'_Edit'部分视图,但是如果地址没有提交按钮,我不知道如何连接控制器。我只想要一个按钮将所有模型保存在一个视图中。我可以使用部分视图在ASP.NET MVC中编辑多个模型吗?

因此,我可以创建一个新的CompanyView模型,视图和控制器,并以此方式完成。但是,如果我有许多具有地址的对象,那么继续创建“查看模型”以允许您以同一形式编辑对象和地址似乎有很多工作要做。有没有办法创建地址部分编辑视图,并以某种方式更新公司编辑控制器中的地址字段?或者,让它以某种方式通过模型。返回公司编辑控制器而不是null?

编辑:

模式

public class Address 
{ 
    public Int32 Id { get; set; } 

    [Display(Name = "Address 1")] 
    public String Address1 { get; set; } 

    [Display(Name = "Address 2")] 
    public String Address2 { get; set; } 

    [Display(Name = "City")] 
    public String City { get; set; } 

    [Display(Name = "State")] 
    public String State { get; set; } 

    [Display(Name = "Postal Code")] 
    public String PostalCode { get; set; } 

    [Display(Name = "Country")] 
    public String Country { get; set; } 
} 

public class Company 
{ 
    public Int32 Id { get; set; } 

    [Display(Name = "Company Name")] 
    public String Name { get; set; } 

    public Int32 AddressId { get; set; } 

    public virtual Address Address { get; set; } 
} 

地址_Edit管窥

@model Models.Address 

<div class="well"> 
    <fieldset> 
     <legend>Address</legend> 

     @Html.EditorFor(model => model.Address1) 
     @Html.EditorFor(model => model.Address2) 
     @Html.EditorFor(model => model.City) 
     @Html.EditorFor(model => model.State) 
     @Html.EditorFor(model => model.PostalCode) 
     @Html.EditorFor(model => model.Country) 
    </fieldset> 
</div> 

公司编辑视图

@model Models.Company 

@{ 
    ViewBag.Title = "Edit"; 
    Layout = "~/Views/shared/ContentLayout.cshtml"; 
} 


<div class="row"> 
    <div class="col-lg-12"> 
     <div class="page-header"> 
      <h2>Edit Company</h2> 
     </div> 
    </div> 
</div> 

<div class="row"> 
    <div class="col-lg-8"> 
@using (Html.BeginForm("Edit", "Company", new { @class = "bs-example form-horizontal" })) { 
    @Html.AntiForgeryToken() 
    @Html.ValidationSummary(true) 

    @Html.HiddenFor(model => model.Id) 

    @Html.EditorFor(model => model.Name) 

    @Html.HiddenFor(model => model.AddressId) 

    @Html.Partial("~/Views/Address/_Edit.cshtml", Model.Address) 

     <p> 
      <button name="button" type="submit" class="btn btn-primary" value="submit">Submit</button> 
     </p> 
} 

    </div> 
</div> 

公司编辑控制器

[HttpPost] 
     public ActionResult Edit(Company model, int id) 
     { 
      if (ModelState.IsValid) 
      { 
       // model.Address = NULL here! 

       Success("Record updated!"); 
       return RedirectToAction("Index"); 
      } 
     } 

回答

4

对于模型绑定正常工作,您只需要发布一个Company回控制器。只是通过你的整个模型到你的部分:

@model Models.Company 

@{ 
    ViewBag.Title = "Edit"; 
    Layout = "~/Views/shared/ContentLayout.cshtml"; 
} 

<div class="row"> 
    <div class="col-lg-12"> 
     <div class="page-header"> 
      <h2>Edit Company</h2> 
     </div> 
    </div> 
</div> 

<div class="row"> 
    <div class="col-lg-8"> 
     @using (Html.BeginForm("Edit", "Company", new { @class = "bs-example form-horizontal" })) { 
      @Html.AntiForgeryToken() 
      @Html.ValidationSummary(true) 

      @Html.HiddenFor(model => model.Id) 

      @Html.EditorFor(model => model.Name) 

      @Html.HiddenFor(model => model.AddressId) 

      @Html.Partial("~/Views/Address/_Edit.cshtml", Model) 

      <p> 
       <button name="button" type="submit" class="btn btn-primary" value="submit">Submit</button> 
      </p> 
     } 
    </div> 
</div> 

_Edit

@model Models.Company 

<div class="well"> 
    <fieldset> 
     <legend>Address</legend> 
     @Html.HiddenFor(model => model.Address.Id) 
     @Html.EditorFor(model => model.Address.Address1) 
     @Html.EditorFor(model => model.Address.Address2) 
     @Html.EditorFor(model => model.Address.City) 
     @Html.EditorFor(model => model.Address.State) 
     @Html.EditorFor(model => model.Address.PostalCode) 
     @Html.EditorFor(model => model.Address.Country) 
    </fieldset> 
</div> 

控制器

[HttpPost] 
public ActionResult Edit(Company model, int id) 
{ 
    if (ModelState.IsValid) 
    { 
     // model.Address should now be available 

     Success("Record updated!"); 
     return RedirectToAction("Index"); 
    } 
} 

您现在应该看到您的模型正确地绑定上的Address导航属性帖子。基于问题的意见

你如何建立你的观点和谐音


编辑是你的真。要记住的重要一点是,模型绑定基于由HTML助手给予表单元素的名称。

因此Html.HiddenFor(m => m.Id)将导致<input name="Id">Html.HiddenFor(m => m.Address.Id)将导致<input name="Address.Id">。第一个将不会被模型联编程序拾取为Company的导航属性,第二个将会。

简单的路线就是复制你的局部视图。但是,如果它的局部变得非常大且复杂,并且有大量字段,那么您可以创建一个部分基类,这两个实体都可以继承。

BaseEntityWithAddress.cs

public partial class BaseEntityWithAddress 
{ 
    public virtual Address Address { get; set; } 
} 

Customer.cs

public class Customer : BaseEntityWithAddress 
{ 
    // your properties, no need to redefine Address here 
} 

Vendor.cs

public class Vendor: BaseEntityWithAddress 
{ 
    // your properties, no need to redefine Address here 
} 

然后你的部分观点将采取BaseEntityWithAddress为模型,这你仍然通过整个模型。

_Edit.cshtml

@model Models.BaseEntityWithAddress 

<div class="well"> 
    <fieldset> 
     <legend>Address</legend> 
     @Html.HiddenFor(model => model.Address.Id) 
     @Html.EditorFor(model => model.Address.Address1) 
     @Html.EditorFor(model => model.Address.Address2) 
     @Html.EditorFor(model => model.Address.City) 
     @Html.EditorFor(model => model.Address.State) 
     @Html.EditorFor(model => model.Address.PostalCode) 
     @Html.EditorFor(model => model.Address.Country) 
    </fieldset> 
</div> 

这将生成正确的名称形式要素模型绑定回暖。

+0

好的,那可行!那么,假设我有一个客户和供应商,都需要一个地址,您说您要为客户和供应商复制'_Edit'视图?你会命名这些_EditCustomer和_EditVendor或只是_Edit?有没有办法为地址写一个通用的局部编辑视图,这样我就只有一个局部编辑视图用于所有具有地址的对象? – Sephrial

+0

@Sephrial这是一个很长的答案,在评论中输入,所以我编辑了我的原始答案,告诉你如何做到这一点。 – dom

+0

感谢您的深入解释!这帮助我将我的头包裹在模型上。 – Sephrial

1

所以,你将有2类:

class Address 
{ 
    public string street {get;set;} 
    public string state {get;set;} 
} 

class Customer 
{ 
    public string name {get;set;} 
    public Address address {get;set;} // links to the above class. 
} 

您的主要客户的看法是这样的:

@model Models.Customer 

@using (Html.BeginForm() 
{ 

    @Html.TextBoxFor(m => m.name) 

    @Html.Partial("_Edit", Model.address) 

    <button type="submit">Submit</button> 

} 

您部分:

@model Models.Address 

@Html.TextBoxFor(m => m.street) 
@Html.TextBoxFor(m => m.state) 

然后在你的控制器:

public ActionResult customer(Customer model) 
{ 
    // do whatever 

} 
+0

这是我试图做的非常多,除了当我检查控制器中的客户模型。 model.Address为null。 – Sephrial

+0

将您尝试过的问题添加到您的问题中很有用。这样人们可以更好地了解你所处的位置。 – jzm

+0

当然,我用我的代码更新了我的帖子。谢谢! – Sephrial

相关问题