WCF类型和ServiceKnownType之间的差异

时间:2014-10-10 13:09:52

标签: c# .net wcf

考虑以下两个数据合同:

[DataContract]    
public class Item
{
    [DataMember]
    public int X;
}

[DataContract]
public class SubItem : Item
{
    [DataMember]
    public int Y;
}

在以下服务合同中使用两个数据合同之间有什么区别。

[ServiceContract]
public interface IInterface
{
    [OperationContract]
    [ServiceKnownType(typeof(SubItem))]
    void Save(Item i);
}

[ServiceContract]
public interface IInterface
{
    [OperationContract]
    void Save(SubItem i);
}

可以使用SubItem以外的项的子类调用第一个吗?如果是,那么ServiceKnownType的含义是什么呢?

4 个答案:

答案 0 :(得分:1)

当您使用第一个案例时SubItem继承自Item,当他公开WSDL以考虑{{1}的反序列化时,您告诉您的Web服务} type,因为它可以用作SubItem参数(多态主体)的参数,否则接收端点将无法传递SubItem作为方法的参数,即使该类型在客户端被反序列化由Item

如果DataMemberAttribute未标记Note属性

,则ServiceKnownType应用该类的

SubItem将被序列化

这里有一个例子

服务方

DataMember

客户端

using System.Runtime.Serialization;
using System.ServiceModel;

namespace WcfService1
{

    [ServiceContract]

    public interface IService1
    {

        [OperationContract]
        [ServiceKnownType(typeof(SubItem))] // try to comment this and uncomment GetDataUsingDataContract 
         Item GetData(int value);

        //[OperationContract] //here try to comment/uncomment and see if the subitem was deserialized at client side the operation on server side will not be executed 
        //Item GetDataUsingDataContract(SubItem item);

        //// TODO: Add your service operations here
    }


    // Use a data contract as illustrated in the sample below to add composite types to service operations.
    [DataContract]

    public class Item
    {
        bool boolValue = true;
        string stringValue = "Hello ";

        [DataMember]
        public bool BoolValue
        {
            get { return boolValue; }
            set { boolValue = value; }
        }

        [DataMember]
        public string StringValue
        {
            get { return stringValue; }
            set { stringValue = value; }
        }
    }
    //[DataContract]
    public class SubItem:Item
    {
        private string _subItemVersion;
        //[DataMember]
        public string SubItemToStringValueVersion { get { return _subItemVersion; } set { _subItemVersion = value; } }
    }
}

答案 1 :(得分:0)

是的,可以调用第一个但是如果服务不知道实际类型,它只能使用Item类型中的成员。

在这种情况下,ServiceKnownType对服务器没有用处/含义,因为它没有在参数或返回类型中使用。

例如,如果Save操作将返回一个Item并且实际的项目是SubItem,它会将结果序列化为SubItem。这就是它的ServiceKnownType属性。

答案 2 :(得分:0)

第一个Save方法只能使用 Item SubItem 实例调用,但第二个只接受 SubItem 实例。

ServiceKnownTypeAttribute 的目的是指定在反序列化期间应包含的类型以供考虑。有关详细信息,请查看Data Contract Known TypesServiceKnownTypeAttribute Class

答案 3 :(得分:0)

在以下服务合同中使用这两个数据合同有什么区别? 使用第一个,您可以传入Item或SubItem类型的对象,因为SubItem是作为KnownType公开的。在第二个中,您只能传递SubItem类型的项目。

可以使用SubItem以外的项的子类调用第一个吗?如果是,那么ServiceKnownType的含义是什么呢? 不,它不能使用SubItem以外的项的子类调用。为此,您必须将其公开为KnownType。