2009-07-24 6 views
9

मेरे पास सी # में एक संरचना है जो एक गाइड को लपेटती है। मैं उस वर्ग के उदाहरण वाले ऑब्जेक्ट को क्रमबद्ध करने के लिए DataContractJsonSerializer का उपयोग कर रहा हूं। जब मैं सीधे एक गाइड का उपयोग कर रहा था, तो इसे एक सादे स्ट्रिंग के रूप में क्रमबद्ध किया गया था, लेकिन अब इसे नाम/मूल्य जोड़ी के रूप में क्रमबद्ध किया गया है।मैं DataContractJsonSerializer को किसी ऑब्जेक्ट को स्ट्रिंग के रूप में क्रमबद्ध कैसे कर सकता हूं?

private static string ToJson<T>(T data) 
    { 
     DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof (T)); 

     using (MemoryStream ms = new MemoryStream()) 
     { 
      serializer.WriteObject(ms, data); 
      return Encoding.Default.GetString(ms.ToArray()); 
     } 
    } 

    [Serializable] 
    private class ID 
    { 
     private Guid _value; 

     public static explicit operator ID(Guid id) 
     { 
      return new ID { _value = id }; 
     } 

     public static explicit operator Guid(ID id) 
     { 
      return id._value; 
     } 
    } 

    [Test] 
    public void IDShouldSerializeLikeGuid() 
    { 
     Guid guid = Guid.NewGuid(); 
     ID id = (ID) guid; 
     Assert.That(ToJson(id), Is.EqualTo(ToJson(guid))); 
    } 

और परीक्षण धावक उत्पादन:

NUnit.Framework.AssertionException: Expected string length 38 but was 49. Strings differ at index 0. 
    Expected: ""7511fb9f-3515-4e95-9a04-06580753527d"" 
    But was: "{"_value":"7511fb9f-3515-4e95-9a04-06580753527d"}" 
    -----------^ 

मैं कैसे एक सादे स्ट्रिंग के रूप में मेरी struct को क्रमानुसार और मेरी परीक्षा उत्तीर्ण कर सकता हूँ यहाँ एक NUnit परीक्षण और समर्थन कोड है कि समस्या को दर्शाता है है?

उत्तर

10

इस मामले में ऐसा लगता है कि आप वास्तव में जेएसओएन नहीं चाहते हैं, तो आप एक स्ट्रिंग प्रतिनिधित्व चाहते हैं।

interface IStringSerialized 
{ 
    String GetString(); 
} 

अपने ID प्रकार पर इस इंटरफेस को लागू करें (और इसी तरह की आवश्यकताओं है कि अन्य सभी प्रकार के): उस मामले में मैं इस तरह एक अंतरफलक पैदा करेगा।

[Serializable] 
class ID : IStringSerialized 
{ 
    private Guid _value; 

    public static explicit operator ID(Guid id) 
    { 
     return new ID { _value = id }; 
    } 

    public static explicit operator Guid(ID id) 
    { 
     return id._value; 
    } 

    public string GetString() 
    { 
     return this._value.ToString(); 
    } 
} 

फिर इन विशेष मामलों को संभालने के लिए अपने क्रमांकन विधि को संशोधित:

private static string ToJson<T>(T data) 
{ 
    IStringSerialized s = data as IStringSerialized; 

    if (s != null) 
     return s.GetString(); 

    DataContractJsonSerializer serializer 
       = new DataContractJsonSerializer(typeof(T)); 

    using (MemoryStream ms = new MemoryStream()) 
    { 
     serializer.WriteObject(ms, data); 
     return Encoding.Default.GetString(ms.ToArray()); 
    } 
} 
+0

मैंने समस्या को स्पष्ट करने के लिए कुछ जटिलता छोड़ी, लेकिन असली एप्लिकेशन में यह एक ऐसी ऑब्जेक्ट के संदर्भ में है जिसमें इसकी सूची है। मैं असली कोड ["guid1", "guid2"] उत्पन्न करना चाहता हूं, [{"_value": "guid1"}, {"_value": "guid2"}]। तो दुर्भाग्यवश, वह दृष्टिकोण मेरे लिए काम नहीं करेगा। हालांकि विचार के लिए धन्यवाद! –

+7

डिफ़ॉल्ट एन्कोडिंग का उपयोग न करें, क्योंकि यह किसी भी गैर-एएनएसआई वर्णों को दूषित कर देगा। मैं वर्तमान में मोबाइल फोन पुश संदेशों से निपट रहा हूं। आपका कोड अन्य भाषाओं से निपटने में सक्षम होना चाहिए। इसके बजाय यूटीएफ 8 का प्रयोग करें। वापसी एन्कोडिंग .UTF8.GetString (ms.ToArray()); – midspace

0

JavaScriptSerializer कक्षा का उपयोग कर इसे कुंजी, मूल्य ब्लोट मुद्दा नहीं कर पाएगा का प्रयास करें।

+1

लेकिन फिर आप उन सभी डेटा अनुबंधों को नुकसान पहुंचाएंगे जो आपके पास हैं जो आप ऑब्जेक्ट करना चाहते हैं (जैसे emitdefaultvalue) – silver