2011-06-01 62 views
0

我有一個通過的net.tcp露出下面的WCF接口:WCF - 未聲明爲ServiceKnownType傳遞對象

[ServiceContract] 
public interface IMyWCFService 
{ 
    [OperationContract] 
    Response ProcessRequest(Request request); 
} 

這是由以下類(大大簡化了這一目的驅動問題):

[Serializable] 
public abstract class Message 
{ 
    [XmlAttribute] 
    public string Sender { get; set; } 
    [XmlAttribute] 
    public string Recevier { get; set; } 
} 

[Serializable] 
public abstract class Response : Message 
{ 
    [XmlAttribute] 
    public int EventCode { get; set; } 
} 

[Serializable] 
public abstract class Request : Message 
{ 
    [XmlAttribute] 
    public string SourceSystem { get; set; } 
} 

[XmlRoot(Namespace="http://blah.blah.com/blah/")] 
public class StringRequest : Request 
{ 
    [XmlElement] 
    public string Payload { get; set; } 
} 

[XmlRoot(Namespace="http://blah.blah.com/blah/")] 
public class StringResponse : Response 
{ 
    [XmlElement] 
    public string Payload { get; set; } 
} 

注:我們使用XMLSerializer而不是DataContractSerializer因爲這些類必須與基於.NET的2是舊系統兼容。

由於接口採用抽象的請求/響應類的ProcessRequest方法我們要聲明StringResponse/StringRequest爲ServiceKnownType,例如:

[ServiceContract] 
[ServiceKnownType(typeof(StringRequest))] 
[ServiceKnownType(typeof(StringResponse))] 
public interface IMyWCFService 
{ 
    [OperationContract] 
    ResponseMessage ProcessRequest(RequestMessage request); 
} 

這完美的作品,一切都在好世界,然而......

WCF偵聽器只是一個更大的框架的一個組件,上面描述的類在整個過程中都被使用。我們還設計了這個框架,使我們能夠相對容易地添加新類型的請求/響應消息。例如,我可能會添加:

public class CustomRequest : Request 
{ 
    public MyCustomXmlSerialisableRequestObject Payload { get; set; } 
} 

public class CustomResponse: Response 
{ 
    public MyCustomXmlSerialisableResponseObject Payload { get; set; } 
} 

這也工作得很好,直到我得到的WCF服務接口。當我們添加一個新的自定義請求/響應對時,我們還需要更新接口上的ServiceKnownType以包含它們。這意味着我必須重新部署該服務。所以問題是 - 有什麼辦法可以避免更新界面?

作爲我們使用遠程處理的例子,我們可以通過任何我們喜歡的對象,只要它們是可序列化的,所以我假設/希望WCF中有類似的解決方案。

編輯:更新

繼這裏找到指導:

http://ashgeek.blogspot.com/2011/02/wcf-serialization-dynamically-add.html

我似乎是在正確的軌道上。但是,當我更新客戶端服務引用時,它會將所有動態類型引入服務引用。這是不可取的,因爲不是所有的客戶需要,或者應該知道,從請求/響應得到

更重要的是我似乎失去用來推送消息的ServiceClient類,如所有消息:

// Client proxy class goes AWOL after service reference update 
var client = new MyServiceReference.Client(); 
var responseMessage = client.ProcessRequest(requestMessage) 

回答

0

在開始時您提到您需要與.NET 2.0服務兼容,但同時您抱怨.NET Remoting中的某些內容在WCF中不起作用 - 您受.NET特性的限制2.0 Web服務,其中服務器和客戶端必須知道服務層上傳輸的類型=類型必須在服務描述和WSDL中。此外,因爲您決定使用XmlSerializer的,你通常失去了大部分的方式如何實現這一點:

隨着XmlSerializer你有一個選擇

  • 返回 XElement,並通過自己 在服務操作中的XElement和處理XML - 不工作在.NET 2.0

編輯:

服務描述中沒有動態行爲。它只在主機啓動時創建,並且在重啓主機之前不會更改。如果您需要每個客戶端的WSDL子集,則每個客戶端都需要單獨的端點,並且您必須準確定義每個端點上應該公開哪些數據協定。

+0

雖然我意識到.NET 2正在削弱事物在這裏與.NET 2的兼容性不幸是必不可少的。請求/響應類在整個大型框架(300k客戶端,5k服務器)中使用,其中很大一部分僅僅是.NET 2 - 升級它們的成本/時間/等等影響非常大。這是通過DataContract和此問題選擇XmlSerialiser的原因:http://stackoverflow.com/questions/5957524/wcf-datacontract-class-in-net-2。 XElement不可行,因爲這是在3.5中引入Linq的,所以它不適用於.NET2類。 – MrEyes 2011-06-01 12:50:47

+0

是的,你對'XElement'正確 - 我忘記了。在這種情況下,我想知道爲什麼你不使用.NET遠程處理。 – 2011-06-01 12:59:25

+0

其中一項核心服務有.NET 3.5,上面使用WCF有「新的閃亮東西」勢頭。所有這一切說,WCF服務當前支持字符串和二進制請求/響應消息。有了這個,我們可以傳遞XML/byte [],然後我們自己處理它。它的工作原理,但它有一個類型的,各種各樣的界面是很好的。但是,似乎我卡在一個搖滾和.NET 2之間:) – MrEyes 2011-06-01 13:02:37