如何使用KnownType在WCF服务合同中启用多态返回值?

时间:2009-12-01 13:34:18

标签: .net wcf

我正在将远程接口转换为WCF,但是我有一个声明返回“object”的方法,并且可以返回许多不同的类型(主要是不同的枚举)

我在哪里可以找到应对此事的一个例子?

(我正在使用包含所有类型的共享合同程序集,而不是生成客户端代理,如果这会产生影响。)

5 个答案:

答案 0 :(得分:1)

嗯,documentation包含使用KnownTypeAttribute的示例。请注意,它允许同一个类上的多个属性,因此您可以识别多个多态子类型。

这是非常有限的功能,因为它只允许您指定在设计时已知的类型,因此它并不真正适合通常使我们首先使用多态的可扩展性和可维护性思维。

AFAIR,这种限制的存在主要是因为WSDL / XSD中的约束,WCF合同经常被翻译。我们必须始终记住,只有消息通过网络传输 - 而不是对象。另一端的客户端可能根本不是.NET应用程序,因此为了互操作性,这些是我们必须接受的约束。

我通常发现对服务接口进行更静态的重新设计通常是更好的解决方案。您还可以考虑将返回类型公开为System.Object,它将转换为xs:any,但显然您将在此过程中丢失类型安全性。

WCF有一个高级选项,允许您在服务器和客户端之间共享类型,因此这也可能是您的解决方案。但是,如果这样做,您将失去互操作性和许多其他优点,因此在选择之前请仔细考虑此选项。

答案 1 :(得分:1)

看看这个KnownTypeProvider当我们在客户端和服务器之间共享相同的程序集时,我们将它用于silverlight连接并使用NetDataContractSerializer。

答案 2 :(得分:0)

我不确定KnowType attr是否可以使用枚举,因为它们无法继承?

答案 3 :(得分:0)

这就是我最后所做的,但是我很难开始使用Aaron Fischer长期提供的一个解决方案。

/// <summary>
/// WCF can not cope with a method that returns an object so wrap the
/// untyped object in a typed object.  Then use KnowType to tell WCF 
/// about the typs that are wrapped
/// </summary>
[DataContract(), KnownType(typeof(MyType1)), KnownType(typeof(MyType2))]
public class UntypedObjectHolder
{
    [DataMember()]
    private object m_Value;

    public UntypedObjectHolder(object value)
    {
        m_Value = value;
    }

    public object Value
    {
        get { return m_Value; }
    }
}

然后在我的界面

[OperationContract()]
UntypedObjectHolder GetValue(eGetValueType valueType);

可能有效的另一种选择是我没有尝试

[ServiceContract]
[ServiceKnownType(typeof(PhotoCamera))]
[ServiceKnownType(typeof(TemperatureSensor))]
[ServiceKnownType(typeof(DeviceBase))]
public interface IHomeService
{    
   [OperationContract] IDevice GetInterface();
}

答案 4 :(得分:0)

MSDN杂志的2011年2月刊包含“Known Types and the Generic Resolver”,显示了一个很好的解决方案。