2016-03-23 18 views
2

XMLシリアライザを使用すると奇妙な問題が発生します。 シリアル化されたオブジェクトグラフにForm-Feed(0x0C)を含む文字列が含まれている場合、シリアライザは正しくシリアライズできますが、シリアライズされた表現を逆シリアル化できません。XmlSerializerは、同じシリアライザでシリアル化されたXMLを逆シリアル化できません。

ここ

がコンセプトの証明です:

static void Main (string[] args) 
{ 
    var original = "test\fbla"; 

    var stringBuilder = new StringBuilder(); 

    using (var writer = new StringWriter (stringBuilder)) 
    { 
    new XmlSerializer (typeof (string)).Serialize (writer, original); 
    } 
    var serialized = stringBuilder.ToString(); 


    string deserialized; 
    using (var reader = new StringReader (serialized)) 
    { 
    deserialized = (string) new XmlSerializer (typeof (string)).Deserialize (reader); 
    } 

    Console.WriteLine (deserialized); 
} 

シリアライズされた文字列は次のとおりです。

<?xml version="1.0" encoding="utf-16"?> 
<string>test&#xC;bla</string> 

Deserializeへの呼び出しが失敗しました。 これはXmlSerializerのバグであると思われます。これは、シリアライズされた文字列がうまく構成されているようだからです。または私は何か間違っているのですか?

+0

ちょうど確認、それはフォームフィードなしで動作しますか? – Christoph

+0

'Deserialize'の失敗に関する追加情報を提供できますか? –

答えて

2

その文字はXMLで技術的に無効です(良い例外は、この例外をスローしない理由です...リファレンスソースを見ると、XmlWriterの代わりにXmlTextWriterが使用されますが、 tチェック文字?)。あなたは、シリアライザの文字をチェックしないように言われていますXmlReader与える必要があります。しかし

string deserialized; 
XmlReaderSettings settings = new XmlReaderSettings(); 
// this will make the reader not barf on invalid characters 
settings.CheckCharacters = false; 
// can't just use a string reader here, otherwise the Serializer 
// will use an XmlReader with default settings 
using (var reader = XmlReader.Create(new StringReader(serialized), settings)) 
{ 
    deserialized = (string)new XmlSerializer(typeof(string)).Deserialize(reader); 
} 

を - あなたは/間違いなくXMLに無効な文字が含まれていてもよい文字列をシリアル化する必要がある場合は、あなたが使用することを検討すべきです異なるシリアル化形式(BinaryFormatter、JSON、またはプロトコルバッファはすべて、要件/消費者に依存します)。ダウンストリームのコンシューマがXMLで無効な文字を許可する必要があることを保証するための良い方法はありません。また、一部のコンシューマにはそうするオプションがない場合があります。

+0

thx。素晴らしい答え。 – Gerhard77

+0

喜んでお手伝いします - これで問題が解決した場合、今後のユーザーが簡単に見つけられるようにチェックボックスをオンにしてください。 –

関連する問題