Я знаю, что это старше, поэтому у вас уже может быть ответ. Я также знаю, что Google делает API, но с .net он работает только для первой версии Picasa, и вы пытаетесь работать со второй версией, как и я. Я наткнулся на ваш пост и подумал, что предложу вам ответ если вы все еще пытаетесь решить эту проблему или кто-то другой сталкивается с постом и хочет получить ответ.
Я вижу несколько вещей, которые могут быть причиной вашей проблемы. Во-первых, вы, кажется, смешиваете и сопоставляете протокол аутентификации с версией. Я полагаю, что для второй версии API Google Picasa вам нужно использовать протокол OAuth2, а не протокол AuthSub. Я не пробовал с AuthSub. Вторая проблема заключается в том, что я не думаю, что у вас достаточно информации в заголовках (отсутствует длина контента, тип контента и хост [хотя вам может не понадобиться хост при использовании веб-клиента]). Один способ, который я нашел, чтобы убедиться, что мои запросы работают хорошо (и, честно говоря, был спасатель), это перейти на OAuth2Playground в Google: 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 - это еще один класс, который я создал для размещения сведений о токене. То, что вам действительно нужно передать, это строка access_token, которую вы получаете, когда обновляете токен OAuth2. Мой код размещения токена просто имеет access_code, token_type и истекает как часть объекта. Вам просто нужна строка токена доступа для авторизации.