2009-07-24 17 views
9

C# içinde bir kılavuz yazan bir yapıda var. Bu sınıfın bir örneğini içeren bir nesneyi serileştirmek için DataContractJsonSerializer kullanıyorum. Doğrudan bir guid kullandığımda, düz bir dize olarak serileştirildi, ancak şimdi bir isim/değer çifti olarak serileştirildi.DataContractJsonSerializer bir nesneyi bir dizge olarak serileştirebilir?

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))); 
    } 

Ve Test koşucu çıktı:

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"}" 
    -----------^ 

Ben düz bir dize olarak benim struct serialize ve benim test geçmesi yapmak nasıl İşte bir sorunu gösteren bir NUnit testi ve destekleyici kodu?

cevap

10

Bu durumda, gerçekten JSON istemiyorsanız, bir dize temsili istiyorsunuz gibi görünüyor.

interface IStringSerialized 
{ 
    String GetString(); 
} 

sizin ID türüne bu arabirimini uygular (ve benzer gereksinimleri olan tüm diğer türleri): Bu durumda böyle bir arabirim oluşturur.

[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(); 
    } 
} 

Sonra bu özel durumları işlemek için seri yöntemini değiştirin:

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

Sorunu açıklığa kavuşturmak için bazı karmaşıklıkları ihmal ettim, ancak gerçek uygulamada bu, bir List Listesindeki bir nesne içeriyor. Gerçek kodun ["guid1", "guid2"], [{"_value": "guid1"}, {"_value": "guid2"}] üretmesini istiyorum. Maalesef, bu yaklaşım benim için çalışmayacak. Yine de fikir için teşekkürler! –

+7

Herhangi bir ANSI olmayan karakterleri bozacağından, Varsayılan kodlamayı kullanmayın. Şu anda Cep telefonu push mesajları ile uğraşıyorum. Kodunuz diğer dillerle ilgilenebilmelidir. Bunun yerine UTF8 kullanın. dönüş Kodlama .UTF8.GetString (ms.ToArray()); – midspace

0

anahtar, değer kabartmak sorunu önleyecektir JavaScriptSerializer Class kullanmayı deneyin.

+1

ancak sonra seri hale getirmek istediğiniz nesneye sahip olduğunuz tüm veri sözleşmeleri özniteliklerini kaybedeceksiniz (emitdefaultvalue gibi) – silver

İlgili konular