Google Contacts with C# 24


Google Contacts Since Google took down the client login servers a lot of users have been forced to switch to OAuth2. For those of us using the current Google .net client library that is not an issue. However anyone still accessing the old gdata APIs who uses the Gdata client libray using Oauth2 can be a struggle. While the code does work it is far from what I call pretty. The current Google .net client libray handles everything for you. The old gdata client library unfortunately does not do that.

In this tutorial I am going to show you how to access the Google Contacts API using both the current Google .net client library and the old gdata client library.     By mixing the two we get the best of both worlds.   We can use the current Google .net client library for authentication and the old gdata client library to get our Google contacts.

If you are wondering why the current Google .net client library doesn’t allow us to access Google contacts its because the current google .net client library only supports discovery APIs.  There is a big difference between the old gdata APIs and the discovery APIs.

 

Prerequisites

  1. Create an Oauth2 credentials on the Google Developers console. If you don’t know how to do that please read Google Developer Console Oauth2 credentials
  2. Install the current .net client library nuget package.  Install-Package Google.Apis.Auth
    1. This should give you access to Google.apis.auth.oauth2 and google apis.util.store
  3. Install the old .net gdata client library nuget package. Install-Package Google.GData.Contacts

 

Authenticating

We need to authenticate to Google and create an OAuth2Parameters object which the old Google gdata library can read.

public static void auth()
{

    string clientId = "xxxxxx.apps.googleusercontent.com";
    string clientSecret = "xxxxx";


    string[] scopes = new string[] { "https://www.googleapis.com/auth/contacts.readonly" };     // view your basic profile info.
    try
    {
        // Use the current Google .net client library to get the Oauth2 stuff.
        UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets { ClientId = clientId, ClientSecret = clientSecret }
                                                                                     , scopes
                                                                                     , "test"
                                                                                     , CancellationToken.None
                                                                                     , new FileDataStore("test")).Result;

        // Translate the Oauth permissions to something the old client libray can read
        OAuth2Parameters parameters = new OAuth2Parameters();
        parameters.AccessToken = credential.Token.AccessToken;
        parameters.RefreshToken = credential.Token.RefreshToken;
        RunContactsSample(parameters);
    }
    catch (Exception ex)
    {
    Console.WriteLine(ex.Message);
    }
}

Getting Google Contacts

Once we have our OAuth2Parameters we can use them to get access to the Google contacts api.

 
private static void RunContactsSample(OAuth2Parameters parameters)
{
    try
    {
        RequestSettings settings = new RequestSettings("Google contacts tutorial", parameters);
        ContactsRequest cr = new ContactsRequest(settings);
        Feed f = cr.GetContacts();
        foreach (Contact c in f.Entries)
        {
            Console.WriteLine(c.Name.FullName);
        }
    }
    catch (Exception a)
    {
        Console.WriteLine("A Google Apps error occurred.");
        Console.WriteLine();
    }
}

Conclusion

While it is possible to use Oauth2 with the old Google .net gdata client library. It may in some cases be easier to just use the current Google .net client library to authenticate then use the old client gdata library to access the data. This will also work with Google sheets.


About Linda Lawton

My name is Linda Lawton I have more than 20 years experience working as an application developer and a database expert. I have also been working with Google APIs since 2012 and I have been contributing to the Google .Net client library since 2013. In 2013 I became a a Google Developer Experts for Google Analytics.

Leave a Reply to Ehsan Mirzaaee Cancel reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

24 thoughts on “Google Contacts with C#

  • Alan

    Hi, thanks your your posts, your site its great.
    I´m trying to translate the C# code to VB Net but I have a problem with this part:

    UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets { ClientId = clientId, ClientSecret = clientSecret }
    , scopes
    , “test”
    , CancellationToken.None
    , new FileDataStore(“test”)).Result;

    In VB Net I have:

    Dim credential As UserCredential = GoogleWebAuthorizationBroker.AuthorizeAsync(New ClientSecrets() With {
    .ClientId = clientId,
    .ClientSecret = clientSecret
    }, scopes, “test”, CancellationToken.None, New FileDataStore(“test”)).Result

    But I have the error: “BC30652 a reference to assembly ‘Google.Apis.Core, Version = 1.8.1.31685, Culture = neutral, PublicKeyToken = null’ containing the type ‘IDataStore’ is required. Add one to the project”

    Do you know what is the correct translation for this part?
    Sorry if my question is too basic, I´m still learning 🙂

    Greeting from Bolivia.

  • HILTON

    Hi, I use The Same Procedure but the Method AuthorizeAsync of Class GoogleWebAuthorizationBroker return popup with Following error “Mismatch URI”. And URI for that is generated dynamically. using Dynamic Local host every time. Please help…..

  • Ravi Prakas

    protected void Page_Load(object sender, EventArgs e)
    {
    GoogleConnect.ClientId = “xxx.apps.googleusercontent.com”;
    GoogleConnect.ClientSecret = “5kWVAbfx1Diny2fGbwW_DsSI”;

    GoogleConnect.RedirectUri = Request.Url.AbsoluteUri.Split(‘?’)[0];
    GoogleConnect.API = EnumAPI.Contacts;
    if (!string.IsNullOrEmpty(Request.QueryString[“code”]))
    {
    string code = Request.QueryString[“code”];
    string json = GoogleConnect.Fetch(“me”, code, 20000);
    GoogleContacts profile = new JavaScriptSerializer().Deserialize(json);
    DataTable dt = new DataTable();
    dt.Columns.AddRange(new DataColumn[3] { new DataColumn(“Name”, typeof(string)),
    new DataColumn(“Email”, typeof(string)),
    new DataColumn(“PhotoUrl”,typeof(string)) });

    foreach (Contact contact in profile.Feed.Entry)
    {
    string name = contact.Title.T;
    string email=””;
    if(contact.GdEmail!=null)
    email = contact.GdEmail.Find(p => p.Primary).Address;
    Link photo = contact.Link.Find(p => p.Rel.EndsWith(“#photo”));
    string photoUrl = GoogleConnect.GetPhotoUrl(photo != null ? photo.Href : “~/default.png”);
    dt.Rows.Add(name, email, photoUrl);
    gvContacts.DataSource = dt;
    gvContacts.DataBind();
    }
    pnlProfile.Visible = true;
    btnLogin.Enabled = false;
    }
    if (Request.QueryString[“error”] == “access_denied”)
    {
    ClientScript.RegisterClientScriptBlock(this.GetType(), “alert”, “alert(‘Access denied.’)”, true);
    }
    }

    protected void Login(object sender, EventArgs e)
    {
    GoogleConnect.Authorize(Server.UrlEncode(“https://www.google.com/m8/feeds/”));
    }

    public class GoogleContacts
    {
    public Feed Feed { get; set; }
    }

    public class Feed
    {
    public GoogleTitle Title { get; set; }
    public List Entry { get; set; }
    }

    public class GoogleTitle
    {
    public string T { get; set; }
    }

    public class Contact
    {
    public GoogleTitle Title { get; set; }
    public List GdEmail { get; set; }
    public List Link { get; set; }
    }
    public class Email
    {
    public string Address { get; set; }
    public bool Primary { get; set; }
    }

    public class Link
    {
    public string Rel { get; set; }
    public string Type { get; set; }
    public string Href { get; set; }
    }
    }
    i am using above code to visual studio 2010 is working but not in visual studio 2005
    i am getting access_denied error plz help me

  • Rajasekar

    Hi,

    I just followed the way you given in “https://www.daimto.com/google-contacts-with-c/” for my google contact sync.
    Its just working fine in local that means when I run/start the web app from VS2013.
    But the google authentication page will not occur when I try from IIS Server.

    Can you please help on the same…

  • Ehsan Mirzaaee

    Hi, thank you for all you did for this article. I have two question:
    1. when I run exactly above code I get this error in browser:”The redirect URI in the request, http://127.0.0.1:59564/authorize/, does not match the ones authorized for the OAuth client” I matched my project rediect url in developers.google.com with this url but next time that I run it I get the same error with a new url: http://127.0.0.1:NewNumberHere/authorize/” and this happening every time.
    2. how can I save email address of the user that login?
    Thank you for your help

    • Linda Lawton Post author

      you need to set up visual studio so that it stops adding random port numbers.

      You should try google People api instead of google contacts it may work better for you the data should be the same. This method will give you the users email address

      • Ehsan Mirzaaee

        thank you for your answer. of course I fixed my mvc project url from project properties but I don’t know what do you mean exactly, is there any other setting I need to fixed?

  • alish

    hi.
    Google.Apis.Auth Has been updated.
    this:
    UserCredential credential = GoogleWebAuthorizationBroker.AuthorizeAsync

    not be found on this new version

  • Akshay

    Am getting exception as “Access to the path ‘C:\WINDOWS\system32\config\systemprofile’ is denied.”,please help me to fix it.

  • ASIM GUNDUZ

    Hi Linda,

    this works great but in my scenario I have a problem,
    I have the below method I use to update Notes section of the contacts however after an hour or something it stops updating.. how do I refresh the access token? any help is very appreciated !

    public static Contact UpdateContactInfo(RequestSettings rs, string id, string message)
    {

    var cr = new ContactsRequest(rs);
    // First, retrieve the contact to update.
    Contact contact =cr.Retrieve(new Uri(($@”https://www.google.com/m8/feeds/contacts/default/full/{id}”)));
    contact.Content = message + $”\n {contact.Content}”;

    try
    {
    Contact updatedContact = cr.Update(contact);
    //Console.WriteLine(“Updated: ” + updatedEntry.Updated.ToString())
    return updatedContact;
    }
    catch (GDataVersionConflictException e)
    {
    // Etags mismatch: handle the exception.
    }
    return null;
    }