Типы «TypeB» и «TypeC» не записываются в файлы, потому что они не нужны - когда сериализатор сериализует или десериализует экземпляр TypeA, он знает, что тип члена «b» TypeB
, поэтому он не записывает информацию о типе. Вам тоже нужна эта информация? Поскольку вы сериализуете TypeA
и знаете, что поле b
имеет тип TypeB
, вам не нужна эта дополнительная информация в файле журнала.
Во всех сериализаторах, используемых WCF, единственным, с помощью которого вы можете «принудительно» постоянно писать тип, является сериализатор JSON - но тогда вы получите результат как JSON, а не как XML - см. Ниже.
public class StackOverflow_6666697
{
[DataContract]
public class TypeA { [DataMember] public TypeB b = new TypeB(); }
[DataContract]
public class TypeB { [DataMember] public TypeC c = new TypeC(); }
[DataContract]
public class TypeC { [DataMember] public string S1; }
public static void Test()
{
MemoryStream ms = new MemoryStream();
XmlWriterSettings ws = new XmlWriterSettings
{
Indent = true,
IndentChars = " ",
OmitXmlDeclaration = true,
Encoding = Encoding.UTF8
};
TypeA instance = new TypeA { b = new TypeB { c = new TypeC { S1 = "Hello world" } } };
XmlWriter w = XmlWriter.Create(ms, ws);
new XmlSerializer(typeof(TypeA)).Serialize(w, instance);
w.Flush();
Console.WriteLine("XmlSerializer:");
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
ms.SetLength(0);
w = XmlWriter.Create(ms, ws);
new DataContractSerializer(typeof(TypeA)).WriteObject(w, instance);
w.Flush();
Console.WriteLine("DataContractSerializer:");
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
ms.SetLength(0);
w = XmlWriter.Create(ms, ws);
new NetDataContractSerializer().WriteObject(w, instance);
w.Flush();
Console.WriteLine("NetDataContractSerializer:");
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
ms.SetLength(0);
w = JsonReaderWriterFactory.CreateJsonWriter(ms, Encoding.UTF8);
new DataContractJsonSerializer(typeof(TypeA), null, 65536, false, null, true).WriteObject(w, instance);
w.Flush();
Console.WriteLine("DataContractJsonSerializer:");
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
}
}
Другой вариант (который я действительно не советую, так как вы будете изменять логику вашей системы для ведения журнала) - это объявить поля как object
. Таким образом, поскольку объявленный тип отличается от фактического, информация о типе будет записана - см. Ниже.
public class StackOverflow_6666697
{
[DataContract]
public class TypeA { [DataMember] public object b = new TypeB(); }
[DataContract]
public class TypeB { [DataMember] public object c = new TypeC(); }
[DataContract]
public class TypeC { [DataMember] public string S1; }
public static void Test()
{
MemoryStream ms = new MemoryStream();
XmlWriterSettings ws = new XmlWriterSettings
{
Indent = true,
IndentChars = " ",
OmitXmlDeclaration = true,
Encoding = Encoding.UTF8
};
TypeA instance = new TypeA { b = new TypeB { c = new TypeC { S1 = "Hello world" } } };
XmlWriter w = XmlWriter.Create(ms, ws);
new XmlSerializer(typeof(TypeA), new Type[] { typeof(TypeB), typeof(TypeC) }).Serialize(w, instance);
w.Flush();
Console.WriteLine("XmlSerializer:");
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
ms.SetLength(0);
w = XmlWriter.Create(ms, ws);
new DataContractSerializer(typeof(TypeA), new Type[] { typeof(TypeB), typeof(TypeC) }).WriteObject(w, instance);
w.Flush();
Console.WriteLine("DataContractSerializer:");
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
ms.SetLength(0);
w = XmlWriter.Create(ms, ws);
new NetDataContractSerializer().WriteObject(w, instance);
w.Flush();
Console.WriteLine("NetDataContractSerializer:");
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
ms.SetLength(0);
w = JsonReaderWriterFactory.CreateJsonWriter(ms, Encoding.UTF8);
new DataContractJsonSerializer(typeof(TypeA), new Type[] { typeof(TypeB), typeof(TypeC) }, 65536, false, null, true).WriteObject(w, instance);
w.Flush();
Console.WriteLine("DataContractJsonSerializer:");
Console.WriteLine(Encoding.UTF8.GetString(ms.ToArray()));
}
}