Open jhualpa opened 5 years ago
@jhualpa Which doc you are referring here? According to the docs, DateTimeOffset should be added to the KnownTypes of the DataContractSerializer.
@suchiagicha Doc: https://docs.microsoft.com/en-us/dotnet/framework/wcf/feature-details/data-contract-known-types Sure, that is why I do this [KnownType (typeof (DateTimeOffset))], can you provide a simple example of what out mean "DateTimeOffset should be added to the KnownTypes of the DataContractSerializer" in an actor context, I thought it only means to decorate the DataContract only.
To add known types , you need to use custom serialization by extending existing serialization class and then adding knowntypes.
Here is 1 sample of how to add known types but this is for old serialization class. Make sure you instead use this one.
@suchiagicha Thanks, I have implemented it like this:
public class CustomSerializationProvider : WrappingServiceRemotingDataContractSerializationProvider
{
private readonly IEnumerable<Type> _myTypes;
public CustomSerializationProvider()
{
_myTypes = new List<Type>
{
typeof(DateTimeOffset)
};
}
protected override DataContractSerializer CreateRemotingRequestMessageBodyDataContractSerializer(
Type remotingRequestType,
IEnumerable<Type> knownTypes)
{
var newKnownTypes = knownTypes.Concat(_myTypes);
return base.CreateRemotingRequestMessageBodyDataContractSerializer(remotingRequestType, newKnownTypes);
}
protected override DataContractSerializer CreateRemotingResponseMessageBodyDataContractSerializer(
Type remotingResponseType,
IEnumerable<Type> knownTypes)
{
var newKnownTypes = knownTypes.Concat(_myTypes);
return base.CreateRemotingRequestMessageBodyDataContractSerializer(remotingResponseType, newKnownTypes);
}
}
The reminder of the code, I have used the reference project you provided to create the proxy and the listeners, the same error keeps emerging only when I deploy to the Service Fabric cluster on Azure, with the local emulator it works fine, but the previous solution also did locally. What else I may be missing ?
@jhualpa Could you paste your code on how you are using this serializer in proxy and listener code?
@suchiagicha Sure, here is the proxy call from Sender actor which retrieves the entity with the DateTimeOffset member:
var proxyFactory = new ActorProxyFactory(c => new FabricTransportActorRemotingClientFactory(
null,
serializationProvider: new CustomSerializationProvider()));
var proxy = proxyFactory.CreateActorProxy<IReceiver>(actorId)
// now I call the actor interface that only accepts an entity with a DateTimeOffset member and returns a Task
proxy.Transfer(entity);
Here is the listener code from Receiver actor:
internal class ReceiverActorService : ActorService
{
public RececiverActorService(StatefulServiceContext context, ActorTypeInformation typeInfo, Func<ActorService, ActorId, ActorBase> factory)
: base(context, typeInfo, factory)
{ }
protected override Task OnOpenAsync(ReplicaOpenMode openMode, CancellationToken cancellationToken)
{
return Task.FromResult(true);
}
protected override IEnumerable<ServiceReplicaListener> CreateServiceReplicaListeners()
{
return new[]
{
new ServiceReplicaListener(c =>
{
return new FabricTransportActorServiceRemotingListener(this, new CustomSerializationProvider());
})
};
}
@jhualpa Did you change the actor registration(Program.cs) file to use new ReceiverActorService?
Could you try debugging client and service code and see for both customserializer is getting called?
@suchiagicha Of course I changed the actor registration to use the ReceiverActorService, when I debug locally with the emulator with 1 or 5 nodes CustomSerializer gets called, all fine in dev environment. Serialization happens, the problem is when I deploy to production, I get the SerializationException. Even I am able to debug successfully without the CustomSerializer and the listener, the problem is production, that is why this issue is so misleading.
Hi, I have 2 actors, the first one sends the following model to the second. Both use service remoting 2.1.
[DataContract] [KnownType (typeof (DateTimeOffset))] public class TheModel { [DataMember] public DateTimeOffset TheDate { get; set; } ... }
I get a System.Runtime.Serialization.SerializationException with the following message: One or more errors occurred. Expecting element 'DateTimeOffset' from namespace 'http://schemas.datacontract.org/2004/07/System'.. Encountered 'Element' with name 'dateTime', namespace 'http://schemas.microsoft.com/2003/10/Serialization/'.
What I am missing or doing wrong? According to the docs, DateTimeOffset should be added to the KnownTypes of the DataContractSerializer.