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;
}
200_success
146k22 gold badges190 silver badges478 bronze badges
asked Apr 28, 2016 at 15:32
\$\endgroup\$
3
  • \$\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\$ Commented Apr 28, 2016 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\$ Commented Apr 28, 2016 at 17:24
  • \$\begingroup\$ @CodingGorilla yes. Regardless, it needs to return true. \$\endgroup\$ Commented Apr 29, 2016 at 8:17

1 Answer 1

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;
    }
    
answered Apr 28, 2016 at 17:32
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.