如何使DataContractJsonSerializer将对象序列化为字符串?

时间:2009-07-24 14:59:46

标签: c# .net json datacontractserializer

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

如何将我的结构序列化为纯字符串并使我的测试通过?

2 个答案:

答案 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类,它可以防止键值膨胀问题。