- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
以下程序尝试从层次结构中序列化然后反序列化通用类型的对象,失败并出现代码下方列出的错误。
如何让它发挥作用?
[DataContract]
[KnownType(nameof(GetKnownTypes))]
public abstract class Base<T>
{
private static Type[] GetKnownTypes()
{
return new[] {typeof(DerivedA<T>)};
}
}
[DataContract]
public class DerivedA<T> : Base<T>
{
[DataMember]
public T Foo { get; set; }
}
class Program
{
private static void Main()
{
// This works fine
var foo = new DerivedA<string> { Foo = "foo" };
var xml = Serialize(foo);
var foo2 = Deserialize<DerivedA<string>>(xml);
Console.WriteLine(foo2.Foo); // foo
// This throws the exception below
// (from serializer.ReadObject() in the Deserialize method)
var foo3 = Deserialize<Base<string>>(xml);
}
private static string Serialize<T>(T o)
{
string result = null;
var serializer = new DataContractSerializer(o.GetType());
using (var stream = new MemoryStream())
{
serializer.WriteObject(stream, o);
stream.Position = 0;
var reader = new StreamReader(stream);
result = reader.ReadToEnd();
}
return result;
}
private static T Deserialize<T>(string xml)
{
var result = default(T);
var serializer = new DataContractSerializer(typeof(T));
using (var stream = new MemoryStream())
{
var writer = new StreamWriter(stream);
writer.Write(xml);
writer.Flush();
stream.Position = 0;
result = (T)serializer.ReadObject(stream);
}
return result;
}
}
Unhandled Exception: System.Runtime.Serialization.SerializationException: Error in line 1 position 139. Expecting element 'BaseOfstring' from namespace 'http://schemas.datacontract.org/2004/07/ConsoleApplication7'.. Encountered 'Element' with name 'DerivedAOfstring', namespace 'http://schemas.datacontract.org/2004/07/ConsoleApplication7'.
at System.Runtime.Serialization.DataContractSerializer.InternalReadObject(XmlReaderDelegator xmlReader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.XmlObjectSerializer.ReadObjectHandleExceptions(XmlReaderDelegator reader, Boolean verifyObjectName, DataContractResolver dataContractResolver)
at System.Runtime.Serialization.XmlObjectSerializer.ReadObject(XmlDictionaryReader reader)
at System.Runtime.Serialization.XmlObjectSerializer.ReadObject(Stream stream)
at ConsoleApplication7.Program.Deserialize[T](String xml) in c:\users\tly01\documents\visual studio 2015\Projects\ConsoleApplication7\ConsoleApplication7\Program.cs:line 65
消息中最有趣的部分非常清楚出了什么问题:
Expecting element 'BaseOfstring' from namespace . Encountered 'Element' with name 'DerivedAOfstring', namespace .
果然,上面main方法中的xml
是这样的(加了空格):
<DerivedAOfstring
xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication7"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Foo>foo</Foo>
</DerivedAOfstring>
我意识到我必须以某种方式让序列化程序知道我的类型层次结构,但我已经尝试了上面列表中 KnownType
属性的许多不同变体,但没有一个有卓有成效。使这项工作正常进行的正确方法是什么?
最佳答案
您需要做的是始终使用 DataContractSerializer
序列化和反序列化您的派生类型。 constructed using identical Type
arguments .您正在尝试使用 DerivedA<T>
用于序列化和 Base<T>
用于反序列化。这种不一致会导致您看到的问题。
发生这种情况的原因如下。通常,有两种常规方法可以将多态类型序列化为 XML:
可以更改元素名称以表示派生类型。与 XmlSerializer
, 这是通过 [XmlElement(elementName, subType)]
支持的属性等等。
元素可以使用标准 {http://www.w3.org/2001/XMLSchema}type
显式断言其类型属性,通常缩写为 xsi:type
. XmlSerializer
通过 [XmlInclude(subType)]
支持此机制属性。 DataContractSerializer
通过 KnownTypeAttribute
支持这一点.
事实DataContractSerializer
使用第二种机制是导致您的问题的原因。当您序列化派生类的实例时,派生类协定名称将作为根元素名称发出。但是,当您将派生类的实例作为其基类的实例 序列化时,基类协定名称将与附加的 xsi:type
一起使用。 .要看到这一点,请按如下方式重构您的代码:
private static string Serialize<T>(T o)
{
return Serialize(o, null);
}
private static string Serialize<T>(T o, DataContractSerializer serializer)
{
string result = null;
serializer = serializer ?? new DataContractSerializer(o.GetType());
using (var stream = new MemoryStream())
{
serializer.WriteObject(stream, o);
stream.Position = 0;
var reader = new StreamReader(stream);
result = reader.ReadToEnd();
}
return result;
}
现在如果你这样做:
var xml = Serialize(foo);
Debug.WriteLine(xml);
你会看到
<DerivedAOfstring
xmlns="http://schemas.datacontract.org/2004/07/Question37284138" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Foo>foo</Foo>
</DerivedAOfstring>
但如果你这样做
var baseXml = Serialize(foo, new DataContractSerializer(typeof(Base<string>)));
Debug.WriteLine(baseXml);
你会看到:
<BaseOfstring i:type="DerivedAOfstring"
xmlns="http://schemas.datacontract.org/2004/07/Question37284138" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<Foo>foo</Foo>
</BaseOfstring>
注意到区别了吗?这意味着前者不能使用 DataContractSerializer(typeof(Base<string>))
反序列化。 .但是如果你序列化使用 DataContractSerializer(typeof(Base<string>))
然后反序列化将起作用 - 并正确构造 DerivedA<string>
的实例感谢 xsi:type
的存在属性。
关于c# - 通用类型层次结构的 DataContractSerialization,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37284138/
我目前正在尝试基于哈希表构建字典。逻辑是:有一个名为 HashTable 的结构,其中包含以下内容: HashFunc HashFunc; PrintFunc PrintEntry; CompareF
如果我有一个指向结构/对象的指针,并且该结构/对象包含另外两个指向其他对象的指针,并且我想删除“包含这两个指针的对象而不破坏它所持有的指针”——我该怎么做这样做吗? 指向对象 A 的指针(包含指向对象
像这样的代码 package main import "fmt" type Hello struct { ID int Raw string } type World []*Hell
我有一个采用以下格式的 CSV: Module, Topic, Sub-topic 它需要能够导入到具有以下格式的 MySQL 数据库中: CREATE TABLE `modules` ( `id
通常我使用类似的东西 copy((uint8_t*)&POD, (uint8_t*)(&POD + 1 ), back_inserter(rawData)); copy((uint8_t*)&PODV
错误 : 联合只能在具有兼容列类型的表上执行。 结构(层:字符串,skyward_number:字符串,skyward_points:字符串)<> 结构(skyward_number:字符串,层:字符
我有一个指向结构的指针数组,我正在尝试使用它们进行 while 循环。我对如何准确初始化它并不完全有信心,但我一直这样做: Entry *newEntry = malloc(sizeof(Entry)
我正在学习 C,我的问题可能很愚蠢,但我很困惑。在这样的函数中: int afunction(somevariables) { if (someconditions)
我现在正在做一项编程作业,我并没有真正完全掌握链接,因为我们还没有涉及它。但是我觉得我需要它来做我想做的事情,因为数组还不够 我创建了一个结构,如下 struct node { float coef;
给定以下代码片段: #include #include #define MAX_SIZE 15 typedef struct{ int touchdowns; int intercepti
struct contact list[3]; int checknullarray() { for(int x=0;x<10;x++) { if(strlen(con
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: Empty “for” loop in Facebook ajax what does AJAX call
我刚刚在反射器中浏览了一个文件,并在结构构造函数中看到了这个: this = new Binder.SyntaxNodeOrToken(); 我以前从未见过该术语。有人能解释一下这个赋值在 C# 中的
我经常使用字符串常量,例如: DICT_KEY1 = 'DICT_KEY1' DICT_KEY2 = 'DICT_KEY2' ... 很多时候我不介意实际的文字是什么,只要它们是独一无二的并且对人类读
我是 C 的新手,我不明白为什么下面的代码不起作用: typedef struct{ uint8_t a; uint8_t* b; } test_struct; test_struct
您能否制作一个行为类似于内置类之一的结构,您可以在其中直接分配值而无需调用属性? 前任: RoundedDouble count; count = 5; 而不是使用 RoundedDouble cou
这是我的代码: #include typedef struct { const char *description; float value; int age; } swag
在创建嵌套列表时,我认为 R 具有对列表元素有用的命名结构。我有一个列表列表,并希望应用包含在任何列表中的每个向量的函数。 lapply这样做但随后剥离了列表的命名结构。我该怎么办 lapply嵌套列
我正在做一个用于学习目的的个人组织者,我从来没有使用过 XML,所以我不确定我的解决方案是否是最好的。这是我附带的 XML 文件的基本结构:
我是新来的 nosql概念,所以当我开始学习时 PouchDB ,我找到了这个转换表。我的困惑是,如何PouchDB如果可以说我有多个表,是否意味着我需要创建多个数据库?因为根据我在 pouchdb
我是一名优秀的程序员,十分优秀!