Domanda

ho il seguente codice XML di analisi nella mia domanda:

    public static XElement Parse(string xml, string xsdFilename)
    {
        var readerSettings = new XmlReaderSettings
        {
            ValidationType = ValidationType.Schema,
            Schemas = new XmlSchemaSet()
        };
        readerSettings.Schemas.Add(null, xsdFilename);
        readerSettings.ValidationFlags |= XmlSchemaValidationFlags.ProcessInlineSchema;
        readerSettings.ValidationFlags |= XmlSchemaValidationFlags.ProcessSchemaLocation;
        readerSettings.ValidationFlags |= XmlSchemaValidationFlags.ReportValidationWarnings;
        readerSettings.ValidationEventHandler +=
            (o, e) => { throw new Exception("The provided XML does not validate against the request's schema."); };

        var readerContext = new XmlParserContext(null, null, null, XmlSpace.Default, Encoding.UTF8);

        return XElement.Load(XmlReader.Create(new StringReader(xml), readerSettings, readerContext));
    }

Io lo utilizzo per analizzare le stringhe inviate al mio servizio WCF in documenti XML, per deserializzazione personalizzato.

Funziona bene quando ho letto nei file e li inviano oltre il filo (la richiesta); Ho verificato che la distinta base non viene inviato attraverso. Nel mio gestore di richieste sto serializzazione di un oggetto di risposta e l'invio di nuovo come una stringa. Il processo di serializzazione aggiunge una BOM UTF-8 verso la parte anteriore della stringa, che provoca lo stesso codice per rompersi quando l'analisi della risposta.

System.Xml.XmlException : Data at the root level is invalid. Line 1, position 1.

Nella ricerca che ho fatto nel corso dell'ultima ora o giù di lì, sembra che XmlReader dovrebbe onorare la distinta base. Se rimuovere manualmente la distinta dalla parte anteriore della stringa, la risposta XML analizza bene.

mi manca qualcosa di ovvio, o almeno qualcosa di insidioso?

EDIT: Ecco il codice di serializzazione che sto usando per restituire la risposta:

private static string SerializeResponse(Response response)
{
    var output = new MemoryStream();
    var writer = XmlWriter.Create(output);
    new XmlSerializer(typeof(Response)).Serialize(writer, response);
    var bytes = output.ToArray();
    var responseXml = Encoding.UTF8.GetString(bytes);
    return responseXml;
}

Se è solo una questione di XML che contiene in modo non corretto la distinta base, poi mi passare a

var responseXml = new UTF8Encoding(false).GetString(bytes);

, ma non era chiaro a tutti dalla mia ricerca che la distinta base era illegale nella stringa XML vero e proprio; si veda ad esempio c # Rileva codifica XML da array di byte?

È stato utile?

Soluzione

La stringa XML non devono (!) Contengono il BOM, BOM è consentito solo nei dati di byte (ad esempio flussi) che è codificato con UTF-8. Questo perché la rappresentazione stringa non è codificato, ma già una sequenza di caratteri unicode.

Sembra quindi che si carica il torto di stringa, che è in codice che sfortunatamente non ha fornito.

Modifica

Grazie per aver postato il codice di serializzazione.

Non si deve scrivere i dati in un MemoryStream, ma piuttosto ad una StringWriter che è quindi possibile convertire in una stringa con ToString. Dal momento che questo evita passando attraverso una rappresentazione di byte non è solo più veloce, ma evita anche questi problemi.

Qualcosa di simile a questo:

private static string SerializeResponse(Response response)
{
    var output = new StringWriter();
    var writer = XmlWriter.Create(output);
    new XmlSerializer(typeof(Response)).Serialize(writer, response);
    return output.ToString();
}

Altri suggerimenti

  

Nel mio gestore di richieste sto serializzazione di un oggetto di risposta e l'invio di nuovo come una stringa. Il processo di serializzazione aggiunge una BOM UTF-8 verso la parte anteriore della stringa, che provoca lo stesso codice per rompersi quando l'analisi della risposta.

Così si vuole evitare che la distinta di essere aggiunto come parte del processo di serializzazione. Purtroppo, non fornire ciò che la logica è serializzazione.

Che cosa si dovrebbe fare è fornire un UTF8Encoding istanza creata tramite la UTF8Encoding (bool) costruttore per disabilitare la generazione della distinta e passare questa istanza Encoding a qualsiasi metodo che si sta utilizzando, che sta generando la stringa intermedio.

La distinta base non dovrebbe essere nella stringa, in primo luogo.
Distinte materiali sono utilizzati per rilevare la codifica di una matrice di byte crudo; non hanno alcun commercio che è in una stringa effettiva.

Che cosa significa la stringa viene?
Probabilmente stai leggendo con la codifica sbagliata.

Le stringhe in C # sono codificati come UTF-16, in modo che il BOM sarebbe sbagliato. Come regola generale, sempre codifica XML per array di byte e decodificare da array di byte.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top