2011-08-19 11 views
5

Zewnętrzna aplikacja (java) wysyła wiadomości do naszej usługi internetowej. Komunikat ten zawiera wiele nazw:WCF - Kontroluj przestrzenie nazw podczas deserializacji

<StUF:Fo01Bericht xmlns:StUF="http://www.egem.nl/StUF/StUF0300"> 
    <LVO:stuurgegevens xmlns:LVO="http://www.vrom.nl/StUF/sector/lvo/0305"> 
     <StUF:versieStUF>0300</StUF:versieStUF> 
     <StUF:berichtcode>Fo01</StUF:berichtcode> 
    </LVO:stuurgegevens> 
    <StUF:body> 
     <StUF:code>200</StUF:code> 
     <StUF:plek>LVO</StUF:plek> 
     <StUF:omschrijving>test</StUF:omschrijving> 
    </StUF:body> 
</StUF:Fo01Bericht> 

Usługa WCF nie może deserializowania tę wiadomość, ponieważ prefiksu LVO na drugiej linii (to powinna być Stuf według WSDL).

Chcę, aby nasza usługa internetowa akceptowała te wiadomości. Czy istnieje sposób, aby to zrobić - najlepiej używając atrybutów?

Odpowiedz

1

Nie wierzę, że można tego dokonać poprzez modyfikację przestrzeni nazw DataContract. Powodem jest, że atrybut DataMember w uzasadniony sposób zakłada, że ​​właściwości klasy znajdują się w tej samej przestrzeni nazw XML co sama klasa. Jednak możesz to zrobić, używając kombinacji atrybutów MessageContract i MessageBodyMember. Inną możliwą prostszą alternatywą jest implement a message inspector, aby sformatować komunikat mydła, aby zachować zgodność z oczekiwanym schematem XML.

+0

Nie używamy d Serializacja WCF efault. Usługa opiera się na Serializacji XML. Próbowałem już użyć atrybutu XmlNamespaceDeclarations. Ale to nie działa. –

+1

Naprawiono problem, wdrażając interfejs IXmlSerializable. –

+0

@WvanNoort mógłbyś rozwinąć to, co zrobiłeś? W tej chwili mam ten sam problem. – Declan

1

Miałem ten problem, akceptując wiadomość mydła od strony trzeciej.

Oto soapHeader byłem wysyłany (Uwaga różnych nazw w ciągu UsernameToken):

<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:wssu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd"> 
     <wsse:UsernameToken> 
      <wsse:Username>userName</wsse:Username> 
      <wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">password</wsse:Password> 
      <wsse:Nonce>nonce</wsse:Nonce> 
      <wssu:Created>2015-02-19T16:24:32Z</wssu:Created> 
     </wsse:UsernameToken> 
    </wsse:Security> 

deserializacji prawidłowo i konieczne do realizacji IXmlSerializable, w moim DataContract, jak poniżej:

[DataContract(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd", Name = "Security")] 
public partial class SecurityHeaderType 
{ 
    [XmlElementAttribute(Namespace = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd")] 
    [DataMember] 
    public UsernameToken UsernameToken { get; set; } 
} 

public class UsernameToken : IXmlSerializable 
{ 
    public string Username { get; set; } 
    public string Password { get; set; } 
    public string Nonce { get; set; } 
    public string Created { get; set; } 

    public XmlSchema GetSchema() 
    { 
     throw new NotImplementedException(); 
    } 

    public void ReadXml(XmlReader reader) 
    { 
     Dictionary<string, string> secDictionary; 
     string xml = reader.ReadOuterXml(); 

     using (var s = GenerateStreamFromString(xml)) 
     { 
      secDictionary = 
         XElement.Load(s).Elements() 
         .ToDictionary(e => e.Name.LocalName, e => e.Value); 
     } 

     Username = secDictionary["Username"]; 
     Password = secDictionary["Password"]; 
     Nonce = secDictionary["Nonce"]; 
     Created = secDictionary["Created"];   

    } 

Byłem wtedy w stanie deserializować mój nagłówek jak poniżej:

if (OperationContext.Current.IncomingMessageHeaders.FindHeader("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd") != -1) 
{ 
    var securityHeader = OperationContext.Current.IncomingMessageHeaders.GetHeader<SecurityHeaderType>("Security", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"); 
} 
+1

Wygląda na to, że sam znalazłeś odpowiedź. Odkąd przełączyłem się na innego pracodawcę, nie miałem już dostępu do kodu, ale jest to zasadniczo to samo, co ja. –