DotNet, The function call was ambiguous, no matching method was found.

RodtmcleanRodtmclean Member Posts: 89
Hi,

I'm making use of DotNet within NAV, I have touched on it before but having issues as below. The DotNet library in use is System.Security.Cryptography.DSASignatureFormatter.'mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089'

Many thanks, if there are any general pointers or articles that would be great.

vhx4av045nfp.png

Best Answers

  • RodtmcleanRodtmclean Member Posts: 89
    Answer ✓
    Thanks xStepa,

    I'm struggling a bit with Generics/Reflection. I've experimented quite a bit and still getting errors regarding types. There are likely a few basic assumptions I've made, needing to learn cryptography concepts at the same time :smile:

    The Error Message I'm having is
    widqdfep0yhf.png

    I've marked the code with ***** Important part below, hopefully someone can point me to the next part.

    Many Thanks
    Roddy

    // Arr := Arr.CreateInstance(GETDOTNETTYPE(Type),2);
    // Arr.SetValue(GETDOTNETTYPE(String),0);
    // Arr.SetValue(GETDOTNETTYPE(Int),1);
    // 
    // Arr2 := Arr2.CreateInstance(GETDOTNETTYPE(Type),2);
    // Arr2.SetValue(GETDOTNETTYPE(String),0);
    // Arr2.SetValue(GETDOTNETTYPE(Int),1);
    // 
    // Type := GETDOTNETTYPE(Dict);
    // Type := Type.MakeGenericType(Arr);
    // 
    // Dict := Activator.CreateInstance(Type);
    // Dict.Add('test123',0);
    
    //Swapped to using Array of Bytes as above was the wrong type
    Arr := Arr.CreateInstance(GETDOTNETTYPE(Type),2);
    Arr.SetValue(GETDOTNETTYPE(Byte),0);
    Arr.SetValue(GETDOTNETTYPE(Int),1);
    
    Arr2 := Arr2.CreateInstance(GETDOTNETTYPE(Type),2);
    Arr2.SetValue(GETDOTNETTYPE(Byte),0);
    Arr2.SetValue(GETDOTNETTYPE(Int),1);
     
    Type := GETDOTNETTYPE(Dict);
    Type := Type.MakeGenericType(Arr);
     
    Dict := Activator.CreateInstance(Type);
    
    NavByte := 65;
    Dict.Add(0,NavByte);
    Dict.Add(1,NavByte);
    Dict.Add(2,NavByte);
    Dict.Add(3,NavByte);
    
    X509Cert2 := X509Cert2.X509Certificate2('C:\ros\rct\Castle_PIT1.p12', CertPassword);
    //MESSAGE('Issuer Name %1  \Issuer %2  \Private Key %3', X509Cert2.IssuerName, X509Cert2.Issuer, FORMAT(X509Cert2.HasPrivateKey));
    
    PrivateKey := X509Cert2.PrivateKey;
    //MESSAGE(PrivateKey.ToString);
    
    RSASign := RSASign.RSAPKCS1SignatureFormatter(PrivateKey);
    RSASign.SetHashAlgorithm(X509Cert2.GetCertHashString);
    
    
    //***** Important part :smile: 
    //value to be hashed gets passed in here in Arr, signed value is returned to Arr2
    Arr2 := RSASign.CreateSignature(Arr); 
    
    //Reflection/Generics - failed attempt
    // RSASignType := RSASign.GetType;
    // MethodInfo := RSASignType.GetMethod('CreateSignature');
    // Parameters := Parameters.CreateInstance(GETDOTNETTYPE(RSASignType),0);
    // Parameters.SetValue(GETDOTNETTYPE(RSASign), 0);
    // 
    // MethodInvoke := MethodInfo.MakeGenericMethod(Parameters);
    // Parameters := Parameters.CreateInstance(GETDOTNETTYPE(RSASign),1);
    // Parameters.SetValue(RSASign, 0);
    // SignedHashVal := MethodInvoke.Invoke(NullElement, parameters);
    
  • xStepaxStepa Member Posts: 106
    Answer ✓
    Hi Roddy,
    it was just a sample of an heterogenous array (string & int). You have to use the requested type (Byte[]). So you can use one-dimensional Arr.CreateInstance(GETDOTNETTYPE(Byte), 1) or
    Arr := Encoding.Default.GetBytes(PassOrWhatEver)
    
    Regards
    xStepa

Answers

  • kdno_bekdno_be Member Posts: 3
    I would say you get this message because the CreateSignature()-function has 2 different options as parameter and you are passing a regular Text variable?
    The parameter that is expected is either of type Byte[] or HashAlgorithm.

    (https://msdn.microsoft.com/en-us/library/system.security.cryptography.dsasignatureformatter(v=vs.110).aspx)

    The link also has an example in DotNet code.
  • RodtmcleanRodtmclean Member Posts: 89
    Thanks for the reply kdno_be.

    I'm having a look at that link just now. Picking up DotNet as I progress this project. I am trying to pass in C/AL text, the code is C/AL rather that C#. I was using a Text variable, switched to type Byte in C/AL with the same result.

    Regards
    Roddy
  • xStepaxStepa Member Posts: 106
    Byte is not a Byte[] type - use System.Array instead ...
    vjeko.com/generics-in-net-interop-for-nav-2013/
    Regards
    xStepa
  • RodtmcleanRodtmclean Member Posts: 89
    Answer ✓
    Thanks xStepa,

    I'm struggling a bit with Generics/Reflection. I've experimented quite a bit and still getting errors regarding types. There are likely a few basic assumptions I've made, needing to learn cryptography concepts at the same time :smile:

    The Error Message I'm having is
    widqdfep0yhf.png

    I've marked the code with ***** Important part below, hopefully someone can point me to the next part.

    Many Thanks
    Roddy

    // Arr := Arr.CreateInstance(GETDOTNETTYPE(Type),2);
    // Arr.SetValue(GETDOTNETTYPE(String),0);
    // Arr.SetValue(GETDOTNETTYPE(Int),1);
    // 
    // Arr2 := Arr2.CreateInstance(GETDOTNETTYPE(Type),2);
    // Arr2.SetValue(GETDOTNETTYPE(String),0);
    // Arr2.SetValue(GETDOTNETTYPE(Int),1);
    // 
    // Type := GETDOTNETTYPE(Dict);
    // Type := Type.MakeGenericType(Arr);
    // 
    // Dict := Activator.CreateInstance(Type);
    // Dict.Add('test123',0);
    
    //Swapped to using Array of Bytes as above was the wrong type
    Arr := Arr.CreateInstance(GETDOTNETTYPE(Type),2);
    Arr.SetValue(GETDOTNETTYPE(Byte),0);
    Arr.SetValue(GETDOTNETTYPE(Int),1);
    
    Arr2 := Arr2.CreateInstance(GETDOTNETTYPE(Type),2);
    Arr2.SetValue(GETDOTNETTYPE(Byte),0);
    Arr2.SetValue(GETDOTNETTYPE(Int),1);
     
    Type := GETDOTNETTYPE(Dict);
    Type := Type.MakeGenericType(Arr);
     
    Dict := Activator.CreateInstance(Type);
    
    NavByte := 65;
    Dict.Add(0,NavByte);
    Dict.Add(1,NavByte);
    Dict.Add(2,NavByte);
    Dict.Add(3,NavByte);
    
    X509Cert2 := X509Cert2.X509Certificate2('C:\ros\rct\Castle_PIT1.p12', CertPassword);
    //MESSAGE('Issuer Name %1  \Issuer %2  \Private Key %3', X509Cert2.IssuerName, X509Cert2.Issuer, FORMAT(X509Cert2.HasPrivateKey));
    
    PrivateKey := X509Cert2.PrivateKey;
    //MESSAGE(PrivateKey.ToString);
    
    RSASign := RSASign.RSAPKCS1SignatureFormatter(PrivateKey);
    RSASign.SetHashAlgorithm(X509Cert2.GetCertHashString);
    
    
    //***** Important part :smile: 
    //value to be hashed gets passed in here in Arr, signed value is returned to Arr2
    Arr2 := RSASign.CreateSignature(Arr); 
    
    //Reflection/Generics - failed attempt
    // RSASignType := RSASign.GetType;
    // MethodInfo := RSASignType.GetMethod('CreateSignature');
    // Parameters := Parameters.CreateInstance(GETDOTNETTYPE(RSASignType),0);
    // Parameters.SetValue(GETDOTNETTYPE(RSASign), 0);
    // 
    // MethodInvoke := MethodInfo.MakeGenericMethod(Parameters);
    // Parameters := Parameters.CreateInstance(GETDOTNETTYPE(RSASign),1);
    // Parameters.SetValue(RSASign, 0);
    // SignedHashVal := MethodInvoke.Invoke(NullElement, parameters);
    
  • xStepaxStepa Member Posts: 106
    Answer ✓
    Hi Roddy,
    it was just a sample of an heterogenous array (string & int). You have to use the requested type (Byte[]). So you can use one-dimensional Arr.CreateInstance(GETDOTNETTYPE(Byte), 1) or
    Arr := Encoding.Default.GetBytes(PassOrWhatEver)
    
    Regards
    xStepa
  • RodtmcleanRodtmclean Member Posts: 89
    edited 2017-07-12
    A big thanks xStepha,

    I now have my digital signature. Which is good progress.

    Best Regards
    Roddy
Sign In or Register to comment.