2012-04-17 5 views
7

मैं यह त्रुटि है जब मैं एक FormViewएक संपत्ति FormView (दो तरह से नेस्टेड संपत्तियों के लिए बंधन)

अपडेट करने का प्रयास में 'xxx.yyy' नाम नहीं मिल सका

एक संपत्ति 'नाम नहीं मिल सका MainContact । FirstName ' पर ऑब्जेक्टडेटा स्रोत ' odsForm 'में DataObjectTypeName प्रॉपर्टी द्वारा निर्दिष्ट किया गया है।

मुझे लगता है कि ऐसा इसलिए है क्योंकि मैं EditTemplate में इस

<asp:TextBox Text='<%# Bind("MainContact.FirstName") %>' ID="txtFirstName" runat="server" /> 

की तरह एक पाठ बॉक्स का उपयोग करें यह पाठ बॉक्स में सही पाठ दिखाता है, लेकिन जब यह अद्यतन करता है जाहिरा तौर पर यह काम नहीं करता।

यह FormView के डेटा स्रोत है

<asp:ObjectDataSource ID="odsForm" runat="server" DataObjectTypeName="Helpers.BusinessObjects.EntryItem" 
    SelectMethod="GetEntryByEmail" TypeName="Helpers.DataAccessers.EntryHelper" 
    UpdateMethod="UpdateEntry"> 
    <SelectParameters> 
     <asp:SessionParameter SessionField="email" Name="email" Type="String" /> 
    </SelectParameters> 
</asp:ObjectDataSource> 

यह EntryItem कक्षा

public class EntryItem 
    { 
     public int Id { get; set; } 
     public string Email { get; set; } 
     public string Password { get; set; } 
     public Person MainContact { get; set; } 
     ... 
    } 

और व्यक्ति कक्षा

public class Person 
{ 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    ... 
} 

डिबगर FormView ItemUpdating ईवेंट हैंडलर में हो जाता है है , लेकिन Helpers.DataAccessers.EntryHelper.UpdateEntry में कभी नहीं।

मैं इसे कैसे हल कर सकता हूं?

उत्तर

1

दो संभावित दृष्टिकोण।

सबसे पहले, आप अपने ObjectDataSource की परिभाषा से DataObjectTypeName="Helpers.BusinessObjects.EntryItem" छोड़ सकते हैं। मैंने कभी भी इसका इस्तेमाल नहीं किया है और बाइंडिंग हमेशा काम करते हैं।

लेकिन यह शायद मदद नहीं करेगा, क्योंकि Bind/Eval शायद संदर्भों का पालन करने में सक्षम नहीं है (Bind("MainContact.FirstName"))।

इसके बजाय, के रूप में

<%# ((EntryItem)Container.DataItem).MainContract.FirstName #> 

इस पुनर्लेखन नकारात्मक पक्ष यह है कि आप ढीला स्वत: दो तरह से तो बाध्यकारी आप बांधने की मशीन एक छोटे से मदद करनी है। बस अपने ObjectDataSource करने के लिए और संचालकों के अंदर एक Inserting/Updating संचालकों जोड़ें:

protected void TheObjectDataSource_Updating(object sender, BlahBlahEventArgs e) 
{ 
    // find the control in the data bound parent 
    TextBox txt = (TextBox)YourFormView.FindControl("txtFirstName"); 

    // read the value and add it to parameters 
    e.Parameters.Add("nameofyourparameter", txt.Text); 
} 
0

एक जोड़े के सूत्रों के अनुसार, यह वास्तव में संभव नहीं है दो तरह से नेस्टेड गुणों के साथ बंधन करना है।

यहां SO: https://stackoverflow.com/a/1195119/370671 पर एक समान प्रश्न का उत्तर दिया गया है। ObjectDataSource का उपयोग कर आप किसी भी समस्या का कारण नहीं बनेगा जब क्या [आप] बाँध एक सरल संपत्ति इस तरह के एक ग्राहक यानी की एक नाम के रूप में है ज्यादातर मामलों में

अब, अभी भी:

इसके अलावा, there's a blog post समस्या का वर्णन करते: आपके पास क्लाइंट का संग्रह है जो आप GridView से जुड़ते हैं और कॉलम में से एक क्लाइंट का नाम प्रदर्शित करता है। ऐसा करने के लिए आप Bind("Name") जैसे कुछ का उपयोग करें। समस्या तब उत्पन्न होती है जब आपको Bind("Address.StreetName") में उपप्रोपर्टी से जुड़ने की आवश्यकता होती है।यह काम नहीं करेगा

4

आप इस तरह से इस्तेमाल किया जा करने के लिए अपने स्वयं के बंधन आप चाहते हैं के रूप में प्रदर्शन करने में सक्षम नियंत्रण लिख सकता है (मैं इस से एक बना दिया): वैसे भी

<ItemTemplate> 
     <%# Eval("MainContact.FirstName")%> 
    </ItemTemplate> 
    <EditItemTemplate> 
     <xx:BinderHelper runat="server" DataSource='<%# Bind("MainContact") %>'> 
     <ItemTemplate> 
      <asp:TextBox Text='<%# Bind("FirstName") %>' ID="txtFirstName" 
      runat="server" /> 
     </ItemTemplate> 
     </xx:BinderHelper> 
    </EditItemTemplate> 

, मैं तुम्हें सुझाव है सीधे पृष्ठों में डोमेन ऑब्जेक्ट्स का उपयोग न करें, और कुल ऑब्जेक्टडेटा स्रोत के साथ उन्हें न लिखें।

public class Person 
{ 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 

    // just added 
    public DateTime? BirthDate { get; set; } 
} 

तो फिर तुम अन्यथा ढांचे अपने ObjectDataSource फोन करेगा सभी GridViews, FormViews आदि बदलने के लिए, जन्मतिथि स्टोर करने के लिए की आवश्यकता होगी,: समस्या यह है कि उदाहरण के एक क्षेत्र को जोड़ने के लिए के लिए जब आप अपने डोमेन बदल जाएगा जन्मतिथि में null डालने का तरीका अपडेट करें। उदाहरण के लिए:

<asp:GridView runat="server" DataSourceID="odsForm" AutoGenerateColumns="False"> 
    <Columns> 
     <asp:CommandField runat="server" ShowEditButton="True" /> 
     <asp:BoundField DataField="FirstName" /> 
     <asp:BoundField DataField="LastName" /> 
</Columns> 
    </asp:GridView> 

यह आपके व्यक्तियों को डेटाबेस से पढ़ेगा। प्रत्येक व्यक्ति के पास जन्म तिथि निर्धारित होगी। जब आप सहेजते हैं, तो व्यक्ति को जन्मदिन से null पर अपडेट किया जाएगा, क्योंकि ग्रिड व्यू नया फ़ील्ड स्टोर नहीं करता है।

मुझे लगता है कि डाटाबेसिंग के लिए डीटीओ लिखना सबसे अच्छा समाधान है (और उन्हें प्रेजेंटेशन लेयर में छोड़ दें) और डेटा ऑब्जेक्ट्स। आपके मामले में:

public class EntryItemView 
{ 
    public int Id { get; set; } 
    public string Email { get; set; } 
    public string Password { get; set; } 
    public string MainContactFirstName { get; set; } 
} 

[DataObject] 
public class EntryItemViewDataObject { 
    [DataObjectMethod(DataObjectMethodType.Select)] 
    public EntryItemView GetItem(...) { 
     // TODO: read from the database, convert to DTO 
    } 

    [DataObjectMethod(DataObjectMethodType.Update)] 
    public void Update(EntryItemView entry) { 

     EntryItem domainObject = getById(entry.Id); 
     // TODO: use EmitMapper or AutoMapper 
     domainObject.MainContact.FirstName = entry.MainContactFirstName; 

     // TODO: save 
    } 
} 

इस तरह आपके डोमेन के लिए किसी भी अतिरिक्त अपने विचारों के लिए सुरक्षित हो जाएगा, और DataObjects पढ़ा जाएगा/केवल क्षेत्रों वे जरूरत लिखें।

+0

+1: मैं हमेशा 'ऑब्जेक्टडेटा स्रोत' के साथ अपना समय बर्बाद कर देता हूं, मुझे उम्मीद है कि अगली बार मुझे उनसे परेशान न हो। – capdragon

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