WCF OperationContract使用松散类型参数

4

我希望在我的Web方法中使用松散类型的参数。

我有一个场景,客户端可以将25个DataContract对象之一发送到WCF操作中,例如:

proxy1.myFunction(PersonObject)
proxy1.myFunction(ComputerObject)

我的限制是只向客户端公开一个操作契约。

我该如何设计一个Web方法,可以将任何25个DataContract类之一作为参数?我尝试使用object作为参数类型,并给DataContract类提供KnownType属性,但在序列化过程中没有成功。

2个回答

8

我刚刚做了这个,我发现你需要在接口中添加KnownTypesAttribute。

[ServiceContract]
[ServiceKnownType(typeof(MyContract1)]
[ServiceKnownType(typeof(MyContract2)]
[ServiceKnownType(typeof(MyContract3)]
public interface IMyService
{
    [OperationContract]
    object TakeMessage();

    [OperationContract]
    void AddMessage(object contract);

}

在你的实现中,你需要检查类型以确保它是你的数据契约之一。
编辑:如果你有很多契约,你可以使用反射将它们添加到已知类型中。
internal static class KnownTypeHelper
{
    public static IEnumerable<Type> GetKnownTypes(ICustomAttributeProvider provider = null)
    {
        var types = Assembly.GetExecutingAssembly().GetTypes().Where(a => a.Namespace == "Company.Path.To.DataContractsNamespace").ToArray();

        return types;
    }
}

接下来,您可以将接口声明为:

[ServiceContract]
[ServiceKnownType("GetKnownTypes", typeof(KnownTypeHelper))]
public interface IMyService
{
    [OperationContract]
    object TakeMessage( );

    [OperationContract]
    void AddMessage(object contract);
}

这是一种更加简洁的做法。

啊!我明白了……这就是我一直在寻找的……非常感谢您如此快速的回复。 - user1312242
哇塞!!太棒了...这听起来像是写得更少,做得更多 :-) 但我猜反射会导致一点性能下降... - user1312242

1

好的,你可以尝试创建一个名为IObj的接口,并将其实现于25个不同的数据契约对象上。然后在操作契约中,将参数类型设为IObj。这样做可以帮助你发送这25个参数。


哦,这是一个好主意。让我实现一下。但是我有一个问题,比如说接口IObj有两个操作,那么所有的数据契约类都应该实现它们。另一个问题是:假设Web方法采用IObj作为参数类型... 现在,当WCF客户端在该Web方法中发送ComputerObject时,经过在WCF端的类型转换后,我们可以得到一个类型为IObj的对象.. 我的意思是,我们可能会漏掉其中一些不在IObj中的属性... 如果我理解错误,请纠正我... 不管怎样,让我试试这个... 非常感谢您的帮助 :-) - user1312242
在WCF操作契约中,您应该检查并转换每种类型的对象。这样,您就可以获得ComputerObject而不是IObj。但是,是的,对于25种不同的类型,该检查可能会增加额外的开销。 - Krishna

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接