【问题标题】:Creating new album in picasa in .NET在 .NET 中的 picasa 中创建新专辑
【发布时间】:2011-11-12 14:22:16
【问题描述】:

我正在尝试将相册发布到 picasa,但总是收到“错误请求”响应。 我应该改用 HttpRequest 类吗?

System.Net.WebClient wc = new System.Net.WebClient();
wc.Headers.Add("Authorization", "AuthSub token=\"" + token + "\"");
wc.Headers.Add("GData-Version", "2");

string data =   "<entry xmlns='http://www.w3.org/2005/Atom' " +
                        "xmlns:media='http://search.yahoo.com/mrss/' " +
                        "xmlns:gphoto='http://schemas.google.com/photos/2007'>" +
                    "<title type='text'>" + name + "</title>" +
                    "<summary type='text'>" + descr + "</summary>" +
                    "<gphoto:location>asd</gphoto:location>" +
                    "<gphoto:access>" + access + "</gphoto:access>" +
                    "<gphoto:timestamp>1152255600000</gphoto:timestamp>" +
                    "<media:group>" +
                        "<media:keywords>adds</media:keywords>" +
                    "</media:group>" +
                    "<category scheme='http://schemas.google.com/g/2005#kind' " +
                        "term='http://schemas.google.com/photos/2007#album'></category>" +
                "</entry>";


try
{
    string response = wc.UploadString("https://picasaweb.google.com/data/feed/api/user/default", "post", data);
    return response;
}

catch (Exception e)
{
    return e.ToString();
}

【问题讨论】:

标签: c# .net post webclient picasa


【解决方案1】:

Google 为 picasa [.net] 集成制作了一个方便的 api:

http://code.google.com/apis/picasaweb/docs/1.0/developers_guide_dotnet.html

手工编写所有代码没有意义!

这是一些代码(vb.net,但它很简单):

Public Shared Function CreateAlbum(ByVal albumTitle As String) As AlbumAccessor

    Dim newAlbum As New AlbumEntry()
    newAlbum.Title.Text = albumTitle

    Dim ac As New AlbumAccessor(newAlbum)
    ac.Access = "public"

    Dim feedUri As New Uri(PicasaQuery.CreatePicasaUri(ConfigurationManager.AppSettings("GData_Email")))
    Dim albumEntry As PicasaEntry = CreateAuthenticatedRequest().Insert(feedUri, newAlbum)

    Return New AlbumAccessor(albumEntry)

End Function

Public Shared Function CreateAuthenticatedRequest() As PicasaService
    Dim service As New PicasaService(ConfigurationManager.AppSettings("GData_AppName"))
    service.setUserCredentials(ConfigurationManager.AppSettings("GData_Email"), ConfigurationManager.AppSettings("GData_Password"))
    Return service
End Function

【讨论】:

    【解决方案2】:

    我知道这是较旧的,因此您可能已经有了答案。我也知道 Google 确实制作了一个 API,但使用 .net 它仅适用于 Picasa 的第一个版本,而您正尝试使用第二个版本,我也是。我看到您的帖子并认为我会为您提供答案以防您仍在尝试解决此问题,或者其他人看到该帖子并想要答案。

    我发现有几件事可能会导致您的问题。首先是您似乎将身份验证协议与版本混合并匹配。对于 Google Picasa API 的第二个版本,我相信您需要使用 OAuth2 协议,而不是 AuthSub 协议。我还没有尝试过使用 AuthSub。第二个问题是我认为您的标头中没有足够的信息(缺少内容长度、内容类型和主机[尽管在使用网络客户端时您可能不需要主机])。我发现确保我的请求运行良好(老实说一直是救命稻草)的一种方法是访问 Google 上的 OAuth2Playground:Oauth2Playground。在这里,您可以创建令牌和请求,并在成功请求时轻松查看它们的标头和发布信息。

    这是我编写的允许创建专辑的代码的 sn-p。为了创建,您必须拥有一个带有访问代码的经过身份验证的令牌(您需要首先获取用户权限并存储他们的刷新令牌,然后刷新以获取会话 access_token) access_token 在标题的授权行中传递。它还解析响应并从响应和白蛋白中获取成功变量。专辑的整个 xml 提要在响应时返回,因此您可以详细了解如何阅读并直接使用它)

    public bool CreatePicasaAlbum(GoogleUtility.Picasa.AlbumEntry.entry a, IGoogleOauth2AccessToken token)
        {
    
    
            TcpClient client = new TcpClient(picasaweb.google.com, 443);
            Stream netStream = client.GetStream();
            SslStream sslStream = new SslStream(netStream);
            sslStream.AuthenticateAsClient(picasaweb.google.com);
    
            byte[] contentAsBytes = Encoding.ASCII.GetBytes(a.toXmlPostString());
            string data = a.toXmlPostString();
    
            StringBuilder msg = new StringBuilder();
            msg.AppendLine("POST /data/feed/api/user/default HTTP/1.1");
            msg.AppendLine("Host: picasaweb.google.com");
            msg.AppendLine("Gdata-version: 2");
            msg.AppendLine("Content-Length: " + data.Length);
            msg.AppendLine("Content-Type: application/atom+xml");
            msg.AppendLine(string.Format(GetUserInfoDataString(), token.access_token));
            msg.AppendLine("");
    
            byte[] headerAsBytes = Encoding.ASCII.GetBytes(msg.ToString());
            sslStream.Write(headerAsBytes);
            sslStream.Write(contentAsBytes);
    
            StreamReader reader = new StreamReader(sslStream);
            bool success = false;
            string albumID = "";
            while (reader.Peek() > 0)
            {  
                string line = reader.ReadLine();
                if (line.Contains("HTTP/1.1 201 Created")) { success = true; }
                if (line.Contains("Location: https") && string.IsNullOrWhiteSpace(albumID))
                {
                    var aiIndex = line.LastIndexOf("/");
                    albumID = line.Substring(aiIndex + 1);
                }
                System.Diagnostics.Debug.WriteLine(line);
                if (line == null) break;
            }
            return success;
        }
    
    /// <summary>
    /// User Info Data String for Authorization on TCP requests
    /// [Authorization: OAuth {0}"]
    /// </summary>
    /// <returns></returns>
    
    private string GetUserInfoDataString()
    {
        return "Authorization: OAuth {0}";
    }
    

    对不起,我应该补充一点,我创建了一个对象,该对象返回专辑条目 xml 的提要字符串,就像您在上面所做的那样。提要 xml 与文档匹配。我将时间戳留空,因为默认标记是在您创建它时,我还没有弄清楚是否可以将任何内容放入类别中,所以我也将其留空。

    <entry xmlns='http://www.w3.org/2005/Atom' xmlns:media='http://search.yahoo.com/mrss/' xmlns:gphoto='http://schemas.google.com/photos/2007'>
        <title type='text'>Created from code</title>
        <summary type='text'>Code created this album</summary>     
        <gphoto:location>somewhere</gphoto:location>
        <gphoto:access>public</gphoto:access>
        <gphoto:timestamp></gphoto:timestamp>
        <media:group>
            <media:keywords>test, album, fun</media:keywords>
        </media:group>
        <category scheme='http://schemas.google.com/g/2005#kind' term='http://schemas.google.com/photos/2007#album'>
        </category>
    </entry>
    

    另一个编辑:IGoogleOauth2AccessToken 是我创建的另一个类,用于存放令牌详细信息。您真正需要传入的是刷新 OAuth2 令牌时获得的 access_token 字符串。我的令牌外壳代码只有 access_code、token_type,并且作为对象的一部分过期。您只需要访问令牌字符串即可进行授权。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-09-30
      • 2011-12-26
      • 2015-05-23
      • 1970-01-01
      • 1970-01-01
      • 2023-02-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多