在.net的picasa中创建新相册

本文关键字:创建 新相册 picasa net | 更新日期: 2023-09-27 18:07:50

我试图发布一个相册到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();
}

在.net的picasa中创建新相册

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

我知道这是旧的,所以你可能已经有答案了。我也知道,谷歌确实做了一个API,但与。net它只适用于Picasa的第一个版本,你正试图与版本2工作,我也是。我看到了你的帖子,我想我会为你提供一个答案,以防你还在努力解决这个问题,或者其他人看到这篇文章,想要一个答案。

我看到了一些可能导致你的问题的事情。首先,您似乎将身份验证协议与版本混合和匹配。对于Google Picasa API的第二个版本,我认为您需要使用OAuth2协议,而不是AuthSub协议。我还没有尝试过AuthSub。第二个问题是,我不相信你有足够的信息在你的头(缺少内容长度,内容类型和主机[虽然你可能不需要主机时使用一个web客户端])。我发现的一种确保我的请求工作良好的方法(老实说,这是一种拯救)是去Google上的OAuth2Playground: OAuth2Playground。在这里,你可以创建你的令牌和请求,并很容易地看到他们的头和发布信息时,成功的请求。

下面是我编写的一段允许创建专辑的代码片段。为了创建,您必须有一个带有访问代码的经过身份验证的令牌(您可能希望首先获得用户权限并存储他们的刷新令牌,然后刷新以获得会话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和expires作为对象的一部分。您只需要授权的访问令牌字符串。