1

我使用提供了以下调用和响应WCF合同 - 命名空间和SerializationExceptions

http://api.athirdparty.com/rest/foo?apikey=1234 

<response> 
    <foo>this is a foo</foo> 
</response> 

http://api.athirdparty.com/rest/bar?apikey=1234 

<response> 
    <bar>this is a bar</bar> 
</response> 

这是合同和支持类型我写

第三方Web服务
[ServiceContract] 
[XmlSerializerFormat] 
public interface IFooBarService 
{ 
    [OperationContract] 
    [WebGet(
     BodyStyle = WebMessageBodyStyle.Bare, 
     ResponseFormat = WebMessageFormat.Xml, 
     UriTemplate = "foo?key={apikey}")] 
    FooResponse GetFoo(string apikey); 

    [OperationContract] 
    [WebGet(
     BodyStyle = WebMessageBodyStyle.Bare, 
     ResponseFormat = WebMessageFormat.Xml, 
     UriTemplate = "bar?key={apikey}")] 
    BarResponse GetBar(string apikey); 
} 

[XmlRoot("response")] 
public class FooResponse 
{ 
    [XmlElement("foo")] 
    public string Foo { get; set; } 
} 

[XmlRoot("response")] 
public class BarResponse 
{ 
    [XmlElement("bar")] 
    public string Bar { get; set; } 
} 

然后我的客户看起来像这样

static void Main(string[] args) 
{ 
    using (WebChannelFactory<IFooBarService> cf = new WebChannelFactory<IFooBarService>("thirdparty")) 
    { 
     var channel = cf.CreateChannel(); 
     FooResponse result = channel.GetFoo("1234"); 
    } 
} 

当我运行此我得到下面的异常

无法反序列化XML主体与根名称“响应”和根命名空间'(操作“的getFoo”及合同(“IFooBarService”, 'http://tempuri.org/'))使用XmlSerializer。确保将与XML相对应的类型添加到服务的已知类型集合中。

如果我从IFooBarService注释掉GetBar操作,它工作正常。我知道我错过了一个重要的概念 - 只是不知道要找什么。构建我的合同类型的正确方法是什么,以便它们可以正确地反序列化?

回答

2

我想说你的第三方服务已经坏了。这里有一个命名空间冲突 - 有两个元素名为response,但具有不同的XML模式类型。

我想你将不得不使用任何涉及反序列化这个XML的.NET技术。将无法告诉.NET将.NET类型反序列化到哪个.NET中。

你只需要手工完成。为此,LINQ to XML很方便。

+0

所以尽管我的合同上写着'GetFoo'返回一个'FooResponse',也不会尝试使用这种类型的? – kenwarner 2010-03-12 02:29:03

+0

@qntmfred:它必须假定'GetBar'永远不会返回'FooResponse'。鉴于服务很容易为每个响应返回不同的元素,因此我不会错误地指出.NET没有做出这样的假设。 – 2010-03-12 02:34:50

0

你可以用这样的响应等级尝试:

[XmlRoot("response")] 
public class Response 
{ 
    [XmlElement("foo")] 
    public string Foo { get; set; } 

    [XmlElement("bar")] 
    public string Bar { get; set; } 
}