【发布时间】:2011-06-01 10:01:29
【问题描述】:
我有以下通过 net.tcp 公开的 WCF 接口:
[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 方法中使用了抽象的 Request/Response 类,我们必须将 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)
【问题讨论】:
标签: c# wcf datacontractserializer xmlserializer