2011-08-30 4 views
0

안녕,루트 이름이 'Binary'이고 루트 네임 스페이스 인 XML 본문을 deserialize 할 수 없습니까?

나는 (클라이언트) ASP.NET WCF와 웹 서비스와 통신을 시도하고이 (: Connect to a password protected server with WCF over HTTP 자세한 내용은 여기를) 해결하기 위해 길을 따라왔다입니다.

요청 메소드 실행하는 경우 : 나는 다음과 같은 예외가

var proxy = factory.CreateChannel(); 
var response = proxy.GetMyData(id); 

을 :

루트 이름 '진'과 루트 네임 스페이스 ''(작동을 위해 'GetMyData'로 XML 본체를 역 직렬화 할 수 없습니다

및 계약 ('ICFService', 'http://tempuri.org/'))을 사용하여 XmlSerializer를 사용합니다. XML에 해당하는 유형이 서비스의 알려진 유형 콜렉션에 추가되었는지 확인하십시오. 설명 : 현재 웹 요청을 실행하는 동안 처리되지 않은 예외가 발생했습니다. 오류 및 코드에서 시작된 위치에 대한 자세한 정보는 스택 추적을 검토하십시오. 예외 정보 : System.Runtime.Serialization.SerializationException : XmlSerializer를 사용하여 루트 이름 'Binary'및 루트 네임 스페이스 ''(작업 'GetMyData'및 계약 ('ICFService', 'http://tempuri.org/'))로 XML 본문을 deserialize 할 수 없습니다. XML에 해당하는 유형이 서비스의 알려진 유형 콜렉션에 추가되었는지 확인하십시오.

인코딩 문제 일 수 있습니까? 어떻게 해결합니까?

BestRegards

EDIT1 : 나는 "서비스"의 인터페이스에 다음 줄을 추가 한 :

[ServiceKnownType(typeof(MyObject))] 

하지만이 문제가 해결되지 않습니다.

는 또한 새로운 예외가 빈 지금 던진 것을 추가 할 :

루트 레벨에서 데이터가 잘못되었습니다. 줄 1, 위치 1 설명 : 현재 웹 요청을 실행하는 동안 처리되지 않은 예외가 발생했습니다. 오류 및 코드에서 시작된 위치에 대한 자세한 정보는 스택 추적을 검토하십시오. 예외 정보 : System.Xml.XmlException : 루트 수준의 데이터가 잘못되었습니다. 1 호선, 1 번 위치.

이것은 처음에는 예외가되는 경우가 많지만, 다시 시도 할 때 다른 예외가 발생합니까?

webservice는 두 가지 유형의 XML 문서를 반환하도록 설정되었으며 실제 메시지에는 몇 가지 정보가 포함되어 있으며이를 내 응용 프로그램에서 제거합니다. XmlRoot 및 XmlElement 특성을 가진 해당 클래스를 만들었습니다 (이것은 내가 추가 한 클래스입니다. 알려진대로 서비스 인터페이스에 대한 표준). 리턴 될 수있는 다른 메시지는 오직 문자열을 포함 할 것이고, 이런 일이 발생하면 데이터를 지원하지 않는 유형으로 데이터를 deserlize하려고 시도하기 때문에 클라이언트에 예외가 발생할 것입니다. 첫 번째 예외 (루트 이름이 'Binary'인 XML 몸체를 deserialize 할 수 없음)가 Propper 응답과 두 번째 예외 (루트 레벨의 데이터가 유효하지 않습니다. 행 1, 위치 1)를 얻을 때 throw 될 수 있습니다. 지원되지 않는 메시지가 표시됩니다.

나는 속성과 채널 팩토리가 쉽게 만들어야한다고 생각했지만 지금 XML을 내가 다시 볼 수 없으므로 지금 내 솔루션을 XMLDocumet 클래스로 간단하게 전환 할 생각입니다. 이것은 좋은 해결책이 아니지만 나는 어떤 일이 일어나고 있는지 정확히 볼 것입니다.

Edit2가

나는 내 자신의 컴퓨터에 웹 서비스에 대한 URL을 실행하면 나는 다음과 같은 답변을 얻을 것이다 :

<Error><code>E50</code><desc>IP Not Allowed</desc></Error> 

아무것도 더, 나는 올바른 서버에서 실행하는 경우 (내 호스트) 재생은 고객에 따라 같은 것을해야한다 :

<Desc> 
<Make cfe_code="98" cfe_value="Volkswagen" label="Märke" value="Volkswagen"/> 
<ModelName cfe_code="99" cfe_value="Touareg" label="Modell" value="Touareg"/> 
<BodyType cfe_code="212" cfe_value="22" label="Kaross" value="SUV"/> 
... 
</Desc> 

E dit3 :

public XDocument GetMyData(string regNr) 
{ 
    WebClient wc = new WebClient(); 
    wc.Credentials = new NetworkCredential("MyName", "MyPassword"); 

    Stream s = wc.OpenRead("http://MyServer.com/ag/get?UID=9999999999.eu_vddsall_xml&VINREG=" + regNr + "&LANG=sv"); 

    // return an XDocument for LINQ 
    XmlTextReader xmlReader = new XmlTextReader(s); 
    XDocument xdoc = XDocument.Load(xmlReader); 
    xmlReader.Close(); 

    xdoc.Save(HostingEnvironment.MapPath("~/App_Data/Files/Xml/") + DateTime.Now.ToString("hhmmssfff") + ".xml"); 

    return xdoc; 
} 

을 그리고이 위대한 작품 :

는 이제 호스트 서버에이 코드를 시도! 다음을 포함하는 XML 파일이 있습니다.

<?xml version="1.0" encoding="utf-8"?> 

<Desc> 
<Vin cfe_code="11" cfe_value="X" label="Chassie nr" value="X" /> 
<Make cfe_code="98" cfe_value="Volvo" label="Märke" value="Volvo" /> 
<ModelName cfe_code="99" cfe_value="S70" label="Modell" value="S70" /> 
<BodyType cfe_code="212" cfe_value="1" label="Kaross" value="Sedan" /> 
... 
</Desc> 

그럼 왜 내 WCF 버전이 작동하지 않습니까?

+0

질문을 편집하여 [ServiceKnownType (typeObject (MyObject))]를 이미 추가했음을 알릴 수 있습니다. ICFService 인터페이스이지만 아무 것도 바뀌지 않습니다. 그렇지 않으면 사람들이 거기에서 시작할 것입니다. – Tim

+0

@Tim> 감사합니다! 끝난. – Banshee

답변

0

이 내가 배운 것입니다 :

WCF는 REST 서비스를 구축 할 수 있지만, WCF는이 서비스의 소비에 대한 추가 지원을 제공하지 않습니다. 대신 WebClient 또는 HttpWebRequest를 사용하여 REST 서비스와 통신해야합니다. 그러나 WCF는 SOAP 서비스와 통신 할 수있는 방법을 제공하지 않습니다.

내 게시물의 Edit3은 REST 서비스와 통신하는 올바른 방법입니다.

제 경우에는 xDocument가 WebClient의 출력을 XDocument로 파싱합니다. 그런 다음이 XDocument를 내보기 클래스 (ASP.NET MVC)로 수동으로 변환해야합니다.

3

귀하의 linked question이 주어지면 클라이언트 공장에서 webHttpBinding을 사용하는 것으로 보입니다. 이 경우 해당 바인딩은 WebMessageEncodingBindingElement을 내부적으로 사용하여 복합 엔코더을 사용하여 회선에서 메시지를 읽습니다. 인코더는 세 내부 인코더을 가지고 각각의 특정 콘텐츠 형식 처리에 대한 책임 :

  1. 는 "텍스트"인코더, XML 컨텐츠 (텍스트/XML, 응용 프로그램/XML 등) 처리에 대한 책임;
  2. JSON 콘텐츠 (text/json, application/json 등)를 처리하는 "JSON"인코더;
  3. "2 진"또는 "원시"인코더로 다른 모든 콘텐츠 형식을 처리해야합니다.

바이너리 부호화기 (<Binary> 불리는) 하나의 요소를 가진 본체와 메시지 콘텐츠에서 base64 인코딩 된 데이터와 실제의 HTTP 바디를 노출한다. 따라서 XML 데이터를 반환하지 않는 서버 (또는 적어도 XML 콘텐츠 유형이 아닌 서버)가 있으므로 인코더에서 노출 된 XML은 XmlSerializer에서 기대하는 바가 아닙니다.

Fiddler와 같은 네트워크 도구를 확인하여 서버가 실제로 무엇을 반환하는지 확인하십시오.

+0

감사합니다. 문제는 웹 서비스가 특정 데이터 (이 경우에는 내 호스트 서버)로만 적절한 데이터를 반환한다는 것입니다. 나는이 서버에 대한 완전한 액세스 권한이 없기 때문에 Fiddle이나 그런 것을 실행할 수 없습니다. 내 컴퓨터에서 응답을 요청하려고하면 작은 문자열이 다시 나타납니다. Edit2가 표시됩니다. 하지만 XMLDocument를 대신 사용하는 간단한 메서드를 만드는 것이 반환되는 XML 문서를보다 쉽게 ​​확인할 수 있지만 현재 구현 된 것과 같은 훌륭한 솔루션은 아닙니다. – Banshee

+0

Edit3에 대해 훑어보기 – Banshee

+0

서버가 사용하는 권한 부여 정책을 알아야합니다. 서버가 올바른 데이터를 특정 IP로만 리턴하는 경우, 다른 시스템에서이 데이터를 사용할 수 없습니다. 귀하는 서비스에 액세스 할 권한이 없다고 언급했으나 클라이언트에 액세스 할 수 있도록 액세스 권한을 부여해야합니다 (또는 할 수있는 사람과 대화해야합니다). 이 시점에서 WCF와 관련이 없습니다. – carlosfigueira

관련 문제