2010-06-11 55 views
5

在我們的生產環境中,我們的WCF服務使用XMLSerializer進行序列化。爲此,我們的服務接口具有[XMLSerializerFormat]屬性。現在,我們需要更改爲DataContractSerializer,但我們必須保持與現有客戶端的兼容性。因此,我們必須使用兩個序列化器來公開每個服務。如何在同一主機上同時支持DataContractSerializer和XMLSerializer?

我們有一個約束:我們不想重新定義每個合同接口的兩倍,我們有50個服務合同接口,我們不希望有

IIncidentServiceXml 
IIncidentServiceDCS 
IEmployeeServiceXml 
IEmployeeServiceDCS 
IContractServiceXml 
IContractServiceDCS 

我們怎樣才能做到這一點?


更多信息

這是一個什麼樣我們迄今嘗試了說明,但我願意嘗試完全不同的方法:

我們試圖通過創建代碼的所有端點在我們自己的ServiceHostFactory類中。基本上我們創建兩個端點。問題是,在運行時,WCF抱怨服務有兩個端點具有相同的聯繫人名稱,但具有不同的ContractDescription實例。該消息表示我們應該使用不同的合約名稱或重複使用相同的ContractDescription實例。

其他嘗試:

我們也嘗試通過使用不同的命名空間爲每個ContractDescription實例來做到這一點。這樣,我們將保持相同的合同接口(IIncidentService),但有兩個不同的命名空間:

http://ourcompany/XML/IIncidentService 
http://ourcompany/DCS/IIncidentService 

有了,我們能夠獲得遠,但服務有一個奇怪的異常崩潰:

An ExceptionDetail, likely created by IncludeExceptionDetailInFaults=true, whose value is: 
System.InvalidOperationException: An exception was thrown in a call to a WSDL export extension: System.ServiceModel.Description.XmlSerializerOperationBehavior 
contract: http://ourcompany.cs/XML:IUserServiceWCF ----> System.NullReferenceException: Object reference not set to an instance of an object. 
    at System.ServiceModel.Description.XmlSerializerMessageContractExporter.ExportFaults(Object state) 
    at System.ServiceModel.Description.MessageContractExporter.ExportMessageContract() 
    at System.ServiceModel.Description.XmlSerializerOperationBehavior.System.ServiceModel.Description.IWsdlExportExtension.ExportContract(WsdlExporter exporter, WsdlContractConversionContext contractContext) 
    at System.ServiceModel.Description.WsdlExporter.CallExtension(WsdlContractConversionContext contractContext, IWsdlExportExtension extension) 

回答

1

短答案是,你不能,正是你的錯誤信息所說的原因,你不能有太多有效的終結點,你試圖做的。我認爲你將不得不做你說你不想要的。

This might be your only option

的問題是,指定 服務是使用XmlSerializer 需要聲明的 服務或合同 [XmlSerializerFormat]屬性。自從 我們想要使用相同的兩個 端點我們不能將它放在那裏,所以 我們將它放在 合同上。但是,當它歸結爲 時,兩個終端都使用 相同的服務和代理合同 合同嗎?

那麼,它並不一定如此。你 可以有一個合同A衍生自 合同B,然後有服務 執行合同A,使得 兩個合同中的一切都是 的服務。對於這個例子 雖然,合同B將是我們的 標準合同,合同A將 是一個界面,只是定義了 [XmlSerializerFormat]屬性。

但我不能向您保證,這將與您現有的客戶端代碼一起工作,無需更改。

+0

我已經用另一次嘗試更新了我的問題 – Sylvain 2010-06-11 20:22:16

0

如何讓兩個服務實現相同的合同?

像:

class DcsService : Service 
{} 

[XmlSerializerFormat] 
class XmlService : Service 
{} 

class Service : IServiceContract 
{} 

決不XmlSerializer的工作,但我們使用這種結構用於其它目的。

1

只需使用[DataContract]和[DataMember]標籤創建您的對象。 XmlSerializer和DataContractSerializer都會對對象進行序列化。他們更新了3.0框架中的XmlSerializer以處理數據合同序列化。 DataContractSerializer可以處理[Serializable]對象,但行爲並不準確,需要進行一些調整。

只需使用數據合約製作所有對象。這樣你就不必擔心打兩個電話(每個電話一個)。您可以毫無問題地使用XmlSerializer或DataContractSerializer。

如果你需要添加行爲屬性,你可以隨時添加[Serializable]和[DataContract],如果你喜歡。

[Serializable] 
[DataContract] 
public class Customer 

{ 
    [DataMember] 
    public int Age { get; set; } 

    [DataMember] 
    public string Name { get; set; } 

    [DataMember] 
    public int Number { get; set; } 

    [DataMember] 
    public string FullName { get; set; } 

    [XmlIgnore] 
    public int IgnoredNumber { get; set; } 
} 

的XmlSerializer序列化爲:

<?xml version="1.0" encoding="utf-16" ?> 
<Customer xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> 
    <Age>88</Age> 
    <Name>Bob</Name> 
    <Number>808</Number> 
    <FullName>Bob Jones</FullName> 
    </Customer> 

的DataContractSerializer序列化爲:

<?xml version="1.0" encoding="utf-8" ?> 
<Customer xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.datacontract.org/2004/07/ConsoleApplication1"> 
    <Age>88</Age> 
    <FullName>Bob Jones</FullName> 
    <Name>Bob</Name> 
    <Number>808</Number> 
    </Customer> 

可以很明顯的強制命名空間,因此它們都完全匹配。這僅僅是爲了舉例。

相關問題