2013-06-17 4 views
5

Sto tentando di integrare un'applicazione con un servizio web di terze parti. La firma del metodo devo chiamare è qualcosa di simile (generato da VS generatore di proxy):Chiamare un webservice da C# e inviare xml senza caratteri escape

string MyFoo(string param1, string param2, string param3, string someXml) 

Ora per i primi 3 parametri non c'è nessun problema. Il quarto parametro, secondo le specifiche del fornitore, dovrebbe contenere "XML escape avvolto in un blocco CDATA", in questo modo:

<![CDATA[<?xml version="1.0" encoding="utf-8"?><rootNode></rootNode>]]> 

Ora, C# fughe (come mi sarei aspettato che faccia) tutti i caratteri che devono essere sfuggito, soprattutto i caratteri "<" e ">", anche nella dichiarazione CDATA, con conseguente qualcosa di simile:

&lt;![CDATA[&lt;?xml version="1.0" encoding="utf-8"?&gt;&lt;rootNode&gt;&lt;/rootNode&gt;]]&gt; 

per quanto so che questo è un comportamento corretto, e non c'è alcun modo per ignorare esso , in quanto potrebbe generare una cattiva richiesta (messaggio di sapone non valido) e persino un problema di sicurezza.

Qualcuno sa se mi sto perdendo qualcosa, non sapendo qualcosa, o questo è corretto e l'aspettativa del webservice di terze parti non può essere rispettata?

Grazie.

risposta

1

Mi sono messo a trafficare con il problema simile per> 2 giorni a oggi. L'unica soluzione fattibile che ha funzionato per me è stata la scrittura del client di servizio (un'interfaccia e l'implementazione del client) da solo. Questo sarebbe un problema se il tuo servizio dovesse cambiare di volta in volta (non sarai in grado di rigenerare/aggiornare il tuo client con 3 click). Lasciami dire cosa ho fatto.

semplice e veloce ricetta:

  1. copiare l'interfaccia client del servizio generato e denominarlo qualcosa come IServiceClientExtended;
  2. in tale cambio di interfaccia parametro someXml a XmlCDataSection someXml;
  3. in MyFoo gli attributi metodo cambiano XmlSerializerFormatAttribute.Use a System.ServiceModel.OperationFormatUse.Literal da System.ServiceModel.OperationFormatUse.Encoded;
  4. Rimuovi GeneratedCodeAttribute da quello IServiceClientExtended attributi se non lo si è già fatto;
  5. Crea serviceclient classe (è possibile copiare da generato) e l'interfaccia cambiamento implementa ed eredita da ClientBase, IServiceClientExtended;
  6. Creare tutti i metodi richiesti (o copiare da generato) e il metodo cambiamento firme per abito che IServiceClientExtended interfaccia (someXml dovrebbe essere XmlCDataSection, ricordi?);
  7. Nel codice, utilizzare il vostro creato serviceclient classe con quel parametro someXml convertito in XmlCDataSection. Si potrebbe fare che in questo modo:
XmlDocument doc = new XmlDocument(); 
var section = doc.CreateCDataSection(someXmlString); 
string result = client.MyFoo(param1, param2, param3, section); 
0

V. Kasparavičius è giusto. Ma è molto semplice, questo ha solo bisogno di un piccolo cambiamento in Reference.cs. Il tipo di parametro deve essere modificato da string a XmlCDataSection.

private XmlCDataSection foo; 

[System.Xml.Serialization.XmlElementAttribute(Order=2)] 
public XmlCDataSection foo { 
    get { 
     return this.foo; 
    } 
    set { 
     this.foo = value; 
     this.RaisePropertyChanged("foo"); 
    } 
} 

e quindi aggiungere il parametro come XmlCDataSection

var xmlDocument = new XmlDocument(); var parameter = xmlDocument.CreateCDataSection("<foo></foo>");