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; } 
}