Создание нового альбома в Picasa в .NET - PullRequest
3 голосов
/ 08 сентября 2011

Я пытаюсь опубликовать альбом в 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();
}

Ответы [ 2 ]

4 голосов
/ 08 сентября 2011

Google создает удобный API для интеграции с Picasa [.net]:

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
1 голос
/ 29 августа 2012

Я знаю, что это старше, поэтому у вас уже может быть ответ. Я также знаю, что 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 и истекает как часть объекта. Вам просто нужна строка токена доступа для авторизации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...