我的数据实体包含一个字典,但 XmlSerializer 不支持开箱即用的字典。所以我决定使用DataContractSerializer。问题是我无法让它按照我需要的方式运行。
我从以下代码开始:
public static string SerializeObject<T>(T serialisable)
{
var serializer = new DataContractSerializer(serialisable.GetType());
using (var writer = new StringWriter())
using (var stm = new XmlTextWriter(writer))
{
serializer.WriteObject(stm, serialisable);
return writer.ToString();
}
}
它似乎工作正常,直到我注意到如果我将"\r"放在字符串中,它不会被序列化为 XML 实体。根据我使用 XmlSerializer 的经验,我知道我可以使用 NewLineHandling = NewLineHandling.Entitize 设置 XmlWriterSettings。所以我将我的代码转换为以下内容:
public static string SerializeObject<T>(T serialisable)
{
var serializer = new DataContractSerializer(serialisable.GetType());
using (var writer = new StringWriter())
{
using (var stm = XmlWriter.Create(writer,
new XmlWriterSettings()
{
NewLineHandling = NewLineHandling.Entitize
}))
{
serializer.WriteObject(stm, serialisable);
return writer.ToString();
}
}
}
现在的问题是我得到一个空字符串。没有例外,什么都没有 - 只是一个空字符串。stm 变量包含 XmlWellFormedWriter。也许DataContractSerializer不支持它?
然后我尝试强制执行 XmlTextWriter,如下所示:
public static string SerializeObject<T>(T serialisable)
{
var serializer = new DataContractSerializer(serialisable.GetType());
using (var writer = new StringWriter())
using (var stm = XmlWriter.Create(new XmlTextWriter(writer),
new XmlWriterSettings()
{
NewLineHandling = NewLineHandling.Entitize
}))
{
serializer.WriteObject(stm, serialisable);
return writer.ToString();
}
}
这让我回到了我开始的地方 - 我得到了 XML 字符串,但同样"\r"字符串没有转换为实体。
如何使 DataContractSerializer 实体化换行符并以字符串形式返回 XML?
我知道这是一个非常古老的线程,但我偶然发现了它寻找答案,并认为我会回答我发现的。
未实体化的原因是因为它们位于文本节点值中。序列化程序将仅当 个字符位于属性中时,才会对其进行实体化。
以下是我发现在每个 NewLineHandling 值中都会发生的情况
文本节点
NewLineHandling.Replace (Default)
r n rn all go to rn
t remains as t
NewLineHandling.Entitize
rn goes to &#D;
n remains as n
r goes to &#D;
t remains as t
NewLineHandling.None
r remains r
rn remains n
rn remains rn
t remains as t
属性
NewLineHandling.Replace (Default)
rn goes to &#D;&#A;
n goes to &#A;
r goes to &#D;
t remains 	
NewLineHandling.Entitize
rn goes to &#D;&#A;
n goes to &#A;
r goes to &#D;
t remains 	
NewLineHandling.None
r remains r
rn remains as n
rn remains as rn
t remains as t
似乎,问题主要是因为处理 XmlWriter 的工作方式 - 如果我使用 XmlWriter.Create 创建它,它在关闭之前不会刷新,因此 StringWriter 是空的。奇怪的是 - 如果我使用新的 XmlTextWriter 创建它,它会以某种方式将其内容刷新到 StringWriter,所以我的初始方法工作得很好。
这次我只需要重新排列一行代码:
public static string SerializeObject<T>(T serialisable)
{
var serializer = new DataContractSerializer(serialisable.GetType());
using (var writer = new StringWriter())
{
using (var stm = XmlWriter.Create(writer,
new XmlWriterSettings()
{
NewLineHandling = NewLineHandling.Entitize,
Encoding = UTF8Encoding.UTF8
}))
{
serializer.WriteObject(stm, serialisable);
// <- previously writer.ToString() was here and I got an empty string
}
return writer.ToString();
}
}
现在 "\r" 字符被正确编码为 
,但 "" 没有。编码仍然是 utf-16,尽管我将其设置为 UTF8。我想,这是另一个问题。