DataContractSerializer 不反序列化引用
我正在使用 .NET 3.5 中的 DataContractSerializer 来反序列化 xml。该 xml 之前是从实体模型中的一组相关实体序列化的,由实体框架 3.5 支持。有很多引用,并且 xml 广泛包含每个引用实体的成员和键的所有值。
顶级实体可以很好地反序列化,但引用的实体却不能。
这是我用来序列化和反序列化的代码:
public static T DCDeserializeXml<T>(string xml)
{
MemoryStream memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(xml));
using (
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(memoryStream, Encoding.Unicode,
new XmlDictionaryReaderQuotas(), null))
{
DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(T), null, Int32.MaxValue, false, true, null);
return (T)dataContractSerializer.ReadObject(reader, true);
}
}
public static string DCSerializeToXml<T>(T obj)
{
DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(T), null, Int32.MaxValue, false, true, null);
String text;
using (MemoryStream memoryStream = new MemoryStream())
{
dataContractSerializer.WriteObject(memoryStream, obj);
byte[] data = new byte[memoryStream.Length];
Array.Copy(memoryStream.GetBuffer(), data, data.Length);
text = Encoding.UTF8.GetString(data);
}
return text;
}
这是 XML 的片段:
<?xml version="1.0" encoding="utf-8"?>
<Assets>
<Asset z:Id="i1" xmlns="http://schemas.datacontract.org/2004/07/XLayer" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<EntityKey z:Id="i2" xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses" xmlns:a="http://schemas.datacontract.org/2004/07/System.Data">
<a:EntityContainerName>XModelContainer</a:EntityContainerName>
<a:EntityKeyValues>
<a:EntityKeyMember>
<a:Key>AssetGUID</a:Key>
<a:Value i:type="z:guid">7424f615-43db-4834-b15a-5befa46bfd55</a:Value>
</a:EntityKeyMember></a:EntityKeyValues>
<a:EntitySetName>AssetSet</a:EntitySetName>
</EntityKey>
<AssetGUID>7424f615-43db-4834-b15a-5befa46bfd55</AssetGUID>
<Created>2011-06-23T13:34:12.893</Created>
<Description/>
<npAudioInfoReference xmlns:a="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses">
<a:EntityKey i:nil="true" xmlns:b="http://schemas.datacontract.org/2004/07/System.Data"/>
</npAudioInfoReference>
<npCampaigns/>
<npCategory z:Id="i3">
<EntityKey z:Id="i4" xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses" xmlns:a="http://schemas.datacontract.org/2004/07/System.Data">
<a:EntityContainerName>XModelContainer</a:EntityContainerName>
<a:EntityKeyValues>
<a:EntityKeyMember>
<a:Key>CategoryID</a:Key>
<a:Value i:type="b:int" xmlns:b="http://www.w3.org/2001/XMLSchema">1</a:Value>
</a:EntityKeyMember>
</a:EntityKeyValues>
<a:EntitySetName>AssetCategorySet</a:EntitySetName>
</EntityKey>
<AM_DataDocumentTypes/>
<CategoryID>1</CategoryID>
<CategoryName>Generic Content</CategoryName>
<npAssets>
我已经在这个问题上坚持了几天,并且已经用尽了我能找到的所有搜索结果。使用这种技术显然可以避免为模型中的每种实体类型(其中有 143 种)手工编写大量代码。
因此重申一下,顶层实体可以很好地反序列化,但引用的实体却不能。因此,资产已加载,并且 Asset.AssetCategory(以及更多)在反序列化后解析为 null,我需要帮助来修复它,以便实例化所有引用。请问有人吗?
I am using the DataContractSerializer in .NET 3.5 to deserialize xml. The xml was previously serialized from a group of related entities in an entity model, backed by the entity framework 3.5. There are many references, and the xml extensively contains all the values of the members and keys of each referenced entity.
The top level entity deserializes fine, but the referenced entities do not.
This is the code I'm using to serialize and deserialize:
public static T DCDeserializeXml<T>(string xml)
{
MemoryStream memoryStream = new MemoryStream(Encoding.Unicode.GetBytes(xml));
using (
XmlDictionaryReader reader = XmlDictionaryReader.CreateTextReader(memoryStream, Encoding.Unicode,
new XmlDictionaryReaderQuotas(), null))
{
DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(T), null, Int32.MaxValue, false, true, null);
return (T)dataContractSerializer.ReadObject(reader, true);
}
}
public static string DCSerializeToXml<T>(T obj)
{
DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(T), null, Int32.MaxValue, false, true, null);
String text;
using (MemoryStream memoryStream = new MemoryStream())
{
dataContractSerializer.WriteObject(memoryStream, obj);
byte[] data = new byte[memoryStream.Length];
Array.Copy(memoryStream.GetBuffer(), data, data.Length);
text = Encoding.UTF8.GetString(data);
}
return text;
}
This is a snippet of the XML:
<?xml version="1.0" encoding="utf-8"?>
<Assets>
<Asset z:Id="i1" xmlns="http://schemas.datacontract.org/2004/07/XLayer" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<EntityKey z:Id="i2" xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses" xmlns:a="http://schemas.datacontract.org/2004/07/System.Data">
<a:EntityContainerName>XModelContainer</a:EntityContainerName>
<a:EntityKeyValues>
<a:EntityKeyMember>
<a:Key>AssetGUID</a:Key>
<a:Value i:type="z:guid">7424f615-43db-4834-b15a-5befa46bfd55</a:Value>
</a:EntityKeyMember></a:EntityKeyValues>
<a:EntitySetName>AssetSet</a:EntitySetName>
</EntityKey>
<AssetGUID>7424f615-43db-4834-b15a-5befa46bfd55</AssetGUID>
<Created>2011-06-23T13:34:12.893</Created>
<Description/>
<npAudioInfoReference xmlns:a="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses">
<a:EntityKey i:nil="true" xmlns:b="http://schemas.datacontract.org/2004/07/System.Data"/>
</npAudioInfoReference>
<npCampaigns/>
<npCategory z:Id="i3">
<EntityKey z:Id="i4" xmlns="http://schemas.datacontract.org/2004/07/System.Data.Objects.DataClasses" xmlns:a="http://schemas.datacontract.org/2004/07/System.Data">
<a:EntityContainerName>XModelContainer</a:EntityContainerName>
<a:EntityKeyValues>
<a:EntityKeyMember>
<a:Key>CategoryID</a:Key>
<a:Value i:type="b:int" xmlns:b="http://www.w3.org/2001/XMLSchema">1</a:Value>
</a:EntityKeyMember>
</a:EntityKeyValues>
<a:EntitySetName>AssetCategorySet</a:EntitySetName>
</EntityKey>
<AM_DataDocumentTypes/>
<CategoryID>1</CategoryID>
<CategoryName>Generic Content</CategoryName>
<npAssets>
I've been stuck on this for a couple days and I've exhausted all search results that I could find. Using this technique can clearly avoid hand writing tons of code for each entity type in our model, of which there are 143.
So to reiterate, the top level entity deserializes fine, but the referenced entities do not. So Asset is loaded and Asset.AssetCategory (among many more) resolves to null after deserialization, and I need help to fix it so all references get instantiated. Please, anyone?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
有时您需要告诉序列化器其他“已知类型”。
请参阅 MSDN 文档:
http://msdn.microsoft.com/en-us/ library/ms730167.aspx
您可以通过配置、属性或 DataContractSerializer 上的参数/属性来执行此操作。
文档链接到此处有一个完整的示例:
http://msdn.microsoft。 com/en-us/library/ms751512.aspx
Sometimes you need to tell the serializer about other "Known Types".
See the MSDN documentation:
http://msdn.microsoft.com/en-us/library/ms730167.aspx
You can do this through the config, through attributes, or through parameters/a property on DataContractSerializer.
There is a full example the documentation links to here:
http://msdn.microsoft.com/en-us/library/ms751512.aspx