2013-09-25 2 views
4
  • 추가 서비스를 추가하기 위해 기존 서비스를 수정하고 있으며 서비스 나 클라이언트의 구조를 변경할 수 없습니다. ASMX가 구식이며 모범 사례가 사용되지 않는다는 것을 알고 있습니다.

매우 이상한 문제가 발생하며 올바르게 작동하는 방법을 알아낼 수 없습니다. 나는 ASMX 웹 서비스를 가지고있다. (나는 변칙적으로 알고있다. 나는 이것을 바꿀 수 없다.) 그것은 응답을 받고 압축으로 압축한다. 그런 다음 SOAP를 통해 클라이언트에 전달되고 클라이언트는 스트림을 가져 와서 압축을 풀고 "서비스 참조 추가"로 만든 계약과 XMLSerializer를 사용하여 객체를 비 직렬화합니다.부분적으로 실패한 ASMX 웹 서비스의 비 직렬화

내가 가지고있는 문제는 개체를 올바르게 deserialize 할 수 없다는 것입니다. 압축 전과 압축 해제 후의 XML은 똑같아 보이지만 웹 서비스가 매개 변수의 순서를 무시하고있는 것 같습니다. [DataMember], [MessageBodyMember], [XmlElement], [MessageHeader]를 모두 올바른 순서 지정 매개 변수 및 MustUnderstand로 시도했지만 XML의 맨 아래에 항상 요소가있는 것으로 보입니다. 여기

이 혼란 것입니다, 내 messagecontract 클래스는 그들이 잘 작동 주위에 난을 변경하는 경우에도, 기본 연락처 직렬화 잘 때마다 너무

[MessageContract(IsWrapped = true)] 
public class MyClass : MyBaseContract{} 

요소와 같은 또 다른 메시지 계약 클래스에서 상속 . 거기에있는 요소들은 순서를 전혀 포함하지 않고 단지 작동합니다.

다음은 내 비 직렬화 코드입니다. 여기

using (MemoryStream stream = new MemoryStream(data)) 
     { 
      XDocument document = XDocument.Load(stream); 

      System.Xml.Serialization.XmlSerializer serializer = new System.Xml.Serialization.XmlSerializer(type); 
      System.Xml.XmlReader read = System.Xml.XmlReader.Create(new System.IO.StringReader(document.ToString())); 

      object o = serializer.Deserialize(read); 

      return o; 
     } 

직렬화 코드 : 그래서 여기

 XmlSerializer xs = new XmlSerializer(value.GetType()); 
     MemoryStream stream = new MemoryStream(); 
     xs.Serialize(stream, value); 
     stream.Position = 0; 
     StreamReader sr = new StreamReader(stream); 
     return sr.ReadToEnd(); 

내 코드는 웹 서비스에

  1. 전화 걸리는 단계입니다
  2. 웹 서비스는 도우미를 호출하고 응답 객체를 반환
  3. 응답 개체가 압축되었습니다.
  4. 압축 된 객체가 비누 형식의 와이어를 통해 전송됩니다.
  5. 클라이언트가 응답을받습니다.
  6. 클라이언트는 "서비스 참조 추가"기능에서 제공하는 계약을 기반으로 비 직렬화합니다.
  7. 클라이언트는 응답의 기본 클래스에서 데이터를 deserialize하지만 응답 클래스 자체의 데이터는 deserialize되지 않습니다.

답변

2

좋아, 나는 그것을 풀었다. 무슨 일이 있었는지

는 "서비스 참조 추가"생성 된 코드는

[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://myservice.com")] 

일명 네임 스페이스하지만 당신은 어디 생성 된 XML의 네임 스페이스를 포함하지 않는 수동으로 수행 할 수있는 XML 직렬화가 포함되어 있습니다. 이 코드를 사용하여 지정하면 XML serializer가 중단됩니다.

[MessageContract(IsWrapped = true,WrapperNamespace="http://myservice.com")] 

가 제대로 작동하려면 얻을 수있는 유일한 방법은과 같이 다시 계약 클래스에 생성 된 코드에서 네임 스페이스를 명시 할 라인을 추가하는 것입니다.

[XmlType(Namespace="http://myservice.com")] 
public class MyContract {} 

이 추가 후 모든 생성 된 XML에는 각 요소의 전체 네임 스페이스가 포함되며 디시리얼라이저는 올바르게 작동합니다. WCF ism에서 네임 스페이스가 왜 깨지는 지 전혀 모르겠습니다. 그것은 다른 WCF isms 잘 작동합니다.

부분적으로 작동하는 이유는 이전 개발자가 클라이언트 측의 특정 XML 요소에 네임 스페이스를 수동으로 삽입하는 방법을 추가했기 때문입니다. 특히 올바르게 작동하는 기본 클래스의 클래스! 나는 그 방법이 너무 깊게 묻혀 있었기 때문에 호출되는 것을 보지 못했습니다.

관련 문제