0
\$\begingroup\$

I have got two generic methods to call against a service. Depending on call, some methods return an object (passed in params), some don't (void). Can this be further improved? I have got to this point after refactoring a lot and removing anything which was repeated.

private static TResponse ServiceCall<TObjectToPass, TResponse>(
    Func<TObjectToPass, TResponse> func, 
    TObjectToPass obj)
{
    var temp = ServicePointManager.ServerCertificateValidationCallback;
    ServicePointManager.ServerCertificateValidationCallback += 
        (sender, certificate, chain, errors) => true;

    var r = func(obj);

    ServicePointManager.ServerCertificateValidationCallback = temp;

    return r;
}

private static void ServiceCall<TObjectToPass>(
    Action<TObjectToPass> func, 
    TObjectToPass obj)
{
    var temp = ServicePointManager.ServerCertificateValidationCallback;
    ServicePointManager.ServerCertificateValidationCallback += 
        (sender, certificate, chain, errors) => true;

    func(obj);

    ServicePointManager.ServerCertificateValidationCallback = temp;
}
\$\endgroup\$
  • \$\begingroup\$ Is the intent of your ServerCertificateValidationCallback delegate to always validate certificates regardless of the certificate? That's not really what you're doing there. \$\endgroup\$ – Coding Gorilla Apr 28 '16 at 15:49
  • 1
    \$\begingroup\$ You don't really need to pass in obj separately, as it can just be part of the action/func that gets injected. \$\endgroup\$ – Mattias Åslund Apr 28 '16 at 17:24
  • \$\begingroup\$ @CodingGorilla yes. Regardless, it needs to return true. \$\endgroup\$ – Yahya Apr 29 '16 at 8:17
1
\$\begingroup\$
  1. Keep the reference to your callback, so you can remove it when it is no longer needed :

    // add this to the class
    private static readonly RemoteCertificateValidationCallback IgnoreValidation =
        (sender, certificate, chain, errors) => true;
    
    // inside your methods
    ServicePointManager.ServerCertificateValidationCallback += IgnoreValidation;
    // do stuffs
    ServicePointManager.ServerCertificateValidationCallback -= IgnoreValidation;
    
  2. Consider switch the order of your parameter. TObjectToPass is the key generic parameter in both method, yet its definition is unclear until the 2nd parameter is passed or unless you specify in ServerCall<__HERE__>(... or ServerCall((___HERE x) => .... By keep it on the 2nd place, you penalize yourself by not taking advantage of intellisense :

    // compiler has no idea what is x
    ServiceCall(x => x
    
    // compiler is happy to tell you what x can do
    ServiceCall(new { A = 'a' }, x => Console.WriteLine(x.A
    

    private static TResponse ServiceCall<TObjectToPass, TResponse>(
    TObjectToPass obj,
    Func<TObjectToPass, TResponse> func)
    {
        ServicePointManager.ServerCertificateValidationCallback += IgnoreValidation;
        var response = func(obj);
        ServicePointManager.ServerCertificateValidationCallback -= IgnoreValidation;
    
        return response;
    }
    
    private static void ServiceCall<TObjectToPass>(
        TObjectToPass obj,
        Action<TObjectToPass> action)
    {
        ServicePointManager.ServerCertificateValidationCallback += IgnoreValidation;
        action(obj);
        ServicePointManager.ServerCertificateValidationCallback -= IgnoreValidation;
    }
    
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.