我有以下通过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)
答案 0 :(得分:0)
一开始你提到你需要与.NET 2.0服务兼容,但同时你抱怨在.NET远程处理中工作的东西在WCF中不起作用 - 你受到.NET可能的功能的限制2.0服务器和客户端必须知道服务层上的传输类型的Web服务=类型必须在服务描述和WSDL中。此外,因为您决定使用XmlSerializer,所以通常会失去大部分实现方法:
ServiceKnowType
可以从静态方法加载已知类型DataContractSerializer
)DataContractSerializer
)NetDataContractSerializer
和自定义行为)=通常这与远程处理功能相同,它要求服务和客户端之间的共享类型,服务和客户端都必须是使用WCF的.NET应用程序东西。使用XmlSerializer
,您有一个选项
XElement
并接收XElement
并自行处理XML 编辑:
服务描述中没有动态行为。它仅在主机启动时创建一次,之后不会更改,直到您重新启动主机。如果您需要每个客户端的WSDL子集,则每个客户端都需要单独的端点,并且您必须准确定义应在每个端点上公开哪些数据协定。