2011-08-30 57 views
0

嗨,无法反序列化具有根名称“Binary”和根名称空间的XML主体?

我(客户端)试图用ASP.NET WCF web服务进行沟通,一路上都来解决这个问题(这里的更多信息:Connect to a password protected server with WCF over HTTP)。

当运行请求方法:

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

我得到以下异常:

无法反序列化XML主体与根名称“二进制”和根命名空间'(操作“GetMyData”和使用XmlSerializer的合同('ICFService','http://tempuri.org/'))。确保将与XML相对应的类型添加到服务的已知类型集合中。说明:执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪以获取有关该错误的更多信息以及源代码的位置。异常详细信息:System.Runtime.Serialization.SerializationException:无法使用XmlSerializer反转序列化具有根名称'Binary'和根名称空间''(用于操作'GetMyData'和合同('ICFService','http://tempuri.org/'))的XML主体。确保将与XML相对应的类型添加到服务的已知类型集合中。

难道这是一个编码问题?我如何解决它?

BestRegards

EDIT1:我添加下面一行到 “服务” 的接口:

[ServiceKnownType(typeof(MyObject))] 

但这并不解决问题。

我也想补充一点,一个新的异常已经斌现在抛出:

在根级别的数据无效。行1,位置1. 描述:执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪以获取有关该错误的更多信息以及源代码的位置。 异常详细信息:System.Xml.XmlException:根级别的数据无效。第1行,位置1.

这通常是我得到的第一个异常,但是当再次尝试时,我得到另一个异常?

webservice被设置为返回两种类型的XML文档,真正的消息包含一些信息并在我的应用程序中使其失效我已经使用XmlRoot和XmlElement属性创建了corsponding类(这是我添加的类如服务界面所知的那样)。可以返回的其他消息将只包含一个字符串,当发生这种情况时,可能会在我的客户端抛出异常。因为它试图将数据变为不支持它的类型。当我得到一个propper响应时,第二个异常(根级数据无效,第1行,位置1)可能是第一个异常(无法反序列化具有根名称Binary的XML主体)我收到不支持的消息。

我认为属性和的ChannelFactory应该可以很容易,但我不能看到XML我回来因此Im现在想的我的解决方案切换到简单的工作与XMLDocumet类。这不是一个好的解决方案,但我会看到发生了什么事情。

EDIT2

如果我将自己的计算机上运行针对web服务的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> 

Ë 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(typeof(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” 编码器,负责处理JSON内容(文字/ JSON,应用/ JSON,等);
  3. “二进制”或“原始”编码器,负责处理所有其他内容类型。

的二进制编码器暴露与单一元件(称为<Binary>)主体的消息,并且实际的HTTP体作为内容base64编码数据。因此,您可能拥有的是不返回XML数据的服务器(或者至少不包含XML内容类型),因此编码器公开的XML不是XmlSerializer预期的。

检查与网络工具如小提琴手,看看服务器实际上返回。

+0

谢谢!问题是,web服务只会将适当的数据返回给特定的IP,在这种情况下,我的主机服务器。我没有完全访问此服务器,所以我不能运行小提琴或任何类似的东西。如果我尝试从我自己的计算机请求响应,我会收到一个小字符串,请参阅Edit2。虽然是建立一个使用XMLDocument的简单方法,但是这将使检查返回的XML文档变得更加容易,但它不会像现在这样的好解决方案。 – Banshee

+0

请仔细阅读Edit3 – Banshee

+0

您需要找出服务器正在使用的授权策略;如果服务器只将正确的数据返回给特定的IP,那么您将无法从另一台机器使用它。你提到你并不是无法访问该服务,但是你需要以某种方式访问​​它(或者与可能的人交谈)以允许你的客户端访问它。这与WCF没有任何关系。 – carlosfigueira

相关问题