2012-01-25 17 views
8

मेरे पास निम्न नमूना सी # कोड है जो svcutils.exe अनुप्रयोग का उपयोग कर xsd से स्वत: जेनरेट किया गया है।.NET में JSON enum के deserialization को अनुकूलित करने के लिए कैसे?

[DataContract] 
    public enum Foo 
    { 
     [EnumMember(Value = "bar")] 
     Bar = 1, 

     [EnumMember(Value = "baz")] 
     Baz = 2 
    } 

    [DataContract] 
    public class UNameIt 
    { 
     [DataMember(Name = "id")] 
     public long Id { get; private set; } 

     [DataMember(Name = "name")] 
     public string Name { get; private set; } 

     [DataMember(Name = "foo")] 
     public Foo Foo { get; private set; } 
    } 

निम्नलिखित एक इकाई परीक्षण है कि UNameIt वर्ग के लिए एक नमूना JSON दस्तावेज़ deserialise करने का प्रयास करता है।

[TestClass] 
    public class JsonSerializer_Fixture 
    { 
     public const string JsonData = @"{ ""id"":123456, 
              ""name"":""John Doe"", 
              ""foo"":""Bar""}"; 

     [TestMethod] 
     public void DataObjectSimpleParseTest() 
     { 
      DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(UNameIt)); 

      MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(JsonData)); 
      UNameIt dataObject = serializer.ReadObject(ms) as UNameIt; 

      Assert.IsNotNull(dataObject); 
      Assert.AreEqual(123456, dataObject.Id); 
      Assert.AreEqual(Foo.Baz, dataObject.Foo); 
     } 
    } 

दुर्भाग्य से, परीक्षण निम्नलिखित कारण बताए विफल रहता है:

System.Runtime.Serialization.SerializationException: प्रकार MyNamespace.Units.UNameIt की वस्तु deserializing एक त्रुटि हुई। मान 'बार' को 'Int64' प्रकार के रूप में पार्स नहीं किया जा सकता है।

यदि मैं एनम के लिए स्ट्रिंग विनिर्देश को प्रतिस्थापित करने के लिए अपने JSON स्ट्रिंग को अद्यतन करता हूं तो परीक्षण पास होगा।

public const string JsonData = @"{ ""id"":123456, 
            ""name"":""John Doe"", 
            ""foo"":""1""}"; 

मैं परिवर्तन आपूर्ति JSON तो मैं यह पता लगाने की कैसे क्रमबद्धता पर शायद स्ट्रिंग Enum प्रतिनिधित्व कन्वर्ट करने के लिए लचीलापन नहीं है। आदर्श रूप से, मैं अपनी ऑटोगनेरेट क्लास को बदलने के बिना इसे सुविधाजनक बनाना चाहता हूं क्योंकि एक बार जब मैं कक्षा को फिर से उत्पन्न करता हूं तो मैं अपने परिवर्तनों को खो देता हूं।

मुझे आश्चर्य है कि क्या DataContractJsonSerializer को कस्टम हैंडल गणनाओं में विस्तार करना संभव होगा? या शायद ऐसा करने का बेहतर तरीका है?

+0

क्या आपने कक्षा UNameIt की सेट विधि पर 'निजी' संशोधक को हटाने का प्रयास किया है? और अपने परीक्षण लेखन "बार" लोअरकेस को आजमाएं ... –

+0

यह डब्ल्यूसीएफ डेटा अनुबंधों में एक्सपोज़ एनम्स से बचने के लिए अनुशंसा की जाती है क्योंकि वे सूक्ष्म पिछड़ा संगत समस्याओं का निर्माण करते हैं। Http://stackoverflow.com/a/788281/52277 –

+0

[DataContractJsonSerializer और Enums] के संभावित डुप्लिकेट देखें (http://stackoverflow.com/questions/794838/datacontractjsonserializer-and-enums) – nawfal

उत्तर

6

यह व्यवहार डिज़ाइन द्वारा है। यहाँ Enumerations and JSON paragraph on MSDN से एक उद्धरण है:

गणन सदस्य मान JSON, जो कैसे वे डेटा अनुबंध है, जहां वे सदस्य के नाम के रूप में शामिल कर रहे हैं में इलाज कर रहे हैं से अलग है में संख्या के रूप में माना जाता है।

इसके अलावा DataContractJsonSerializer स्वचालित रूप से सभी enumerations को क्रमानुसार जाएगा, ताकि EnumMemberAttribute वास्तव में नजरअंदाज कर दिया है।

वर्कअराउंड पर, this answer on SO पर एक नज़र डालें।

0

इस काम है:

var ret = new JavaScriptSerializer().Deserialize<tblGridProjects>(retApi.Item2); 

लेकिन आप datamembers विशेषताओं का उपयोग नहीं कर सकते, तो गुण नाम नहीं बदल सकते। आपको जेसन भेजकर संपत्ति का नाम सेट करना होगा।

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