我有结构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序列化“认为”我负责序列化,所以把这个对象留给我......但是我怎样才能改回“原始”序列化。
所以现在我处于deadend ...我需要JSON输出看起来像以前一样,但我还需要一些强制写入设置为XML的两个条件:
那么有人能给我一些线索,我该如何解决这个问题? :/
答案 0 :(得分:0)
您可以将DataContractJsonSerializer与IDataContractSurrogate一起使用。使用IDataContractSurrogate将“IntEx”转换为“IntExJson”,而“IntExJson”不需要从IXmlSerializable继承。
IDataContractSurrogate可用于从对象中删除某些功能,并转换为类似的对象。然后使用:
public DataContractJsonSerializer(Type type, IEnumerable<Type> knownTypes, int maxItemsInObjectGraph, bool ignoreExtensionDataObject, IDataContractSurrogate dataContractSurrogate, bool alwaysEmitTypeInformation);
将对象序列化为json。反序列化是一样的。