2011-09-23 82 views
2

我正在開發使用ASP.NET MVC 3.0的銷售訂單管理應用程序。我需要開發一個可以添加客戶詳細信息的頁面。ASP MVC 3.0複雜視圖

客戶詳細信息包括

public class Customer 
    { 
     public int ID { get; set; } 
     public string Code { get; set; } 
     public string Name { get; set; } 
     public string Alias { get; set; } 
     public int DefaultCreditPeriod { get; set; }   
     public Accounts Accounts { get; set; } 
     public IList<Address> Addresses { get; set; } 
     public IList<Contact> Contacts { get; set; } 
    } 

public class Accounts 
    { 
     public int ID { get; set; } 
     public string VATNo { get; set; } 
     public string CSTNo { get; set; } 
     public string PANNo { get; set; } 
     public string TANNo { get; set; } 
     public string ECCNo { get; set; } 
     public string ExciseNo { get; set; } 
     public string ServiceTaxNo { get; set; } 
     public bool IsServiceTaxApplicable { get; set; } 
     public bool IsTDSDeductable { get; set; } 
     public bool IsTCSApplicable { get; set; } 
    } 

public class Address 
    { 
     public int ID { get; set; } 
     public AddressType Type { get; set; }   
     public string Line1 { get; set; } 
     public string Line2 { get; set; } 
     public string Line3 { get; set; } 
     public string Line4 { get; set; } 
     public string Country { get; set; } 
     public string PostCode { get; set; } 
    } 

public class Contact 
    { 
     public int ID { get; set; } 
     public ContactType Type { get; set; } 
     public string Name { get; set; } 
     public string Title { get; set; } 
     public string PhoneNumber { get; set; } 
     public string Extension { get; set; } 
     public string MobileNumber { get; set; } 
     public string EmailId { get; set; } 
     public string FaxNumber { get; set; } 
     public string Website { get; set; } 
    } 

客戶需要一個單一的頁面,以填補所有客戶的詳細信息(一般信息,帳戶信息,地址信息和聯繫信息)。將有多個地址(賬單,發貨等)和多個聯繫人(銷售,採購)。我是MVC的新手。如何爲上述創建視圖並動態添加多個地址?

+1

沒有冒犯,但你期待什麼樣的答案?你所要求的將涉及*許多*不連貫的步驟,所有這些都需要一些學習。最好的辦法是看一些例子(比如官方的[音樂商店示例](http://www.asp.net/mvc/tutorials/mvc-music-store-part-1)),並嘗試創建頁面一旦你提出了更具體的問題,你就回到SO上來。 –

回答

1

我經常創建包裝模型來處理這種情況,例如

public class CustomerWrapperModel 
{ 
    public Customer Customer { get; set;} 
    public Accounts Accounts { get; set;} 
    public List<Address> AddressList { get; set} 

    //Add 
    public CustomerWrapperModel() 
    { 

    } 

    //Add/Edit 
    public CustomerWrapperModel(Customer customer, Accounts accounts, List<Address> addressList) 
    { 
     this.Customer = customer; 
     this.Accounts = accounts; 
     this.AddressList = addressList; 
    } 
} 

然後聲明查看爲類型CustomerWrapperModel,並使用編輯器,像這樣:

@model MyNamespace.CustomerWrapperModel 

@Html.EditorFor(model => model.Customer) 
@Html.EditorFor(model => model.Accounts) 
@Html.EditorFor(model => model.AddressList) 

,並有一個控制器,用於接收,看起來像這樣的帖子:

[HttpPost] 
public ActionResult(Customer customer, Accounts accounts, List<Address> addressList) 
{ 
    //Handle db stuff here 
} 

由於就像動態地添加地址一樣,如果您使用MVC驗證並希望使用正確的列表索引正確地保持列表結構,那麼您可以使用List參數控制器是當前地址發佈到一個輔助控制器是這樣的:

[HttpPost] 
public PartialResult AddAddress(List<Address> addressList) 
{ 
    addressList.Add(new Address); 

    return PartialView(addressList); 
} 

再有,只是再次呈現出來的地址字段的局部視圖:

@model List<MyNamespace.Address> 

@{ 
    //Hack to get validation on form fields 
    ViewContext.FormContext = new FormContext(); 
} 

@Html.EditorForModel() 

確保您地址字段都在一個容器中,然後您可以用返回的數據覆蓋現有的數據,並且您的新地址字段將被添加到底部。一旦你更新了你的容器,你可以做這樣的事情來重新進行驗證:

 var data = $("form").serialize(); 

     $.post("/Customer/AddAddress", data, function (data) { 

      $("#address-container").html(data); 

      $("form").removeData("validator"); 
      $("form").removeData("unobtrusiveValidation"); 
      $.validator.unobtrusive.parse("form"); 

     }); 

NB。我知道一些人有這樣做的問題,因爲它需要服務器端命中添加字段到一個頁面,可以很容易地添加客戶端(我總是用它做所有的客戶端,但嘗試過一次與此方法,並從未回去)。我這樣做的原因是因爲它是保持列表項索引正確的最簡單方法,特別是如果你有插入和添加以及你的對象有很多屬性。此外,通過使用局部視圖來呈現數據,您可以確保在開箱即用的新字段上生成驗證,而不必爲新添加的客戶端字段手動分割驗證。在大多數情況下,權衡是在ajax請求期間傳輸少量數據。

您也可以選擇使用發送到AddAddress控制器的字段進行更細化處理,如您所見,我只是將整個表單發佈到控制器,並忽略除地址字段以外的所有內容,我使用的是快速服務器和與我可以以更高帶寬效率的方式浪費編碼這種類型的功能的時間相比,不需要的表單字段的附加(次要)開銷可以忽略不計。

+0

感謝羅布,這是有道理的。讓我嘗試。 – RAM

0

你通過根模型對象來查看呼叫在您的控制器是這樣的:

public ActionResult Index() { 
    var customer = GetCustomer(); // returns a Customer 
    return View(customer); 
} 

然後你的觀點看起來是這樣的:

@model Customer 

<!DOCTYPE html> 
<!-- etc., etc. --> 
<h1>Customer @Model.Name</h1> 
<ul> 
@foreach (var address in Model.Addresses) { 
    <li>@address.Line1</li> 
} 
</ul> 

人們得到的圖片。

上面的代碼依賴於@model指令,這是ASP.NET MVC 3中的新增功能(請參閱this blog post)。

0

是一個很好的問題:d正常的導航性能,如Accounts這樣做是不是要拼命:

@Html.EditorFor(model => model.Accounts.ID) 

@Html.EditorFor(model => model.Accounts.VATNo) 

會做你想要的東西。但對於收藏導航屬性(AddressesContacts),默認情況下不能在一個位置執行此操作。我建議您爲Addresses(和Contacts)使用不同的頁面。因爲這是最簡單的方法。但是,如果你想這樣做在一個地方(也有出AJAX請求),您可以通過Customer創建視圖,使用腳手架模型和它的簡單的導航性能,以及列表(AddressesContacts)您必須將它們添加到JavaScriptinput字段(例如對於每個添加的Address,將其放在Array中)並將字段發佈到服務器。在服務器上,您可以通過默認的model-binder和列表獲得主模型和簡單屬性,您可以1)創建自己的模型綁定器2)自己從輸入的字符串解析它們。好鎖