2010-04-06 2 views
1

타사 서버의 wsdl이 있습니다. 란 svcutil 및 세트의 끝났다XmlSerializer 디시리얼라이시 오류

방법. 각 메서드에 대한 응답/요청 개체를 설명하는 별도의 100 페이지 pdf가 있습니다.

제 생각에는 웹 메서드를 래핑하고 XmlSerializer를 사용하여 강력한 형식의 개체를 반환했습니다. 반환 된 XML은 다음과 같습니다 (나는 비누 헤더를 제거했습니다) :

<Response xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xsi:type="ResponseExt" 
     xmlns="http://www.thirdparty.com/lr/"> 
    <Code>0</Code> 
    <Message>SUCCESS</Message> 
    <SessionId>session_token</SessionId> 
</Response> 

간단한 것으로 보입니다. 클래스를 작성 (문서로부터/와이어 캡쳐)

[XmlRoot("Response")] 
//EDIT added XmlType 
[XmlType("ResponseExt", Namespace = "http://www.thirdparty.com/lr/")] 
public class MyClass { 
    public string Code {get; set;} 
    public string Message {get; set;} 
    public string SessionId {get; set;} 
} 

처리 시간 :

//XmlNode node = xml from above 
XmlSerializer serializer = new XmlSerializer(typeof(MyClass)); 
XmlNodeReader reader = new XmlNodeReader(node); 
Myclass myclass = serializer.Deserialize(reader) as MyClass 

마지막 줄은 그 내부 예외 메시지 불면 : 지정된 타입이 인식되지 이름 = 'ResponseExt', 네임 스페이스 = 'http://www.thirdparty.com/lr/',에 <Response xmlns=''>.
나는 시리얼을 행복하게하는 방법을 알아낼 수 없습니다 정확히이 두

XSI 무엇을 의미 : 유형 = "ResponseExt" 의 xmlns = "http://www.thirdparty.com/lr/

을 항상 조언과 포인터가


편집 감사합니다으로

:. 허용 대답 아래

,

나는 이것을 발견 할 때까지 여전히 예외를 받고 있었다. 희망을 갖고 누군가에게 시간을 절약 할 것이다. 나는 거꾸로 일하기 시작했다. 전선에서 XML을 캡처했습니다. 올바른 속성으로 생성 된 클래스에 deserialize : 매력처럼 작동합니다. webservice에서 다시 시도 - 예외. 어떤 이유로 XmlSerializer가 ResponseExt를 인식하지 못합니다.

XmlSerializer serializer = new XmlSerializer(typeof(Response)); 
XmlNode node = (XmlNode)results[0]; 
XmlDocument doc = new XmlDocument(); 
doc.LoadXml(node.OuterXml); //reload node 
XmlNodeReader reader = new XmlNodeReader(doc.FirstChild); //there is only one node 
Response rsp = serializer.Deserialize(reader) as Response; //works 

편집 : 기본 문제 wsdl 파일이 완전하지 않습니다. 이틀 동안이 (못생긴) 해결 방법을 찾은 후 타사 공급 업체가 완료된 WSDL (오류없이 비 직렬화하는 모든 유형)을 제공했습니다.

+0

좋아, 내 대답을 업데이트했습니다. – Cheeso

답변

1

왜 WSDL을 사용하면 XML을 수동으로 deserialize 하시겠습니까?

WSDL이있는 경우 svcutil.exe 도구 또는 wsdl.exe 도구를 사용하여 와이어에서 보내고받는 XML 메시지에 대한 프록시 클래스와 DTO를 생성하십시오.

웹 서비스 툴킷 또는 "스택"의 요점은 이것을 제공하여 클래스와 XML 직렬화 코드를 직접 작성하지 않아도된다는 점입니다.

시도해 보셨습니까? 이러한 도구 중 하나를 통해 WSDL을 실행하려고 시도 했습니까? 또는 Visual Studio에서 "웹 참조 추가"를 시도 했습니까?


질문을 업데이트 한 후 사용자 지정 코드를 작성하는 대신 WSDL을 수정하는 것이 좋습니다.원하는 프록시 클래스를 올바르게 생성 할 수있는 서비스 용 사용자 지정 WSDL을 생성 할 수 있습니다. 100 가지 방법 (또는 여러 가지 방법)이 모두 필요하지 않다면, 그들을 버려 두십시오. 메소드의 사용자 정의 객체가 필요하면 해당 객체에 해당하는 complexType을 정의하십시오. 이는 각 메서드에 대한 XML 직접 변환 코드를 직접 작성하는 것보다 훨씬 간단하고 안정적입니다. 당신이 생각처럼, 수동으로 XML의 직렬화 코드를 편지로 고수하지 않으려면


, 다음 두 가지 작업을 수행해야합니다

  1. a namespace to the XmlRoot attribute를 연결합니다.

  2. 클래스 이름을 ResponseExt으로 변경하고 Response 클래스에서 파생시킵니다. Response 클래스를 XmlInclude 특성으로 꾸미십시오. 이것은 the Xml Serializer with the xsi:type used in the XML fragment의 사용을 조정합니다.

그것은 코드에서 다음과 같습니다

[XmlRoot("Response", Namespace="http://www.thirdparty.com/lr/")] 
public class ResponseExt : Response { 
} 

[XmlRoot("Response", Namespace="http://www.thirdparty.com/lr/")] 
[XmlInclude(typeof(ResponseExt))] 
public class Response { 
    public string Code {get; set;} 
    public string Message {get; set;} 
    public string SessionId {get; set;} 
} 

public class XsiType 
{ 
    public static void Main(string[] args) 
    { 
     try 
     { 
      string filename = "XsiType.xml"; 
      XmlSerializer s1 = new XmlSerializer(typeof(Response)); 
      ResponseExt r = null; 
      using(System.IO.StreamReader reader= System.IO.File.OpenText(filename)) 
      { 
       r= (ResponseExt) s1.Deserialize(reader); 
      } 

      var builder = new System.Text.StringBuilder(); 
      var xmlws = new System.Xml.XmlWriterSettings { OmitXmlDeclaration = true, Indent= true }; 
      using (var writer = System.Xml.XmlWriter.Create(builder, xmlws)) 
      { 
       //s1.Serialize(writer, r, ns); 
       s1.Serialize(writer, r); 
      } 
      string xml = builder.ToString(); 
      System.Console.WriteLine(xml); 

     } 
     catch (System.Exception exc1) 
     { 
      Console.WriteLine("Exception: {0}", exc1.ToString()); 
     } 
    } 
} 

관련 : 당신이 질문을 업데이트 한 후 How can I force the use of an xsi:type attribute?

+0

Cheeso, 도구를 실행했는데 unfortunatly wsdl에 요청/응답 정보가 없으므로 모든 메소드가 객체를 가져 와서 XmlNode를 반환합니다. 각 방법을 설명하는 별도의 문서가 있습니다. 문제를 명확히하기 위해 질문을 업데이트했습니다. – smvlad

+0

좋아, 대답을 업데이트했다. – Cheeso

+0

은 클래스 이름이 변경된 네임 스페이스로 코드를 업데이트했습니다. 여전히 동일한 예외 – smvlad

관련 문제