Ultimamente sto lavorando su un progetto che mi ha portato ad utilizzare un'architettura SOA che si basa su WSE per mettere in sicurezza le comunicazioni. Utilizzo dataset per lo scambio dei dati tra tier, e così facendo mi sono accorto di uno strano comportamento che si verifica solamente nel caso in cui ci si trovi nelle seguenti condizioni:
- Sto effettuando una chiamata ad un Web Service che accetta come parametro un DataSet
- Sto utilizzando l'elemento di cifratura nella configurazione del proxy WSE
- Utilizzo il Framework 1.1
- Il dataSet che sto inviando al server contiene almeno una relazione con constraint tra due tabelle in esso contenute
L'errore è di questo tipo:
"Impossibile leggere la richiesta. --> Errore nel documento XML (1, 3491). --> Vincolo di identità 'http://tempuri.org/WSEBug/Service1:Orders_Constraint1' non dichiarato. Errore in , (1, 3283)." String
Indagando ulteriormente, ho realizzato un'applicazione per verificare le condizioni in cui questo errore si verifica. E' da notare come la richiesta fatta dal client non raggiunga neppure l'endpoint SOAP da me specificato, bensì si fermi prima. Creando un filtro input SOAP (SoapInputFilter) sono riuscito ad intercettare la richiesta e la differenza tra i due messaggi è minima, ma c'è! A seguire riporto i due messaggi: prima quello "buono", poi quello "cattivo":
<?xml version="1.0" encoding="utf-8"?>
<
soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"><soap:Header>
<wsa:Action>http://tempuri.org/WSEBug/Service1/PutOrder</wsa:Action>
<wsa:MessageID>uuid:eb11066b-3ef0-440e-bbac-223ad20c697f</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>http://localhost/WSEBUG/WSOrder.asmx</wsa:To>
</soap:Header>
<soap:Body>
<PutOrder xmlns="http://tempuri.org/WSEBug/Service1">
<order>
<xs:schema id="NewDataSet" xmlns="" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:Locale="it-IT">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
'Envelope che causa l'errore
<?xml version="1.0" encoding="utf-8"?>
<
soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:wsa="http://schemas.xmlsoap.org/ws/2004/03/addressing" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<soap:Header>
<wsa:Action>http://tempuri.org/WSEBug/Service1/PutOrder</wsa:Action>
<wsa:MessageID>uuid:93c85e29-c5b2-497e-ab59-1d7a918da515</wsa:MessageID>
<wsa:ReplyTo>
<wsa:Address>http://schemas.xmlsoap.org/ws/2004/03/addressing/role/anonymous</wsa:Address>
</wsa:ReplyTo>
<wsa:To>http://localhost/WSEBUG/WSOrder.asmx</wsa:To>
</soap:Header>
<soap:Body>
<PutOrder xmlns="http://tempuri.org/WSEBug/Service1">
<order>
<xs:schema id="NewDataSet" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xs:element name="NewDataSet" msdata:IsDataSet="true" msdata:Locale="it-IT">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
Giusto per non giocare a "Trova le differenze", ho evidenziato l'attributo mancante all'interno dell'envelope. Si tratta di un elemento xmlns="", presente nella versione che non dà errori, assente nella versione con errori. La buona notizia è che con le seguenti righe di codice all'interno del filtro il problema si risolve:
'hack to insert the attribute xmlns="" (missing if you use the WSE crypt)
'Dim _schema As XmlNode = envelope.DocumentElement.ChildNodes(1).FirstChild.FirstChild.FirstChild()
'If _schema.Name = "xs:schema" Then
' Dim _att As XmlAttribute = envelope.CreateAttribute("xmlns")
' _schema.Attributes.Append(_att)
'End If
L'altra buona notizia è che se si utilizza il framework 2.0 per far girare il Web Service l'errore scompare. Probabilmente il baco è già stato individuato e risolto. Buon per noi!