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

C# 如何使DataContractJsonSerializer将对象序列化为字符串?,c#,.net,json,datacontractserializer,C#,.net,Json,Datacontractserializer,我有一个C#结构,它包装了一个guid。我正在使用DataContractJsonSerializer序列化包含该类实例的对象。当我直接使用guid时,它被序列化为普通字符串,但现在它被序列化为名称/值对。下面是一个NUnit测试和支持代码,演示了该问题: private static string ToJson<T>(T data) { DataContractJsonSerializer serializer = new DataContractJ

我有一个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)));
    }

如何将结构序列化为普通字符串并通过测试?

在这种情况下,您似乎并不真正需要JSON,而是需要字符串表示。在这种情况下,我将创建如下界面:

interface IStringSerialized
{
    String GetString();
}
在您的
ID
类型(以及具有类似要求的所有其他类型)上实现此接口

然后修改序列化方法以处理以下特殊情况:

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());
    }
}
私有静态字符串ToJson(T数据)
{
IStringSerialized s=数据为IStringSerialized;
如果(s!=null)
返回s.GetString();
DataContractJsonSerializer序列化程序
=新的DataContractJsonSerializer(类型(T));
使用(MemoryStream ms=new MemoryStream())
{
serializer.WriteObject(ms,data);
返回Encoding.Default.GetString(ms.ToArray());
}
}

尝试使用该类,它将防止出现键、值膨胀问题。

我省略了一些复杂性以澄清问题,但在实际应用程序中,这是在包含对象的上下文中,其中包含一个列表。我希望真正的代码生成[“guid1”,“guid2”],而不是[{u值”:“guid1”},{u值”:“guid2”}]。不幸的是,这种方法对我不起作用。谢谢你的主意!不要使用默认编码,因为它会损坏任何非ANSI字符。我目前正在处理手机推送消息。您的代码应该能够处理其他语言。改用UTF8。返回Encoding.UTF8.GetString(ms.ToArray());但是,您将丢失您想要序列化的对象中的所有数据协定属性(如emitdefaultvalue)
[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());
    }
}