.net 为什么DataContractSerializer忽略XmlWriterSettings设置?

.net 为什么DataContractSerializer忽略XmlWriterSettings设置?,.net,newline,encode,datacontractserializer,.net,Newline,Encode,Datacontractserializer,我的数据实体包含字典,但XmlSerializer不支持开箱即用。所以我决定使用DataContractSerializer。问题是我无法让它按我需要的方式运行 我从以下代码开始: public static string SerializeObject<T>(T serialisable) { var serializer = new DataContractSerializer(serialisable.GetType()); using (var writer

我的数据实体包含字典,但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();
    }
}
公共静态字符串序列化对象(T serialisable)
{
var serializer=新的DataContractSerializer(serialisable.GetType());
使用(var writer=new StringWriter())
使用(var stm=new XmlTextWriter(writer))
{
serializer.WriteObject(stm,可序列化);
返回writer.ToString();
}
}
在我注意到如果将“\r\n”放入字符串中,它不会被序列化为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();
        }
    }
}
公共静态字符串序列化对象(T serialisable)
{
var serializer=新的DataContractSerializer(serialisable.GetType());
使用(var writer=new StringWriter())
{
使用(var stm=XmlWriter.Create(writer,
新的XmlWriterSettings()
{
NewLineHandling=NewLineHandling.Entitize
}))
{
serializer.WriteObject(stm,可序列化);
返回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();
    }
}
公共静态字符串序列化对象(T serialisable)
{
var serializer=新的DataContractSerializer(serialisable.GetType());
使用(var writer=new StringWriter())
使用(var stm=XmlWriter.Create)(新建XmlTextWriter(writer),
新的XmlWriterSettings()
{
NewLineHandling=NewLineHandling.Entitize
}))
{
serializer.WriteObject(stm,可序列化);
返回writer.ToString();
}
}
这让我回到了我开始的地方-我得到了XML字符串,但“\r\n”字符串并没有转换为实体


如何使DataContractSerializer对换行符进行实体化并将XML作为字符串返回?

看来,问题主要在于如何处理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();
        }
    }
公共静态字符串序列化对象(T serialisable)
{
var serializer=新的DataContractSerializer(serialisable.GetType());
使用(var writer=new StringWriter())
{
使用(var stm=XmlWriter.Create(writer,
新的XmlWriterSettings()
{
NewLineHandling=NewLineHandling.Entitize,
编码=UTF8Encoding.UTF8
}))
{
serializer.WriteObject(stm,可序列化);

//我知道这是一条非常古老的线索,但我无意中发现了它,想寻找答案,我想我会回答我发现的问题

未对\n进行实体化的原因是它们位于文本节点值中。如果字符位于属性中,\n序列化程序将仅对其进行实体化

下面是我发现在每个NewLineHandling值中都会发生的情况

文本节点

属性

NewLineHandling.Replace (Default) 
\r \n \r\n all go to \r\n
\t remains as \t

NewLineHandling.Entitize
\r\n goes to &#D;
\n remains as \n
\r goes to &#D;
\t remains as \t

NewLineHandling.None
\r remains \r
\r\n remains \n
\r\n remains \r\n
\t remains as \t
NewLineHandling.Replace (Default) 
\r\n goes to &#D;&#A;
\n goes to &#A;
\r goes to &#D;
\t remains &#9;

NewLineHandling.Entitize
\r\n goes to &#D;&#A;
\n goes to &#A;
\r goes to &#D;
\t remains &#9;

NewLineHandling.None
\r remains \r
\r\n remains as \n
\r\n remains as \r\n
\t remains as \t