当前位置 : 主页 > 网页制作 > xml >

如何阻止.net Xml序列化插入非法字符

来源:互联网 收集:自由互联 发布时间:2021-06-13
0x20以下的任何内容(0x09,0x0a,0x0d除外,即tab,carrige返回和换行)都不能包含在 XML文档中. 我有一些来自数据库的数据,并作为对Web服务请求的响应传递. Soap格式化程序很高兴地将0x12字符(Asci
0x20以下的任何内容(0x09,0x0a,0x0d除外,即tab,carrige返回和换行)都不能包含在 XML文档中.

我有一些来自数据库的数据,并作为对Web服务请求的响应传递.

Soap格式化程序很高兴地将0x12字符(Ascii 18,Device Control 2)编码为但是在十六进制值为0x12的客户端上响应失败,是一个无效字符

<咆哮>我觉得非常令人沮丧的是这些是同一枚硬币的两面,客户端和服务都是.net应用程序.如果没有什么东西可以读取它,为什么soap格式化程序会写坏xml?< / rant>

我也愿意

>让Xml Serialiser正确处理这些奇怪的字符或
>请求在Web服务中失败

我用google搜索,除了a)“清理你的输入”或b)“改变你的文档结构”之外,找不到太多.

a)不是跑步者,因为其中一些数据是20年
b)也不是一个选项,除了我们自己的前端,我们有客户端直接对Web服务进行编码.

有什么明显的东西我不见了吗?或者仅仅是围绕AscII控制代码的代码案例?

谢谢

更新
这实际上是XmlSerialiser的问题,以下代码会将无效字符序列化到流中,但不会对其进行反序列化

[Serializable]
public class MyData 
{
    public string Text { get; set; }

}
class Program
{
    public static void Main(string[] args)
    {
        var myData = new MyData {Text = "hello " 
                + ASCIIEncoding.ASCII.GetString(new byte[] { 0x12 }) 
                + " world"};

        var serializer = new XmlSerializer(typeof(MyData));

        var xmlWriter = new StringWriter();

        serializer.Serialize(xmlWriter, myData);

        var xmlReader = new StringReader(xmlWriter.ToString());

        var newData = (MyData)serializer.Deserialize(xmlReader); // Exception 
        // hexadecimal value 0x12, is an invalid character.

    }
}

我可以通过显式创建一个XmlWriter并将其传递给Serialise来解决写入xml的问题(我将很快发布作为我自己的答案),但这仍然意味着我要在发送之前对数据进行整理.
由于这些字符很重要,我不能剥离它们,我需要在传输之前对它们进行编码,并在读取时解码它们,我真的很惊讶,似乎没有现成的框架方法来执行此操作.

第二:解决方案

使用DataContractSerializer(默认情况下用于WCF服务)而不是XmlSerializer工作

[Serializable]
public class MyData
{
    public string Text { get; set; }
}
class Program
{
    public static void Main(string[] args)
    {
        var myData = new MyData
        {
            Text = "hello "
                + ASCIIEncoding.ASCII.GetString(new byte[] { 0x12 })
                + " world"
        };

        var serializer = new DataContractSerializer(typeof(MyData));

        var mem = new MemoryStream();

        serializer.WriteObject(mem, myData);

        mem.Seek(0, SeekOrigin.Begin);
        MyData myData2 = (MyData)serializer.ReadObject(mem);

        Console.WriteLine("myData2 {0}", myData2.Text);
    }
}

第一个:解决方法

在编写Xml时,我可以通过使用XmlWriter来阻止它,这可能比客户端窒息更好.例如

但是,它不能解决发送无效字符的根本问题

[Serializable]
public class MyData 
{
    public string Text { get; set; }
}
class Program
{
    public static void Main(string[] args)
    {
        var myData = new MyData {Text = "hello " 
            + ASCIIEncoding.ASCII.GetString(new byte[] { 0x12 }) 
            + " world"};
        var serializer = new System.Xml.Serialization.XmlSerializer(typeof(MyData));

        var sw = new StringWriter();
        XmlWriterSettings settings = new XmlWriterSettings();

        using (var writer = XmlWriter.Create(sw))
        {
            serializer.Serialize(writer, myData); // Exception
            // hexadecimal value 0x12, is an invalid character
        }
        var xmlReader = new StringReader(sw.ToString());

        var newUser = (MyData)serializer.Deserialize(xmlReader);

        Console.WriteLine("User Name = {0}", newUser);

    }
}
网友评论