0

次のコードを使用してオブジェクトをシリアル化します。

public static string Serialise(IMessageSerializer messageSerializer, DelayMessage message)
{
    using (var stream = new MemoryStream())
    {
        messageSerializer.Serialize(new[] { message }, stream);

        return Encoding.UTF8.GetString(stream.ToArray());
    }
}

残念ながら、(LINQ to SQLを使用して)データベースに保存してからデータベースにクエリを実行すると、文字列は疑問符で始まるように見えます。

?<z:anyType xmlns...

どうすればそれを取り除くことができますか?次を使用して逆シリアル化しようとすると、次のようになります。

public static DelayMessage Deserialise(IMessageSerializer messageSerializer, string data)
{
    using (var stream = new MemoryStream(Encoding.UTF8.GetBytes(data)))
    {
        return (DelayMessage)messageSerializer.Deserialize(stream)[0];
    }
}

次の例外が発生します。

"1行目の位置1にエラーがあります。名前空間' http://schemas.microsoft.com/2003/10/Serialization/ 'から要素'anyType'が必要です。..名前''、名前空間''の'Text'が見つかりました。"

messageSerializer使用の実装は次のDataContractSerializerとおりです。

public void Serialize(IMessage[] messages, Stream stream)
{
    var xws = new XmlWriterSettings { ConformanceLevel = ConformanceLevel.Fragment };
    using (var xmlWriter = XmlWriter.Create(stream, xws))
    {
        var dcs = new DataContractSerializer(typeof(IMessage), knownTypes);
        foreach (var message in messages)
        {
            dcs.WriteObject(xmlWriter, message);
        }
    }
}

public IMessage[] Deserialize(Stream stream)
{
    var xrs = new XmlReaderSettings { ConformanceLevel = ConformanceLevel.Fragment };
    using (var xmlReader = XmlReader.Create(stream, xrs))
    {
        var dcs = new DataContractSerializer(typeof(IMessage), knownTypes);
        var messages = new List<IMessage>();
        while (false == xmlReader.EOF)
        {
            var message = (IMessage)dcs.ReadObject(xmlReader);
            messages.Add(message);
        }
        return messages.ToArray();
    }
}
4

1 に答える 1

3

残念ながら、(LINQ to SQLを使用して)データベースに保存してからデータベースにクエリを実行すると、文字列は疑問符で始まるように見えます。

?<z:anyTypexmlns..。

データベースがUnicode文字をサポートするように設定されていません。BOMを含む文字列を書き込むと、データベースはそれを格納できないため、「?」にマングルします。次に、戻って文字列をXMLとして読み取ると、「?」ルート要素外のテキストコンテンツであり、エラーが発生します。(ルート要素の外側にのみ空白テキストを含めることができます。)

BOMがそこに到達するのはなぜですか?Microsoftは、BOMが必要ない場合でも(UTF-8では必要ない場合でも)、BOMをあちこちにドロップするのが大好きだからです。解決策は、組み込みのEncoding.UTF8を使用する代わりに、UTF8Encodingの独自のインスタンスを作成し、その愚かなBOMが不要であることを通知することです。

Encoding utf8onlynotasridiculouslysucky= new UTF8Encoding(false);

ただし、これはデータベース構成である実際の問題を実際に覆い隠しているだけです。

于 2009-08-25T13:16:04.097 に答える