September 9, 2010  
  You are here:  Blog
LINQ to Joe Archive
Module Border Module Border
My Book

C#


VB

Module Border Module Border

A Practical Lambda Expression Example For The UPS Tracking Web Service Call
 
Location: BlogsLINQ to Joe    
Posted by: Joe Rattz 2/3/2010 3:17:28 PM

A Practical Lambda Expression Example For The UPS Tracking Web Service Call

In "Pro LINQ: Language Integrated Query in C# 2008" I provided an example of the evolution of named methods to anonymous methods and finally to lambda expressions.  I was illustrating the brevity that anonymous methods provide over named methods, and that lambda expressions provide over anonymous methods.  Just this week, while consuming the UPS Tracking web service, I have yet again found lambda expressions to be useful for this purpose.

When compiling the UPS-provided test code, I received the following warning:

'System.Net.ServicePointManager.CertificatePolicy' is obsolete: 'CertificatePolicy is obsoleted for this type, please use ServerCertificateValidationCallback instead.

While it's just a warning and the code worked just fine, the code causing the warning has been obsolete for quite a while now so I thought I had better fix this now rather than potentially having to do it next time I upgrade to a new version of .NET.

Here is the code causing the warning:

System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();

Here we are instantiating an object from a class named TrustAllCertificatePolicy.  That class implements the System.Net.ICertificatePolicy interface and here is the class code right from the UPS-provided test code:

public class TrustAllCertificatePolicy : System.Net.ICertificatePolicy
{
    public TrustAllCertificatePolicy()
    { }

    public bool CheckValidationResult(ServicePoint sp,
      System.Security.Cryptography.X509Certificates.X509Certificate cert, WebRequest req, int problem)
    {
        return true;
    }
}

All that was really needed was just the CheckValidationResult callback function but it was implemented in .NET originally as an interface.  This requires creating a named class implementing the interface, instantiating an object of that named class type, and setting a reference to the object.  While this works, for a single callback, it is pretty verbose.  So, they made that obsolete and added a callback delegate type (thanks Jon Skeet for the terminology - C# in Depth - ISBN:  1-93398-836-3) that looks like this:

public delegate bool RemoteCertificateValidationCallback (
    Object sender,
    X509Certificate certificate,
    X509Chain chain,
    SslPolicyErrors sslPolicyErrors
)

This would now allow you to call a named method.  So instead of this:

...
System.Net.ServicePointManager.CertificatePolicy = new TrustAllCertificatePolicy();
...
public class TrustAllCertificatePolicy : System.Net.ICertificatePolicy
{
    public TrustAllCertificatePolicy()
    { }

    public bool CheckValidationResult(ServicePoint sp,
      System.Security.Cryptography.X509Certificates.X509Certificate cert, WebRequest req, int problem)
    {
        return true;
    }
}

You would have this:

...
System.Net.ServicePointManager.ServerCertificateValidationCallback += CheckValidationResult;
...
public static bool CheckValidationResult(
    object sender,
    System.Security.Cryptography.X509Certificates.X509Certificate certificate,
    System.Security.Cryptography.X509Certificates.X509Chain chain,
    System.Net.Security.SslPolicyErrors sslPolicyErrors)
{
    return true;
}

Not bad.  We eliminated a single use class and no longer have to instantiate an object from it.  Anonymous methods make this even better so that you don't even have to write a named method.  Changing the code to use an anonymous method looks like this:

System.Net.ServicePointManager.ServerCertificateValidationCallback +=
    delegate(
        object sender,
        System.Security.Cryptography.X509Certificates.X509Certificate certificate,
        System.Security.Cryptography.X509Certificates.X509Chain chain,
        System.Net.Security.SslPolicyErrors sslPolicyErrors)
    {
        return true;
    };

Even better.  Not only do we no longer have a named class, we no longer have a named method.  This is great for single-use methods.  Now I'll take the last step and convert the code to use a lambda expression.  Ready?

System.Net.ServicePointManager.ServerCertificateValidationCallback +=
    (sender, certificate, chain, sslPolicyErrors) => true;

Wow, how about that!  No named class.  No named method.  No verbose delegate syntax.  Not even any parameter types.  I could have specified parameter types had I wanted to, but for brevity I did not.

Changing the code from the initial, obsolete version, to the version using a lamda expression updated the code so that it is no longer obsolete and reduced the number of lines of code from twelve to two.  Not to mention how much easier it is to read and understand...once you understand lambda expressions.

In all of these examples, the callback method simply returned true and you may need to update it for your needs.

I hope this demonstrates how lamda expressions can simplify your code as well as resolve the obsolete warning you may be seeing if you are consuming the UPS tracking web service.

Copyright ©2010 Joe Rattz
Permalink |  Trackback

Your name:
Title:
Comment:
Add Comment   Cancel 
 
 
Home|Forums|Blog|LINQ Extras|Contact Me|Book Reviews
  Copyright (c) 2010 LINQDev Terms Of Use Privacy Statement