Convalida gli oggetti con XSD: la serializzazione è ridondante o trascurabile?

2

Contesto:

Ho un servizio web che si occupa di oggetti richiesta / risposta. Esistono schemi rigidi, definiti esternamente, che limitano sia la struttura che il contenuto di entrambe le richieste e le risposte. Devo convalidare tutte le richieste non appena vengono ricevute e tutte le risposte prima che vengano rispedite (sul servizio web fine del filo).

Non voglio replicare le regole di convalida nel codice, quindi convaliderò gli oggetti di richiesta / risposta serializzati (XML), probabilmente usando XmlReader come punto di partenza (per la velocità). Sarà oggetto a 1 via - > Metodo di convalida XML che urla se la validazione fallisce, altrimenti l'oggetto originale sarà usato per il lavoro effettivo.

Sto usando WCF, ma con XMLSerializer poiché gli schemi sono complessi e ho bisogno del supporto XSD aggiuntivo.

Domanda:

1) C'è un modo per evitare la serializzazione degli oggetti mentre colpiscono la mia estremità del filo? Idealmente mi piacerebbe arrivare all'XML prima che sia de-serializzato prima di entrare, e dopo che è serializzato, prima che vada, in uscita.

Sono a conoscenza delle annotazioni [OnSerializing] e [OnSerialized], ma non funzioneranno con XMLSerializer. Non penso che dovrei scrivere ReadXml () e WriteXml () usando IXmlSerializable - gli schemi sono complessi e soggetti a modifiche.

2) Dato che i documenti XML sono piuttosto piccoli (122kb sembra essere il massimo nel set di dati di esempio che ho) ho ragione nel sostenere che il successo delle prestazioni di ri-serializzazione sarà trascurabile?

3) Qualche idea migliore?

    
posta Tom Tom 29.01.2013 - 12:58
fonte

2 risposte

1

Per rispondere alla mia stessa domanda: sì la ri-serializzazione sarebbe stata ridondante .

La risposta che stavo cercando era usare Message Inspector - lavoro svolto.

    
risposta data 14.03.2013 - 18:20
fonte
0

Hai mai pensato di utilizzare gli strumenti XSD di code-gen? Possono deserializzare / serializzare e convalidare tramite gli ordini di grandezza dello schema più velocemente di altre tecniche in C #. Puoi utilizzare classi parziali o classi wrapper per aggiungere campi o gerarchia di oggetti aggiuntivi per la logica di business del tuo dominio.

xsd.exe schema.xsd /classes

Qualche codice che ho estratto da qui: link

public static string SerializeToXmlString(object targetInstance)
{
    string retVal = string.Empty;
    TextWriter writer = new StringWriter();
    XmlSerializer serializer = new XmlSerializer(targetInstance.GetType());
    serializer.Serialize(writer, targetInstance);
    retVal = writer.ToString(); 
    return retVal; 
}

public static object DeserializeFromXmlString(string objectXml, Type targetType)
{
    object retVal = null;
    XmlSerializer serializer = new XmlSerializer(targetType);
    StringReader stringReader = new StringReader(objectXml);
    XmlTextReader xmlReader = new XmlTextReader(StringReader);
    retVal = serializer.Deserialize(xmlReader); 
    return retVal; 
}

Se non puoi usare XSD.exe (come sottintendi nei tuoi commenti), allora che ne dici di scrivere alcune funzioni di classe helper che usano XmlDocument.Validate quando ricevi o invii i messaggi? link In realtà non si intende duplicare il codice di convalida se si tratta di un componente condiviso.

Dal loro bell'esempio:

XmlReaderSettings settings = new XmlReaderSettings();
settings.Schemas.Add("http://www.contoso.com/books", "contosoBooks.xsd");
settings.ValidationType = ValidationType.Schema;

XmlReader reader = XmlReader.Create("contosoBooks.xml", settings);
XmlDocument document = new XmlDocument();
document.Load(reader);

ValidationEventHandler eventHandler = new ValidationEventHandler(ValidationEventHandler);

// the following call to Validate succeeds.
document.Validate(eventHandler);
    
risposta data 11.02.2013 - 18:36
fonte

Leggi altre domande sui tag