json - 使用 IXmlSerializable 对对象进行 WCF JSON 序列化

标签 json wcf serialization

我有结构 IntEx - 简而言之,它扩展了正常的 Int32 和已处理的操作。它看起来像这样:

[Serializable]
public struct IntEx
{
    private int internalValue;

    private IntEx(int value)
    {
        internalValue = value;
    }

    public static implicit operator int(IntEx value)
    {
        return value.internalValue;
    }

    public static implicit operator IntEx(int value)
    {
        return new IntEx(value);
    }
}

如果我们通过 WCF 发送这个结构,它会使用 JSON 进行序列化,并且输出会“看起来很漂亮”。就像我们将使用下面的示例代码一样:

DataContractJsonSerializer jsonSerializer = new DataContractJsonSerializer(typeof(TestClass));

using (MemoryStream stream = new MemoryStream())
{
    jsonSerializer.WriteObject(stream, testClass);

    string serializedString = Encoding.UTF8.GetString(stream.GetBuffer());

    Console.WriteLine("JSON: {0}", serializedString);
}

public class TestClass
{
    public int I1 { get; set; }

    public IntEx I2 { get; set; }
}

输出看起来像这样
JSON: {"I1":11,"I2":{"internalValue":22}}

客户端和其他“第三方”程序使用这种格式(带有 internalValue )。

使用 IntEx 在我的应用程序中被广泛使用。其中一个对象被序列化为 XML(某种设置)。该对象使用 IntEx 作为类型。
所以我必须实现 IXmlSerializable 来构造 IntEx,因为没有这个属性会像空节点一样被序列化
XML: <TestClass><I1>11</I1><I2 /></TestClass>

如果我将 IntEx 更改为使用 IXmlSerializable

[Serializable]
public struct IntEx : IXmlSerializable
{
    private int internalValue;

    private IntEx(int value)
    {
        internalValue = value;
    }

    public static implicit operator int(IntEx value)
    {
        return value.internalValue;
    }

    public static implicit operator IntEx(int value)
    {
        return new IntEx(value);
    }

    System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema()
    {
        return null;
    }

    void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
    {
        throw new NotImplementedException();
    }

    void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
    {
        writer.WriteValue(internalValue);
    }
}

XML 输出看起来不错
XML: <TestClass><I1>11</I1><I2>22</I2></TestClass>

但是我所有的服务都崩溃了,因为现在 JSON 看起来像这样:
JSON: {"I1":11,"I2":"<IntEx xmlns=\"http:\/\/schemas.datacontract.org\/2004\/07\/TestJSONSerialization\">22<\/IntEx>"}

我读到,如果您使用 IXmlSerializable,JSON 序列化“认为”我负责序列化,所以把这个对象留给我......但是我怎样才能改回“原始”序列化。

所以现在我处于死胡同......我需要像以前一样的 JSON 输出,但我还需要一些如何强制在两个条件下将设置写入 XML:
  • internalValue 应该保持私有(private) - 它不应该可以使用某些公共(public)属性
  • 访问
  • 我不想重写一堆代码来更改(对 JSON 的属性使用装箱)或更改所有可能的属性或可以保存到 XML 文件的类。

  • 那么谁能给我一些线索,我该如何解决这个问题? :/

    最佳答案

    您可以将 DataContractJsonSerializer 与 IDataContractSurrogate 一起使用。使用 IDataContractSurrogate 将“IntEx”转换为“IntExJson”,而“IntExJson”不需要继承自 IXmlSerializable。

    IDataContractSurrogate 可用于从对象中删除某些特征,并转换为相似的对象。然后使用:

    public DataContractJsonSerializer(Type type, IEnumerable<Type> knownTypes, int maxItemsInObjectGraph, bool ignoreExtensionDataObject, IDataContractSurrogate dataContractSurrogate, bool alwaysEmitTypeInformation);
    

    将对象序列化为 json。反序列化是相同的。

    关于json - 使用 IXmlSerializable 对对象进行 WCF JSON 序列化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14891226/

    相关文章:

    json - Jersey 2.0 和 Moxy 内部服务器错误但没有服务器日志

    ios - NSURLSession 超时

    读取 Json 后 iOS PickerView 为空

    c# - 如何使用 WCF 解决将共享相同数据源但将为每个客户端具有单独实例/ session 的服务器-客户端系统

    c# - 两种方式通信的服务器/客户端架构?

    c# - 在 SerializationInfo 中获取具有值的成员

    java - 序列化外部库

    java - 来自 json 的 Proto 反序列化将在新字段或未知枚举值上失败

    c# - 在线程上启动多个服务

    c# - MongoDb 自定义集合序列化器