【问题标题】:Unable to deserialize XML body with root name 'Binary' and root namespace?无法使用根名称“二进制”和根命名空间反序列化 XML 正文?
【发布时间】:2011-08-30 19:21:22
【问题描述】:

嗨,

我(客户端)正在尝试使用 ASP.NET WCF 与 web 服务进行通信,并且已经解决了这个问题(更多信息:Connect to a password protected server with WCF over HTTP)。

运行请求方法时:

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

我得到以下异常:

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

这可能是编码问题吗?我该如何解决?

致以最诚挚的问候

Edit1:我在“服务”的界面中添加了以下行:

[ServiceKnownType(typeof(MyObject))]

但这并不能解决问题。

我还想补充一点,现在已经抛出了一个新异常:

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

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

webservice 设置为返回两种类型的 XML 文档,真实消息包含一些信息,为了在我的应用程序中反序列化,我创建了具有 XmlRoot 和 XmlElement 属性的对应类(这是我添加的类服务接口的已知类型)。可以返回的另一条消息将只包含一个字符串,当这种情况发生时,我的客户端可能会抛出一个异常,因为它试图将数据反序列化为不支持它的类型。当我得到适当的响应时,可能会引发第一个异常(无法反序列化根名称为“Binary”的 XML 正文),而第二个异常(根级别的数据无效。第 1 行,第 1 行)可能是我收到不支持的消息。

我认为属性和 channelfactory 应该让它变得简单,但我看不到我返回的 XML,所以我现在正在考虑将我的解决方案切换到使用 XMLDocumet 类的简单工作。这不是一个好的解决方案,但我会确切地看到发生了什么。

编辑2

如果我在自己的计算机上针对 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>

编辑3:

我现在已经在主机服务器上尝试过这段代码:

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 版本不起作用?

【问题讨论】:

  • 您可能想编辑您的问题并让人们知道您已经将 [ServiceKnownType(typeof(MyObject))] 添加到 ICFService 接口,但这不会改变任何东西 - 否则人们会开始那里:)

标签: .net wcf web-services serialization


【解决方案1】:

鉴于您的linked question,您似乎在客户端工厂中使用webHttpBinding。如果是这种情况,该绑定在内部使用WebMessageEncodingBindingElement,它定义了一个复合编码器来从线路中读取消息。编码器有三个内部编码器,每个编码器负责处理特定的内容类型:

  1. “文本”编码器,负责处理 XML 内容(文本/xml、应用程序/xml 等);
  2. 一个“JSON”编码器,负责处理JSON内容(text/json、application/json等);
  3. “二进制”或“原始”编码器,负责处理所有其他内容类型。

二进制编码器公开一条带有单个元素的正文(称为&lt;Binary&gt;)的消息,并将实际的 HTTP 正文作为内容中的 base64 编码数据。因此,您可能拥有的是不返回 XML 数据(或至少不具有 XML 内容类型)的服务器,因此编码器公开的 XML 不是 XmlSerializer 所期望的。

使用 Fiddler 等网络工具检查服务器实际返回的内容。

【讨论】:

  • 谢谢!问题是 web 服务只会将正确的数据返回到特定的 IP,在这种情况下返回到我的主机服务器。我没有对该服务器的完全访问权限,所以我无法运行 Fiddle 或类似的东西。如果我尝试从我自己的计算机请求响应,我会得到一个小字符串,请参阅 Edit2。虽然是构建一个使用 XMLDocument 的简单方法,这将使检查返回的 XML 文档变得更容易,但它不会像现在的那样好的解决方案。
  • 您需要了解服务器使用的授权策略;如果服务器只将正确的数据返回到特定的 IP,那么您将无法在另一台机器上使用它。您提到您没有访问该服务的权限,但您需要以某种方式访问​​它(或与可以访问的人交谈)以允许您的客户访问它。目前它与 WCF 没有任何关系。
  • @carlosfigueura > 抱歉不清楚。我无法访问安装了远程 Web 服务的服务器,但我可以通过发送请求来访问该 Web 服务。我已经使用 XDocument 管理连接到 web 服务(使用基本身份验证)并获取我然后保存为文件的数据。问题是 WCF 版本不起作用,所以我必须手动解析 xDocument。
【解决方案2】:

这是我学到的:

WCF 能够构建 REST 服务,但 WCF 不为使用此服务提供额外帮助。相反,您应该使用 WebClient 或 HttpWebRequest 与 REST 服务进行通信。然而,WCF 确实提供了一种与 SOAP 服务进行通信的方式,否则这将很难做到。

所以我帖子的 Edit3 是与 REST 服务通信的正确方式。

在我的例子中,xDocument 会将 WebClient 的输出解析为 XDocument。然后我必须手动将此 XDocument 转换为我的视图类 (ASP.NET MVC)

【讨论】:

    猜你喜欢
    • 2016-06-19
    • 1970-01-01
    • 2019-10-12
    • 2021-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多