我有结构 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:
那么谁能给我一些线索,我该如何解决这个问题? :/
最佳答案
您可以将 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/