您好,
我(客户端)尝试使用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'和根命名空间''(对于操作'GetMyData'和contract('ICFService','http://tempuri.org/'))反序列化XML主体。确保将与XML对应的类型添加到服务的已知类型集合中。描述:执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。异常详细信息:System.Runtime.Serialization.SerializationException:无法使用根名称'Binary'和根命名空间''(对于操作'GetMyData'和contract('ICFService','http://tempuri.org/'))反序列化XML主体XmlSerializer的。确保将与XML对应的类型添加到服务的已知类型集合中。
这可能是编码问题吗?我该如何解决?
BestRegards
编辑1:我已将以下行添加到“服务”的界面中:
[ServiceKnownType(typeof(MyObject))]
但这并没有解决问题。
我还想补充一点,现在抛出一个新的异常:
根级别的数据无效。第1行,第1位。 描述:执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。 异常详细信息:System.Xml.XmlException:根级别的数据无效。第1行,第1位。
这通常是我得到的第一个例外但是再次尝试时我得到了另一个例外吗?
webservice设置为返回两种类型的XML文档,真正的消息包含一些信息,并在我的应用程序中对此进行deserilize,我创建了带有XmlRoot和XmlElement属性的相应类(这是我添加的类已知的服务接口类型)。可以返回的另一条消息只包含一个字符串,当发生这种情况时,我的客户端可能会抛出异常,因为它试图将数据保存为不支持它的类型。当我得到一个propper响应并且第二个异常(根级别的数据无效。第1行,第1位)可能是第二个异常时,可能会抛出第一个例外(无法反序列化具有根名称'Binary'的XML主体)我得到了不支持的消息。
我认为属性和channelfactory应该让它变得简单,但我看不到我得到的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>
EDIT3:
我现在在主机服务器上尝试了这段代码:
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 :(得分:3)
鉴于您的linked question,您似乎正在使用客户端工厂中的webHttpBinding
。如果是这种情况,那么该绑定在内部使用WebMessageEncodingBindingElement
,它定义复合编码器以从线路读取消息。编码器有三个内编码器,每个编码器负责处理特定的内容类型:
二进制编码器使用具有单个元素(称为<Binary>
)的正文和实际HTTP正文作为内容中的base64编码数据公开消息。所以你可能拥有的是一个没有返回XML数据的服务器(或者至少没有XML内容类型),因此编码器公开的XML不是XmlSerializer
期望的那样。
使用Fiddler等网络工具进行检查,了解服务器实际返回的内容。
答案 1 :(得分:0)
这是我学到的:
WCF能够构建REST服务,但WCF不会为此服务的使用提供额外帮助。相反,您应该使用WebClient或HttpWebRequest与REST服务进行通信。但是,WCF提供了一种与SOAP服务进行通信的方式,否则这将很难做到。
因此,我的帖子的Edit3是与REST服务进行通信的正确方法。
在我的情况下,xDocument会将WebClient的输出解析为XDocument。然后我将手动将此XDocument转换为我的视图类(ASP.NET MVC)