Search code examples
c#callbackazure-functions.net-6.0

Populate class variable from inside callback method


I have a method in .NET containing a callback. The callback is not able to hit a method outside the function, how can I debug the callback method?

This is my method

public string ChainStatusLog { get; set; }

public GPayService(IConfiguration configuration, IOptions<GpayConfiguration> gPayConfiguration, BlobService blobService)
{
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls | SecurityProtocolType.Tls11 | SecurityProtocolType.Tls12;

    //Get Certificate
    CaCert = GetPemCertificate(blobService);

    ServicePointManager.ServerCertificateValidationCallback = (sender, certificate, chain, sslPolicyErrors) =>
    {
        if (sslPolicyErrors == System.Net.Security.SslPolicyErrors.None)
            return true;

        if (sslPolicyErrors != 0 && System.Net.Security.SslPolicyErrors.RemoteCertificateChainErrors != 0)
        {
            X509Chain caChain = new X509Chain();
            caChain.ChainPolicy.ExtraStore.Add(CaCert);
            caChain.ChainPolicy.VerificationFlags = X509VerificationFlags.NoFlag;
            caChain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
            caChain.Build(new X509Certificate2(certificate));

            ChainStatusLog = GetChainStatusMessage(caChain.ChainStatus);

            if (caChain.ChainStatus.Any(status => status.Status != X509ChainStatusFlags.UntrustedRoot))
            {
                foreach (X509ChainStatus chainStatus in caChain.ChainStatus)
                {
                    if (chainStatus.Status == X509ChainStatusFlags.UntrustedRoot)
                    {
                        return true;
                    }
                }
            }

            if (caChain.ChainStatus.Length == 0)
                return false;

            return caChain.ChainStatus[0].Status == X509ChainStatusFlags.NoError || caChain.ChainStatus[0].Status == X509ChainStatusFlags.PartialChain;
        }
        else
            return false;


    };
}

public static string GetChainStatusMessage(X509ChainStatus[] chainStatus)
{
    if (chainStatus == null || chainStatus.Length == 0)
    {
        return "";
    }

    StringBuilder sb = new StringBuilder();
    foreach (var status in chainStatus)
    {
        sb.AppendLine($"Status: {status.Status}, Status Information: {status.StatusInformation}");
    }

    return sb.ToString();
}

A breakpoint set on GetChainStatusMessage(X509ChainStatus[] chainStatus) method is never hit and therefore ChainStatusLog class variable is always null.


Solution

  • I think you might be missing a "+" sign before the "=" sign, where you assign the event handler method to the ServerCertificateValidationCallback delegate property, i.e. ServicePointManager.ServerCertificateValidationCallback += (sender, certificate, chain, sslPolicyErrors).

    This syntax is used for multicast delegates, allowing you to combine multiple event handlers on a delegate. NOTE that despite RemoteCertificateValidationCallback being a multicast delegate, only the last handler's return value is authoritative. More info here: https://learn.microsoft.com/en-us/dotnet/api/system.net.servicepointmanager.servercertificatevalidationcallback?view=net-6.0