WCF - 传递未声明为ServiceKnownType的对象

时间:2011-06-01 10:01:30

标签: c# wcf datacontractserializer xmlserializer

我有以下通过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)

1 个答案:

答案 0 :(得分:0)

一开始你提到你需要与.NET 2.0服务兼容,但同时你抱怨在.NET远程处理中工作的东西在WCF中不起作用 - 你受到.NET可能的功能的限制2.0服务器和客户端必须知道服务层上的传输类型的Web服务=类型必须在服务描述和WSDL中。此外,因为您决定使用XmlSerializer,所以通常会失去大部分实现方法:

使用XmlSerializer,您有一个选项

  • 在您的服务操作中返回XElement并接收XElement并自行处理XML - 在.NET 2.0中不起作用

编辑:

服务描述中没有动态行为。它仅在主机启动时创建一次,之后不会更改,直到您重新启动主机。如果您需要每个客户端的WSDL子集,则每个客户端都需要单独的端点,并且您必须准确定义应在每个端点上公开哪些数据协定。