2011-08-19 19 views
5

Ứng dụng bên ngoài (java) gửi tin nhắn đến dịch vụ web của chúng tôi. Thông báo này có chứa nhiều không gian tên:WCF - Kiểm soát không gian tên khi deserializing

<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> 

Các dịch vụ WCF không thể deserialize nhắn này vì tiền tố LVO trên dòng thứ hai (nó cần phải có được Stuf theo WSDL).

Tôi muốn dịch vụ web của mình chấp nhận các thư này. Có cách nào để làm điều này - tốt nhất là sử dụng các thuộc tính?

Trả lời

1

Tôi không tin rằng bạn có thể thực hiện điều đó thông qua việc sửa đổi các không gian tên DataContract. Lý do là thuộc tính DataMember hợp lý giả định các thuộc tính lớp nằm trong cùng một không gian tên XML như chính lớp đó. Tuy nhiên, bạn có thể thực hiện việc này với sự kết hợp của các thuộc tính MessageContractMessageBodyMember. Một lựa chọn khác có thể đơn giản hơn là implement a message inspector để định dạng lại thông điệp xà phòng để tuân thủ lược đồ XML dự kiến.

+0

Chúng tôi không sử dụng d efault WCF serialization. Dịch vụ này dựa trên việc tuần tự hóa XML. Tôi đã cố gắng sử dụng thuộc tính XmlNamespaceDeclarations. Nhưng điều đó dường như không hoạt động. –

+1

Khắc phục sự cố bằng cách triển khai giao diện IXmlSerializable. –

+0

@WvanNoort bạn có thể mở rộng trên những gì bạn đã làm không? Tôi đang gặp vấn đề tương tự vào lúc này. – Declan

1

Tôi gặp sự cố này khi chấp nhận thông điệp xà phòng từ bên thứ ba.

Đây là SOAPHeader tôi đã được gửi đi (Lưu ý các không gian tên khác nhau trong 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> 

Để deserialize đúng i cần thiết để thực hiện IXmlSerializable, trong DataContract tôi, như sau:

[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"];   

    } 

Tôi sau đó có thể deserialize tiêu đề của tôi như sau:

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

Có vẻ như bạn đã tự tìm thấy câu trả lời. Kể từ đó, tôi chuyển sang một chủ nhân khác mà tôi không có quyền truy cập vào mã nữa, nhưng điều này về cơ bản giống như tôi đã làm. –

Các vấn đề liên quan