我在C#中有一个包含guid的结构。我正在使用DataContractJsonSerializer来序列化包含该类实例的对象。当我直接使用guid时,它被序列化为纯字符串,但现在它被序列化为名称/值对。这是一个NUnit测试和支持代码,用于演示此问题:
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"}"
-----------^
如何将我的结构序列化为纯字符串并使我的测试通过?
答案 0 :(得分:10)
在这种情况下,看起来你真的不想要JSON,你想要一个字符串表示。在这种情况下,我会创建一个这样的界面:
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());
}
}
答案 1 :(得分:1)
尝试使用JavaScriptSerializer类,它可以防止键值膨胀问题。