2009-05-20 16 views
8

पर पॉपुलटिंग नहीं है मेरे पास एक मॉडल के साथ एक एएसपी.NET एमवीसी एप्लीकेशन है जो कई परतों को गहराई से संग्रहित करता है।एएसपी.नेट एमवीसी - संग्रह के साथ मॉडल पोस्टबैक

मेरा मानना ​​है कि ऑब्जेक्ट्स बनाने के लिए दृश्य सही ढंग से सेट अप किया गया है, लेकिन जब मैं सर्वर पर फॉर्म पोस्ट करता हूं तो यह मॉडल के भीतर संग्रह को पॉप्युलेट नहीं करता है।

मैं डेटा का एक टुकड़ा जो वर्ग पदानुक्रम इस प्रकार में पाया जाता है है:

person.PersonDetails.ContactInformation[0].Data; 

इस वर्ग संरचना LinqToSql द्वारा बनाई गई है, और ContactInformation प्रकार EntitySet<ContactData> की है।

return View(person); 

और दृश्य के भीतर मैं एक रूप है जो कि ऊपर उल्लेख किया क्षेत्र से जुड़े एक नाम के साथ एक एकल पाठ बॉक्स शामिल है:

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

पोस्ट विधि दृश्य मैं निम्नलिखित पारित बनाने के लिए भीतर मेरे नियंत्रक तो इस प्रकार है:

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

यह इस बिंदु जहां मैं के रूप में person.PersonDetails.ContactInformation.Count() == 0 खो जाना है। तो मॉडलबिंडर ने एक संपर्क जानकारी ऑब्जेक्ट बनाया है, लेकिन इसे उस ऑब्जेक्ट के साथ पॉप्युलेट नहीं किया है जिसे इसे इंडेक्स 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. मुझे केवल [बाइंड (उपसर्ग = "व्यक्ति.पर्सन विवरण। संपर्क जानकारी")] संपर्क जानकारी [] जानकारी) और मॉडल ऑब्जेक्ट की इसी सेटिंग की आवश्यकता है। 2. संपर्क जानकारी [] को सही प्रकार के अनुरूप होने के लिए EntitySet होना आवश्यक है। अब उपसर्ग पर कुछ और विवरण देखने के लिए .... आपकी मदद के लिए धन्यवाद। रिचर्ड – Richbits

+0

नाइस, अभी तक 'उपसर्ग' के बारे में नहीं पढ़ा था! – Ropstah

+0

अच्छा एक .. या आप अपना खुद का कस्टम मॉडल बाइंडर विकसित कर सकते हैं जो समझ जाएगा कि फॉर्म इनपुट से अपने जटिल मॉडल को कैसे प्राप्त किया जाए, क्या आप लिंक या इंपोर्ट साझा कर सकते हैं। अगर आप पहले ही एचवी कर चुके हैं? –

0

शायद बाइंड विशेषता की कमी मामला है:

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

धन्यवाद, मैंने इसे बिना किसी किस्मत के प्रयास किया है। तथ्य यह है कि यह व्यक्ति के लिए बाध्यकारी है और ContactInformation ऑब्जेक्ट को ऑब्जेक्ट्स बनाने के लिए मुझे इंगित करता है कि यह बाध्यकारी है, केवल संपर्क डेटा स्तर पर नहीं। – Richbits

+0

नहीं, यदि आपको डिफ़ॉल्ट बाध्यकारी नियमों को बदलने की आवश्यकता है तो बाइंड केवल एक तर्क पर आवश्यक है। –

0

Html.TextBox का पहला तर्क पाठ बॉक्स का नाम है, दूसरा मान होगा।

"गलत":

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

"ठीक है":

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

धन्यवाद, लेकिन मेरी समझ यह है कि दूसरा पैरामीटर एक टेक्स्ट में टेक्स्टबॉक्स को पॉप्युलेट करने के लिए उपयोग किया जाने वाला मान है। संपादन परिदृश्य। पहले मान को डिफॉल्टमोडेलबिंडर द्वारा फ़ॉर्म को बाध्य करने के लिए बनाए गए ऑब्जेक्ट में बाध्य करने के लिए उपयोग किया जाता है। – Richbits

+0

मेरा बुरा ........... – Ropstah

5

यदि कोई संपत्ति शून्य है, तो मॉडल बाइंडर अन्य इसे नहीं ढूंढ सका या संपत्ति के प्रकार का उदाहरण बनाने के लिए आवश्यक सबमिट किए गए फॉर्म में मूल्य नहीं मिल सका। उदाहरण के लिए, यदि संपत्ति में एक गैर-शून्य आईडी है और आपके फॉर्म में उस आईडी के लिए कोई डेटा नहीं है, तो मॉडल बाइंडर संपत्ति को शून्य के रूप में छोड़ देगा क्योंकि यह आईडी को जानने के बिना प्रकार का एक नया उदाहरण नहीं बना सकता है।

दूसरे शब्दों में, इस समस्या का निदान करने के लिए आपको सावधानीपूर्वक सबमिट किए गए फॉर्म में डेटा की तुलना करना चाहिए (यह फ़ायरबग या फिडलर के साथ देखना आसान है) जिस वस्तु को आप मॉडल बाइंडर को पॉप्युलेट करने की उम्मीद कर रहे हैं उसकी संरचना के साथ। यदि कोई आवश्यक फ़ील्ड गुम है, या यदि मान इस तरह से सबमिट किए जाते हैं कि उन्हें किसी आवश्यक फ़ील्ड के प्रकार में परिवर्तित नहीं किया जा सकता है, तो संपूर्ण ऑब्जेक्ट को शून्य छोड़ दिया जाएगा।

+2

यह सही लगता है। –

+0

धन्यवाद, निश्चित रूप से यदि आप यहां जो कहते हैं वह सही है, तो tvanfossen का समाधान भी असफल हो जाएगा? – Richbits

+0

जरूरी नहीं है।मैं एक संभावित मुद्दा का वर्णन करता हूं। वह दूसरे का वर्णन करता है। –

1

मैं परिदृश्य के इस एक ही प्रकार के साथ संघर्ष कर रहे हैं और अंत में साकार करने के लिए मूल समस्या यह है कि MVC डिफ़ॉल्ट मॉडल बांधने की मशीन EntitySet < टी > क्षेत्रों, केवल सूची < टी > खेतों पर काम करने के लिए प्रतीत नहीं होता आया था। हालांकि मुझे एक सरल कामकाज मिल गया जो स्वीकार्य लगता है। मेरे मामले में, मेरे पास एक कंपनी इकाई है जिसमें संपर्कों के लिए कई संबंध हैं (मेरी लिंक-टू-एसक्यूएल एंटिटीसेट)।

के बाद से ऐसा लगता है कि जब मैं EntitySet से मेरे कोड बदलने < संपर्क > < संपर्क > सूची में, MVC डिफ़ॉल्ट मॉडल बांधने की मशीन के रूप में उम्मीद (भले ही LTS अब नहीं है) काम करना शुरू करता है, मैं समझ मैं एक प्रदान करेगा वैकल्पिक, "उपनाम" संपत्ति एमवीसी के लिए है जो प्रकार < संपर्क > से संपर्क करें, और यह सुनिश्चित है कि यह काम करने लगता है।

मेरी कंपनी इकाई वर्ग में:


// 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> 

एक आकर्षण की तरह काम करने के लिए लगता है!

शुभकामनाएँ! -माइक

+0

धन्यवाद, क्षमा करें थोड़ी देर के लिए दूर चला गया। मुझे उम्मीद है कि आपने एमएसडीएन पर इसका जवाब देखा (मुझे लगता है कि यह आप थे जिन्होंने वहां टिप्पणी की थी)। मैंने कनेक्ट साइट पर एक बग भी लॉग किया है, और इसकी पुष्टि नेट 4.0 में तय की गई है। मेरे मामले में मुझे लगता है कि आपका समाधान बहुत जटिल हो गया है क्योंकि इकाई वर्ग मेरी कक्षा संरचना में गहरा है। मैंने यह भी पाया है कि EntitySets का संपादन एक वास्तविक समस्या है क्योंकि अद्यतन के बजाय एक नई डीबी पंक्ति बनाई गई है। उम्मीद है कि इसे 4.0 के लिए भी हल किया जाएगा। – Richbits

+0

यह सुनकर अच्छा लगा कि यह संबोधित किया जाएगा। और हां, मैंने माइक्रोसॉफ्ट न्यूज ग्रुप के लिए वही समाधान पोस्ट किया है जैसा कि मैंने यहां किया था: मुझे अब तक एहसास नहीं हुआ कि आप ही इसे शुरू कर चुके थे! आपको एलन से एक जवाब मिला जो दिखाता है कि संपत्ति-सेटर को कैसे ठीक किया जाए, जो कि अधिक आदर्श लगता है, लेकिन मेरे मामले में मैं एलटीएस से उत्पन्न इकाइयों का उपयोग कर रहा हूं और यह सुनिश्चित नहीं करता कि इसे आसानी से कैसे ठीक किया जाए (बिना अधिक विशाल कामकाज के)। पीएस, दूसरा धागा यहां है: http://groups.google.com/group/microsoft.public.dotnet.framework.aspnet/browse_thread/thread/a2869970f33c712a/188c0a9e5c00dc2a – Funka

0

सुनिश्चित करें कि आपके मॉडल (और सभी नेस्टेड मॉडल) फ़ील्ड के बजाय गुण (गेटर्स/सेटर्स) का उपयोग कर रहे हैं। स्पष्ट रूप से डिफ़ॉल्ट बाइंडर को गुणों को ठीक से काम करने की आवश्यकता होती है। मेरे पास एक समान स्थिति थी जो आवश्यक फ़ील्ड को गुणों में बदलकर तय की गई थी।

संबंधित मुद्दे