Reputation: 9763
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
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
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
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
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