I've created the contract
[ServiceContract]
public interface ITestService
{
[OperationContract]
[NetDataContract]
void PassGuid(Guid id);
[OperationContract]
[NetDataContract]
void PassInt(int id);
}
Attribute NetDataContractAttribute
described here.
When I'm calling PassGuid
I get an error:
Additional information: The formatter threw an exception while trying to deserialize the message: There was an error while trying to deserialize parameter http://tempuri.org/:id. The InnerException message was 'XML 'Element' 'http://tempuri.org/:id' does not contain expected attribute 'http://schemas.microsoft.com/2003/10/Serialization/:Type'. The deserializer has no knowledge of which type to deserialize. Check that the type being serialized has the same contract as the type being deserialized.'. Please see InnerException for more details.
But PassInt
could be called with no errors.
Full source code here.
Edited: This question is not about efficiency of sending guids, like this one, it is mostly about using NetDataContractSerializer.
You are using the custom serializer as NetDataContractSerializer
at server side. The difference between the NetDataContractSerializer
and DataContractSerializer
is that the serialization adds additional information of Types.
E.g.
DatacontractsSerializer
serialized to:
<Customer xmlns="http://www.contoso.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<FirstName>Zighetti</FirstName>
<ID>101</ID>
<LastName>Barbara</LastName>
</Customer>
NetDataContractSerializer
would serialize the same object to:
<Customer z:Id="1" z:Type="NetDCS.Person" z:Assembly="NetDCS, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" xmlns="http://www.contoso.com" xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns:z="http://schemas.microsoft.com/2003/10/Serialization/">
<FirstName z:Id="2">Zighetti</FirstName>
<ID>101</ID>
<LastName z:Id="3">Barbara</LastName>
</Customer>
Inducing more type specific information.
In your case server knows about the NetDataContractSerializer
but client doesn't. You have to share this behavior to the client by putting it in a shared code library. Then you can add this enw behavior to the client using below code:
using (var client = new TestServiceClient())
{
// Get the channel factory
var factory = client.ChannelFactory;
// Attach the behavior
foreach (OperationDescription desc in factory.Endpoint.Contract.Operations)
{
DataContractSerializerOperationBehavior dcsOperationBehavior = desc.Behaviors.Find<DataContractSerializerOperationBehavior>();
if (dcsOperationBehavior != null)
{
int idx = desc.Behaviors.IndexOf(dcsOperationBehavior);
desc.Behaviors.Remove(dcsOperationBehavior);
desc.Behaviors.Insert(idx, new WcfClient.NetDataContractAttribute.NetDataContractSerializerOperationBehavior(desc));
//return true;
}
}
// pass
client.PassInt(0);
// fail
client.PassGuid(Guid.NewGuid());
client.Close();
}
You can also use attach the behavior via configuration file.