WCF बिना "सेट" वाले गुणों पर चुटकी लेता है। कोई वर्कअराउंड?


97

मेरे पास कुछ वर्ग है जो मैं एक सेवा पद्धति के परिणामस्वरूप गुजर रहा हूं, और उस वर्ग के पास केवल संपत्ति है:

[DataContract]
public class ErrorBase
{
  [DataMember]
  public virtual string Message { get { return ""; } }
}

मुझे सेवा पक्ष पर एक अपवाद मिल रहा है:

System.Runtime.Serialization.InvalidDataContractException: 'MyNamespace.ErrorBase' प्रकार में संपत्ति 'संदेश' के लिए कोई सेट विधि नहीं।

मेरे पास यह संपत्ति केवल पाने वाले के रूप में है, मैं उपयोगकर्ताओं को इसे मूल्य निर्दिष्ट करने की अनुमति नहीं दे सकता। किसी भी वैकल्पिक हल मैं उपयोग कर सकते हैं? या मुझे कुछ अतिरिक्त विशेषता याद आ रही है?

जवाबों:


106

संदेश को एक सार्वजनिक गेट्टर लेकिन संरक्षित सेटर दें, ताकि केवल उपवर्ग (और DataContractSerializer), क्योंकि यह धोखा देता है :) मान को संशोधित कर सकता है।


यह एक साफ समाधान है!
रसेल

धन्यवाद, खुशी है कि यह उपयोगी था! यह वास्तव में इस ट्रिक के कई उपयोगों में से एक है। चूँकि गेटर्स और सेटर तकनीकी रूप से कार्य करते हैं, आप इस तकनीक का उपयोग प्राइमरी प्रकार (शायद एक्सएमएल में एक कस्टम समय प्रारूप) के कस्टम क्रमांकन प्रदान करने के लिए डराने वाले IDataContractSurrogate को अलग करने की आवश्यकता के बिना भी कर सकते हैं।
आरएच

28
आप इसे निजी भी बना सकते हैं। Serializer को कोई आपत्ति नहीं है कि यह निजी, सार्वजनिक, संरक्षित, आंतरिक या संरक्षित आंतरिक है।
हाबिल

8
और सेटर throw new NotSupportedException()
बनाइए

2
एक के बाद private set;काम करता है अगर आप का उपयोग करें [DataContract]और [DataMember]। यदि आप उन्हें छोड़ देते हैं, तो आपको जरूरत है public set;
user276648

12

यहां तक ​​कि अगर आपको मूल्य को अपडेट करने की आवश्यकता नहीं है, तो वस्तु को अलग करने के लिए WCFSerializer द्वारा सेटर का उपयोग किया जाता है (और मूल्य को फिर से सेट करें)।

यह SO तब है जब आप इसके बाद हैं: WCF DataContracts


1
तो मेरे लिए समस्या को दूर करने का एकमात्र तरीका संपत्ति के बजाय एक विधि बनाना है? फिर, मैं इस संपत्ति पर "सेट" की अनुमति नहीं दे सकता हूं
एंड्री

आप इसे एक विधि बना सकते हैं (उदाहरण के लिए GetMessage () {return "";}) वैकल्पिक रूप से, मुझे पूरा यकीन है कि आप इसे अनदेखा करने के लिए WCF सीरियल को बता सकते हैं। मैं देखूंगा कि मैं क्या ढूंढ सकता हूं और आपको बता दूं।
रसेल

1
स्टैकओवरफ़्लो प्रश्न सिर पर कील मारता है: stackoverflow.com/questions/172681/wcf-datacontracts
रसेल


5

यदि आपके पास केवल एक गटर है, तो आपको संपत्ति को क्रमबद्ध करने की आवश्यकता क्यों है। ऐसा लगता है कि आप केवल पढ़ने के लिए संपत्ति के लिए DataMember विशेषता को हटा सकते हैं, और धारावाहिक सिर्फ संपत्ति की उपेक्षा करेंगे।


3
यह वास्तव में एक व्युत्पन्न संपत्ति (जैसे, एक URL संपत्ति जो एक आईडी संपत्ति से गणना की जाती है) को एक स्थिर भंडारण (उदाहरण के लिए, एक डेटाबेस) - उसके लिए upvote - क्रमबद्ध करने के लिए समझ में नहीं आता है, लेकिन यह इसे क्रमबद्ध करने के लिए कोई मतलब नहीं है प्रतिनिधित्व (उदाहरण के लिए, JSON या XML) जो API अनुरोध द्वारा वापस किया जाता है।
फ्लोरियन विंटर

3

क्या आपके पास बस "डू-नथिंग" सेटर नहीं हो सकता है ??

[DataContract]
public class ErrorBase
{
  [DataMember]
  public virtual string Message 
  {
      get { return ""; } 
      set { }
  }
}

या उस पर भी DataContract serializer barf करता है ??


14
यह वर्जित नहीं है, मैं सिर्फ क्लाइंट एपीआई का उपयोग करने वाले डेवलपर्स को यह सोचने देना नहीं चाहता था कि वे संपत्ति को सामान सौंप सकते हैं।
एंड्री

2

DataMember विशेषता वाले गुणों के लिए हमेशा सेट की आवश्यकता होती है। आपको डेटा अनुप्रयोग पर simmilar object लिखना चाहिए क्योंकि DataContract के सदस्यों को हमेशा मान सौंपे जा सकते हैं।


2

मुझे ASP.NET MVC के साथ यह समस्या थी और मैं JSON आउटपुट में आइटम पर नामों को नियंत्रित करने में सक्षम होने के लिए DataContractSerializer का उपयोग करना चाहता था। आखिरकार मैंने सीरियल को JSON.NET में स्विच कर दिया, जो बिना सेटर के संपत्तियों का समर्थन करता है (जो DataContractSerializer नहीं करता है) और संपत्ति का नाम नियंत्रण (जो ASP.NET MVC में अंतर्निहित JSON धारावाहिक नहीं है) [JsonProperty(PropertyName = "myName")]


2

यदि यह एक व्यवहार्य विकल्प है, तो ErrorBaseआधार वर्ग के रूप में होने के बजाय , इसे निम्नानुसार परिभाषित करें:

    public interface IError
    {
        string Message
        {
            [OperationContract]
            get;

            // leave unattributed
            set;
        }
    }

अब, भले ही एक सेटर मौजूद है, यह WCF चैनल के माध्यम से क्लाइंट के लिए दुर्गम है, इसलिए यह ऐसा है जैसे कि यह निजी था।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.