2009-05-20 35 views
8

我有一個ASP.Net MVC應用程序與一個模型是幾層深含有一個集合。ASP.Net MVC - 模型與收集不填充回發

我相信創建對象的視圖都是正確設置的,但是當我將表單發佈到服務器時,它並沒有在模型中填充集合。

我有一塊數據中的哪一個在類層次結構從而發現:

person.PersonDetails.ContactInformation[0].Data; 

此類結構由LinqToSQL創建,並且是ContactInformation EntitySet<ContactData>類型。爲了創建我通過下面的視圖:

return View(person); 

和視圖內我有一個包含一個文本框相關聯於上述字段的名稱的形式:

<%= Html.TextBox("person.PersonDetails.ContactInformation[0].Data")%> 

POST方法在我的控制器就如下:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create (Person person) 
{ 
    //Do stuff to validate and add to the database 
} 

正是在這一點上,我擔心迷路person.PersonDetails.ContactInformation.Count()== 0。所以ModelBinder已經創建了一個ContactInformation對象,但沒有用它應該容納的對象(即ContactData)填充索引0.

我的問題是兩倍: 1.我是否採取了正確的方法..即應該這項工作? 2.關於爲什麼它可能無法填充ContactInformation對象的任何想法?

非常感謝, 理查德

回答

20

我認爲你的模型是默認的模型綁定一起工作太複雜。你可以嘗試使用多個參數,並與前綴結合他們:

public ActionResult Create( 
    Person person, 
    [Bind(Prefix="Person.PersonDetails")] 
    PersonDetails details, 
    [Bind(Prefix="Person.PersonDetails.ContactInformation")] 
    ContactInformation[] info) 
{ 
     person.PersonDetails = details; 
     person.PersonDetails.ContactInformation = info; 

     ... 
} 

或者你也可以開發自己的自定義模型粘結劑,將瞭解如何從表單輸入派生複雜的模型。

+1

謝謝,完美的作品。我已經嘗試過一個更深層次的例子,它可以很好地工作,但你可能是正確的,它正在複雜性中迷失。爲了清晰起見,兩條評論: 1.我只需要[Bind(Prefix =「Person.PersonDetails.ContactInformation」)] ContactInformation [] info)和模型對象的相應設置。 2. ContactInformation []需要爲EntitySet 以對應正確的類型。 現在查找一些前綴的更多細節.... 感謝您的幫助。 Richard – Richbits 2009-05-20 13:06:01

0

也許缺乏綁定屬性是這樣的:

[AcceptVerbs(HttpVerbs.Post)] 
public ActionResult Create ([Bind] Person person) 
{ 
// Do stuff to validate and add to the database 
} 
+0

謝謝,我給了這個嘗試沒有運氣。它綁定到該人並創建對象到ContactInformation對象的事實表明它是綁定的,而不是ContactData級別。 – Richbits 2009-05-20 12:24:34

+0

不,綁定只在參數上需要,如果您需要更改默認綁定規則。 – 2009-05-20 12:33:36

0

Html.TextBox的第一個參數是文本框的名字,第二個是值。

「錯誤」:

<%= Html.TextBox("person.PersonDetails.ContactInformation[0].Data")%> 

「右」:

<%= Html.TextBox("nameoftextbox", person.PersonDetails.ContactInformation[0].Data)%> 
+2

謝謝,但我的理解是,第二個參數是用來填充文本框的值。編輯方案。 defaultmodelbinder使用第一個值將表單綁定到回發時創建的對象。 – Richbits 2009-05-20 12:18:58

+0

我的不好........... – Ropstah 2009-05-20 12:27:10

5

如果某個屬性爲null,則模型聯編程序其他人無法找到它,或者無法在提交的表單中找到創建該屬性類型實例所需的值。例如,如果屬性具有不可空的ID,並且表單不包含該ID的任何數據,則模型聯編程序將將該屬性留爲空,因爲它無法在不知道該ID的情況下創建該類型的新實例。

換句話說,要診斷此問題,您必須仔細比較提交表單中的數據(這很容易與Firebug或Fiddler一起查看)與您期望模型綁定器填充的對象的結構進行比較。如果缺少任何必填字段,或者如果以不能將其轉換爲所需字段類型的方式提交值,則整個對象將保留爲空。

1

我一直是這樣同類型的情況下掙扎,最終都實現了深層的問題是,MVC默認模型聯編似乎沒有在EntitySet的<牛逼>領域,只列出<牛逼>下地幹活。然而,我找到了一個似乎可以接受的簡單解決方法。就我而言,我有一個與聯繫人(我的Linq-to-Sql EntitySet)具有一對多關係的公司實體。

因爲它似乎是,當我在我的代碼EntitySet的改變<聯繫>列出<聯繫>的MVC默認模型聯編開始預期(即使LTS是不是現在)的工作,我想我會提供一個替代,「別名」屬性MVC,這是類型列表<聯繫>,果然,這似乎工作。

在我公司實體類:


// This is what LINQ-to-SQL will use: 
private EntitySet<Contact> _Contacts = new EntitySet<Contact>(); 
[Association(Storage="_Contacts", OtherKey="CompanyID", ThisKey="ID")] 
public EntitySet<Contact> Contacts 
{ 
    get { return _Contacts; } 
    set { _Contacts.Assign(value); } 
} 

// This is what MVC default model binder (and my View) will use: 
public List<Contact> MvcContacts 
{ 
    get { return _Contacts.ToList<Contact>(); } 
    set { _Contacts.AddRange(value); } 
} 

所以現在,在我看來,我有以下幾點:

 
<label>First Name* 
    <%= Html.TextBox("Company.MvcContacts[" + i + "].FirstName") %> 
</label> 
<label>Last Name* 
    <%= Html.TextBox("Company.MvcContacts[" + i + "].LastName") %> 
</label> 

看起來像一個魅力的工作!

祝你好運! -Mike

0

確保您的模型(和所有嵌套模型)正在使用屬性(getters/setters)而不是字段。顯然,默認聯編程序需要屬性才能正常運行。我有一個非常相似的情況,通過將必要的字段更改爲屬性來修復。