Friday, October 25, 2013

1.6.0-beta is available!

Hi all, happy 1.6.0-beta everyone!

We just announced a new release of the .NET client library for Google APIs as you can find in this announcement post. The blogpost contains all the release highlights, so you should take a look at it before you upgrade.

This release introduced a new Google.Apis.Auth NuGet package for making authenticated calls to Google services. It supports .NET 4 applications as well as Windows Phone, Windows Store applications and Portable Class Libraries.
For supporting ASP.NET MVC applications we also provide the Google.Apis.Auth.MVC package.

The old Google.Apis.Authentication package, which depends on DotNetOpenAuth, is now obsolete and we are not going to support this package any more.
Feel free to read more in our OAuth2 wiki page for instructions how to use this package on different Windows platforms with different OAuth2 flows.

The following lines of code present how easy it is to use a Google service from WP:

           UserCredential credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
               new FileStream("client_secrets.json", FileMode.Open, FileAccess.Read),
               new[] { DriveService.Scope.Drive },
               "user", CancellationToken.None);


           var service = new DriveService(new BaseClientService.Initializer
               {
                   HttpClientInitializer = credential,
                   ApplicationName = "WP Drive Sample Application”
               });


           // DO YOUR MAGIC HERE… Sample code could look like the following:
           var list = await service.Files.List().ExecuteAsync();

And in a Windows Store applications your code should look something like the following:

           UserCredential credential = await GoogleWebAuthorizationBroker.AuthorizeAsync(
               new Uri("ms-appx:///Assets/client_secrets.json"),
               new[] { Uri.EscapeUriString(CalendarService.Scope.Calendar) },
               "user", CancellationToken.None);

           var service = new CalendarService(new BaseClientService.Initializer
               {
                   HttpClientInitializer = credential,
                   ApplicationName = "Store sample",
               });
            
           // DO YOUR MAGIC HERE… Sample code could look like the following:
           var calendarListResource = await service.CalendarList.List().ExecuteAsync();

It looks like it's the exact same code, but of course that's our intention - having one user experience for every platform. You can imagine what sample code for .NET 4 applications would look like.

Things you should be aware of:
  1. GoogleWebAuthorizationBroker is a utility class which exists in the WP and WinRT extensions. You will get it from NuGet when you target the appropriate platform. It manages all the OAuth2 "dance" for you, including redirecting the user to Google authorization server for first login and saving the user's access token and refresh token (for future use) in a specific data store for WP or WinRT applications, etc.
  2. UserCredential, the output of the AuthorizeAsync method, implements IConfigurableHttpClientInitializer, IHttpExecuteInterceptor and IHttpUnsuccessfulResponseHandler. It implements the initializer so it will be able to add itself as an unsuccessful response handler (for refreshing the token on 401 responses) and as an execute interceptor (to add the authorization header for every request). Read more here.
  3. Plugging this OAuth2 solution into your service is done by adding the UserCredential as HttpClientInitializer. That's all!

Indian Summer, Upstate NY 2013














Happy 1.6.0-beta!

Happy Halloween!

Enjoy,


Eyal

Tuesday, October 15, 2013

ApplyAuthenticationToRequest errors

In the last months, just a few weeks after releasing 1.4.0-beta version of the Google APIs client library for .NET, I was asked by several developers about the following error:
System.TypeLoadException: Method 'ApplyAuthenticationToRequest' in type 'Google.Apis.Authentication.OAuth2.OAuth2Authenticator`1' from assembly 'Google.Apis.Authentication.OAuth2, Version=1.4.0.28223, Culture=neutral, PublicKeyToken=null' does not have an implementation.

This error also occurred after releasing 1.5.0-beta (Version=1.5.0.28991). The most problematic issue was that I didn't succeed in reproducing it on my machine and I spent a lot of time trying to figure out what is the exact problem ("But It works ON MY MACHINE!").

I understood then that the real problem wasn't our implementation of ApplyAuthenticationToRequest, but was based on the usage of System.Net assembly, in particular on the parameter to ApplyAuthenticationToRequest - System.Net.HttpWebRequest.
In addition, other developers also complained about the following compilation warnings:
warning CS1684: Reference to type 'System.Net.HttpWebRequest' claims it is defined in 'c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Net.dll', but it could not be found
warning CS1684: Reference to type 'System.Net.WebResponse' claims it is defined in 'c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Net.dll', but it could not be found
warning CS1684: Reference to type 'System.Net.WebRequest' claims it is defined in 'c:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Net.dll', but it could not be found

So... I investigated and investigated and had several different directions - does it depend on the Windows platform (Vista, Windows 7 and Windows 8), what is the different in the GAC content, etc.

To make a long story short, just lately we found out the core of all evil.
Users who encounter this error should install KB2468871 patch for the .NET framework 4. This patch includes a new version of System.Net.dll (and other core assemblies as well) and it solves this issue.

Special thanks to the owners of Microsoft.Net.Http package which helped a lot in investigating this issue and refer me to this article, and specifically to the following section:
If you target the .NET Framework 4 or later, the computer must have the .NET Framework 4 with an update, Update 4.0.3 for the .NET Framework 4, or the .NET Framework 4.5 installed.

Thanks also to our developers for reporting the issue, for collecting all the data I asked them to, and for offering solutions.


Nahal Mishmar, April 2013, Israel

Eyal