Serve Laurijssen
Serve Laurijssen

Reputation: 9763

WCF Difference between type and ServiceKnownType

Consider the following two data contracts:

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

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

What is the difference between using the two data contracts in the following service contracts.

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

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

Can the first one be called with a subclass of item other than SubItem? If yes, whats the meaning of ServiceKnownType then?

Upvotes: 1

Views: 659

Answers (4)

Aditya Patil
Aditya Patil

Reputation: 558

What is the difference between using the two data contracts in the following service contracts? With the first one, you can pass in an object of type Item or SubItem since SubItem is exposed as a KnownType. In the second one, you can pass items of type SubItem only.

Can the first one be called with a subclass of item other than SubItem? If yes, whats the meaning of ServiceKnownType then? No, it cannot be called with a subclass of item other than SubItem. To be able to do that you will have to expose it as a KnownType.

Upvotes: 0

BRAHIM Kamel
BRAHIM Kamel

Reputation: 13794

When you use for the first case given that SubItem Inherits from Item you are telling to your webservice when he expose it's WSDL to take into consideration the deserialization of SubItem type as it may be used as an argument for the Item parameter (polymorphism principal), otherwise the receiver endpoints will not able to pass a SubItem as an argument for the method even if the type was deserialized on the client side by the DataMemberAttribute.

Note that with ServiceKnownType applied the class will be serialized even if SubItem was not marked with tha DataMember attribute

here an example

Service side

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; } }
    }
}

Client Side

  static void Main(string[] args)
        {
            Service1Client service1Client =  new Service1Client();
             var result  = service1Client.GetData(5);
            if (result is SubItem)
            {

            }
        }

Upvotes: 1

Lukas Kubis
Lukas Kubis

Reputation: 929

The first Save method can be called only with Item or SubItem instance, but The second one accepts only SubItem instance.

The purpose of ServiceKnownTypeAttribute is specify the types that should be included for consideration during deserialization. For more information look at the Data Contract Known Types and ServiceKnownTypeAttribute Class

Upvotes: 0

Emond
Emond

Reputation: 50692

Yes the first one can be called but if the actual type is unknown to the service it can only use the the members that are in the Item type.

The ServiceKnownType has no use/meaning to the server in this case because it is not used in either parameters or return types.

E.g., if the Save operation would return an Item and the actual item was a SubItem it would serialize the result as a SubItem. This is what the ServiceKnownType attribute it for.

Upvotes: 0

Related Questions