I am attempting to encrypt a number of third-party class objects using SHA1. These class objects are being consumed from Service References and are unmanaged by me. While I can see and review the code in the Service Reference, I am unable to make changes to the code.
One requirement is to compute SHA1 hash on these class objects prior to sending them through SOAP. To do this, I am currently utilizing the object extensions found at http://alexmg.com/compute-any-hash-for-any-object-in-c/.
However, when I attempt to Serialize one of the classes using the DataContractSerializer
in the computerHash<T>
method, I receive the error below. I can, however, serialize this same class using the XmlSerializer
to an XML document without any trouble.
Type '[namespace].[class].[method]' with data contract name '[method]:http://schemas.datacontract.org/2004/07/[namespace].[class]' is not expected. Consider a DataContractResolver or add any types not known statically to the list of known types - for example, by using the KnownTypeAttribute attribute or by adding them to the list of known types passed to DataContractSerializer.
Any guidance on getting this to work will greatly be appreciated.
I found this StackOverflow post from a number of years ago which led me to an old blog post and tried implementing Solution 1 from that blog by using the NetDataContractSerializer
instead of the DataContractSerializer
. The code now seems to be working without throwing any Exception.
private static byte[] computeHash<T>(object instance, T cryptoServiceProvider) where T : HashAlgorithm, new()
{
// Original Code using DataContractSerializer throws an Exception.
//DataContractSerializer serializer = new DataContractSerializer(instance.GetType());
// Use the following instead of the above in order to avoid Exception being thrown.
NetDataContractSerializer serializer = new NetDataContractSerializer();
using (MemoryStream memoryStream = new MemoryStream())
{
serializer.WriteObject(memoryStream, instance);
cryptoServiceProvider.ComputeHash(memoryStream.ToArray());
return cryptoServiceProvider.Hash;
}
}