在.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();
}
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作为对象的一部分。您只需要授权的访问令牌字符串。