开发者

Accessing Google Docs with GData

Working Platform: ASP.NET 4.0 C# ( Framework Agnostic )

Google GData is my dependency

using Google.GData.Client;
using Google.GData.Extensions;
using Google.GData.Documents;开发者_运维百科

I have two pages Auth and List.

Auth redirects to Google Server like this

public ActionResult Auth()
{
    var target = Request.Url.ToString().ToLowerInvariant().Replace("auth", "list");
    var scope = "https://docs.google.com/feeds/";
    bool secure = false, session = true;

    var authSubUrl = AuthSubUtil.getRequestUrl(target, scope, secure, session);
    return new RedirectResult(authSubUrl);
}

Now it reaches the List Page if Authentication is successful.

public ActionResult List()
{
    if (Request.QueryString["token"] != null)
    {
        String singleUseToken = Request.QueryString["token"];

        string consumerKey = "www.blahblah.net";
        string consumerSecret = "my_key";
        string sessionToken = AuthSubUtil.exchangeForSessionToken(singleUseToken, null).ToString(); 

        var authFactory = new GOAuthRequestFactory("writely", "qwd-asd-01");
        authFactory.Token = sessionToken;
        authFactory.ConsumerKey = consumerKey;
        authFactory.ConsumerSecret = consumerSecret;
        //authFactory.TokenSecret = "";
        try
        {
            var service = new DocumentsService(authFactory.ApplicationName) { RequestFactory = authFactory };

            var query = new DocumentsListQuery();
            query.Title = "project";

            var feed = service.Query(query);
            var result = feed.Entries.ToList().ConvertAll(a => a.Title.Text);
            return View(result);
        }
        catch (GDataRequestException gdre)
        {
            throw;
        }
    }
}

This fails at the line var feed = service.Query(query); with the error

Execution of request failed: https://docs.google.com/feeds/default/private/full?title=project

The HttpStatusCode recieved on the catch block is HttpStatusCode.Unauthorized

What is wrong with this code? Do I need to get TokenSecret? If so how?


You need to request a token from Google and use it to intialize your DocumentsService instance.

Here's an example using Google's ContactsService. It should be the same for the DocumentsService.

Service service = new ContactsService("My Contacts Application");
service.setUserCredentials("your_email_address_here@gmail.com", "yourpassword");
var token = service.QueryClientLoginToken();
service.SetAuthenticationToken(token);

But as you mentioned, you are using AuthSub. I jumped the gun a bit too fast.

I see that you are requesting a session token. According to the documentation of the API you must use the session token to authenticate requests to the service by placing the token in the Authorization header. After you've set the session token, you can use the Google Data APIs client library.

Here's a complete example (by Google) on how to use AuthSub with the .NET client library:

http://code.google.com/intl/nl-NL/apis/gdata/articles/authsub_dotnet.html

Let me include a shortened example:

GAuthSubRequestFactory authFactory = 
    new GAuthSubRequestFactory("cl", "TesterApp");
authFactory.Token = (String) Session["token"];
CalendarService service = new CalendarService(authFactory.ApplicationName);
service.RequestFactory = authFactory;

EventQuery query = new EventQuery();

query.Uri = new Uri("http://www.google.com/calendar/feeds/default/private/full");

EventFeed calFeed = service.Query(query);
foreach (Google.GData.Calendar.EventEntry entry in calFeed.Entries)
{
    //...
}

And if I see correctly your example code pretty follows the same steps, except that you set the ConsumerKey and ConsumerSecret for the AuthFactory which is not done in the example by Google.


Used the 3-legged OAuth in the Google Data Protocol Client Libraries

Sample Code

string CONSUMER_KEY = "www.bherila.net";
string CONSUMER_SECRET = "RpKF7ykWt8C6At74TR4_wyIb";
string APPLICATION_NAME = "bwh-wssearch-01";

string SCOPE = "https://docs.google.com/feeds/";

public ActionResult Auth()
{
    string callbackURL = String.Format("{0}{1}", Request.Url.ToString(), "List");
    OAuthParameters parameters = new OAuthParameters()
    {
        ConsumerKey = CONSUMER_KEY,
        ConsumerSecret = CONSUMER_SECRET,
        Scope = SCOPE,
        Callback = callbackURL,
        SignatureMethod = "HMAC-SHA1"
    };

    OAuthUtil.GetUnauthorizedRequestToken(parameters);
    string authorizationUrl = OAuthUtil.CreateUserAuthorizationUrl(parameters);
    Session["parameters"] = parameters;
    ViewBag.AuthUrl = authorizationUrl;
    return View();
}

public ActionResult List()
{
    if (Session["parameters"] != null)
    {
        OAuthParameters parameters = Session["parameters"] as OAuthParameters;
        OAuthUtil.UpdateOAuthParametersFromCallback(Request.Url.Query, parameters);

        try
        {
            OAuthUtil.GetAccessToken(parameters);

            GOAuthRequestFactory authFactory = new GOAuthRequestFactory("writely", APPLICATION_NAME, parameters);

            var service = new DocumentsService(authFactory.ApplicationName);
            service.RequestFactory = authFactory;

            var query = new DocumentsListQuery();
            //query.Title = "recipe";

            var feed = service.Query(query);
            var docs = new List<string>();
            foreach (DocumentEntry entry in feed.Entries)
            {
                docs.Add(entry.Title.Text);
            }
            //var result = feed.Entries.ToList().ConvertAll(a => a.Title.Text);
            return View(docs);
        }
        catch (GDataRequestException gdre)
        {
            HttpWebResponse response = (HttpWebResponse)gdre.Response;

            //bad auth token, clear session and refresh the page
            if (response.StatusCode == HttpStatusCode.Unauthorized)
            {
                Session.Clear();
                Response.Write(gdre.Message);
            }
            else
            {
                Response.Write("Error processing request: " + gdre.ToString());
            }
            throw;
        }
    }
    else
    {
        return RedirectToAction("Index");
    }
}

This 2-legged sample never worked for me for google docs.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜