I have a very simple MVC app at this point:
Controller:
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Welcome!";
var qs = HttpContext.Request.QueryString;
var keys = qs.AllKeys.ToList();
if (keys.Count > 0 && keys.Contains("token"))
{
Session["token"] = qs.Get("token");
Models.GoogleContact gc = new Models.GoogleContact();
}
else
{
ViewBag.GoogleUrl = AuthSubUtil.getRequestUrl(HttpContext.Request.Url.AbsoluteUri, "https://www.google.com/m8/feeds/", false, true);
}
return View();
}
public ActionResult About()
{
return View();
}
}
I have this Home View:
@{
ViewBag.Title = "Home Page";
}
<p>Home Page...</p>
<a href="@ViewBag.GoogleUrl">Tie in with Google</a>
<br />
<br />
When the app first launches there is no query string so the Controller will create the link that I embed on the Home page. You click the link and it shoots you off to Google. Authorize that you wish for this app to have access to the Google Contacts and it returns with a query string back to the home page. The Controller sees the query string, strips off the token and instantiates a Google “Model” class.
Base Class:
internal class baseGoogle
{
#region Private Properties
internal const string googleContactToken = "cp";
internal const string googleCalendarToken = "cl";
internal string _authSubToken;
internal GAuthSubRequestFactory _gAuthSubRequestFactory;
internal RequestSettings _requestSettings;
internal ContactsRequest _contactsRequest;
internal ContactsService _contactsService;
#endregion
internal baseGoogle()
{
#if DEBUG
_authSubToken = HttpContext.Current.Session["token"].ToString();
_gAuthSubRequestFactory = new Google.GData.Client.GAuthSubRequestFactory(googleContactToken, "Tester1");
_requestSettings = new Google.GData.Client.RequestSettings(_gAuthSubRequestFactory.ApplicationName, _authSubToken);
_contactsRequest = new Google.Contacts.ContactsRequest(_requestSettings);
_contactsService = new Google.GData.Contacts.ContactsService(_gAuthSubRequestFactory.ApplicationName);
_contactsService.RequestFactory = _gAuthSubRequestFactory;
#endif
}
}
My Google Contacts Class:
internal class GoogleContact : baseGoogle
{
#region Public Properties
[NotMapped]
public Dictionary<string, Group> Groups { get; set; }
#endregion
public GoogleContact() : base()
{
// Get the list of contact groups...
_requestSettings.AutoPaging = true;
Feed<Group> fg = _contactsRequest.GetGroups();
foreach (Group g in fg.Entries)
{
this.Groups.Add(g.Title, g);
}
}
}
Everything appears to be working fine until I try to iterate the Feed items. It pops a 401 – Unauthorized error at that point.
Any ideas of why it is doing this? I am following the docs up on Google Dev.
I am using the 1.7.0.1 version of the APIs.
NOTE: I found a blog entry with some different code and guess what, that works. Now to figure out why the semi-official way does not work! Anyone with any ideas?
After a lot of playing around I discovered one way to accomplish what I needed. First off, I could not discover a way to use the OpenID authorization token to get at that users contacts, calendar, etc. I am still looking for a way to do that. (see my question here)
What I did figure out was to have a person enter his google username and password in his profile then use that to connect via GData to their info. My feeling is most people would NOT want to do this! (And it is rather redundant!)
Here is the code I came up with:
Now, to figure out how to use their OpenID login instead of having to ask for their login credentials!