System.Runtime.Serialization.InvalidDataContractException 'System.Security.Cryptography.X509Certificates.X509Certificate2'

Sakthi 1 Reputation point
2021-04-14T03:43:49.997+00:00

I have three stateless applications Application-A, Application-B, and Application-C. Application-B and Application-C were communicating with Application-A with remoting V1.

Recently I migrated Application-C to .Net 5.0. As V1 Remoting is not supported in .Net Core I made two listeners in Application-A(service application) as shown below to support both V1 and V2_1 listeners.

protected override IEnumerable<ServiceInstanceListener> CreateServiceInstanceListeners()
{
    return new[]
    {
        new ServiceInstanceListener(this.CreateHeadersAwareServiceInstanceListener),
        new ServiceInstanceListener((c) =>
        {
            var settings = new FabricTransportRemotingListenerSettings {UseWrappedMessage = true};
            return new FabricTransportServiceRemotingListener(c, this,settings);

        },"ServiceEndpointV2_1")
    };
}

public async Task<ClientInfo> GetClientInfo(string clinetId, CancellationToken cancellationToken = default(CancellationToken))
{
        var data = await _logic.GetClientData(clinetId, cancellationToken);
        return data.FromInternalModel();
}

Application-B should communicate with Application-A using V1 Remoting and Application-C will communicate with Application-A using remoting V2_1 stack. Below is how Application-C calls Application-A

 var client ServiceProxy.Create<IBackEndService>(new Uri(_serviceURL), listenerName: "ServiceEndpointV2_1");
await clinet.GetClientInfo(clinetId);

GetClinetInfo method return ClinetInfo object and ClientInfo looks like

 [DataContract]
    public class ClientInfo : IExtensibleDataObject
    {

        [DataMember]
        public string ClinetId { get; set; }

        [DataMember]
        public ClientAddress Address { get; set; }

        [DataMember]
        public string Name { get; set; }

        [DataMember]
        public X509Certificate2 ClientCertificate { get; set; }

        public virtual ExtensionDataObject ExtensionData { get; set; }
    }

When Application-C calls GetClinetInfo() I'm getting below exception

Exception Summary:
======================================
Message:Type 'System.Security.Cryptography.X509Certificates.X509Certificate2' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. Alternatively, you can ensure that the type is public and has a parameterless constructor - all public members of the type will then be serialized, and no attributes will be required.
UTC Timestamp: 04/12/2021 11:34:39.298
Machine Name: id-b3000000
Assembly Full Name: Temp.MyAppDomain, Version=3.16.0.0, Culture=neutral, PublicKeyToken=null
Assembly Version: 3.16.0.0
App Domain Name: Temp.MyAppDomain 
Windows Identity: 
Additional Context: 

Exception Information Details:
======================================
Exception Type: System.Runtime.Serialization.InvalidDataContractException
Message: Type 'System.Security.Cryptography.X509Certificates.X509Certificate2' cannot be serialized. Consider marking it with the DataContractAttribute attribute, and marking all of its members you want serialized with the DataMemberAttribute attribute. Alternatively, you can ensure that the type is public and has a parameterless constructor - all public members of the type will then be serialized, and no attributes will be required.
Help Link: 
HResult: -2146233088
Source: Microsoft.ServiceFabric.Services
Target Site: Void MoveNext()

Stack Trace Information Details: 
======================================
   at Microsoft.ServiceFabric.Services.Communication.Client.ServicePartitionClient`1.InvokeWithRetryAsync[TResult](Func`2 func, CancellationToken cancellationToken, Type[] doNotRetryExceptionTypes)
   at Microsoft.ServiceFabric.Services.Remoting.V2.Client.ServiceRemotingPartitionClient.InvokeAsync(IServiceRemotingRequestMessage remotingRequestMessage, String methodName, CancellationToken cancellationToken)
   at Microsoft.ServiceFabric.Services.Remoting.Builder.ProxyBase.InvokeAsyncV2(Int32 interfaceId, Int32 methodId, String methodName, IServiceRemotingRequestMessageBody requestMsgBodyValue, CancellationToken cancellationToken)
   at Microsoft.ServiceFabric.Services.Remoting.Builder.ProxyBase.ContinueWithResultV2[TRetval](Int32 interfaceId, Int32 methodId, Task`1 task)
   at Temp.MyAppDomain.Utils.DataProvider.GetMyData(String deviceId) in F:\Test\GH-LSU0BCDS-JOB1\Sources\MyLogic\Utils\MyProvider.cs:line 40
   at Temp.MyAppDomain.Logic.GetMyCertificate() in F:\Test\GH-LSU0BCDS-JOB1\Sources\MyLogic\MyLogic.cs:line 462
   at Temp.MyAppDomain.Logic.VerifySignature(Message message) in F:\Test\GH-LSU0BCDS-JOB1\Sources\MyLogic\MyLogic.cs:line 387
Azure Service Fabric
Azure Service Fabric
An Azure service that is used to develop microservices and orchestrate containers on Windows and Linux.
252 questions
C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
10,310 questions
{count} votes

1 answer

Sort by: Most helpful
  1. prmanhas-MSFT 17,891 Reputation points Microsoft Employee
    2021-05-11T12:43:46.737+00:00

    @Sakthi Apologies for all the delay and all the inconvenience caused because of the issue.

    You are attempting to send a certificate object across the wire, and that’s not a serializable object.

    If using custom serialization an option, could you please follow this doc and try migration.

    If it is not the case I would suggest you to open Support Ticket if you have a Support Plan in place otherwise let me know I will try to open one time Free Support for you.

    Hope it helps!!!

    Please "Accept as Answer" if it helped so it can help others in community looking for help on similar topics.

    0 comments No comments