понедельник, 18 июня 2012 г.

C# работа с VK через API

Для создания приложения, которое при работе контактирует с контактом надо заметить, что есть множество вариантов. Можно импортировать готовую библиотеку vkAPI, или написать свой фрагмент кода, который осуществляет взаимодействие с сайтом vk.com. Написание своего будет разумны, если вы не доверяете создателю библиотеки и предполагаете, что она может иметь среди функций что то вредоносное. Также это можно делать уменьшения размера программы, но разница там в несколько килобайт...

Сразу скажу, что через http пытаться авторизовать в контакте бессмысленно и сложно. Это может подойти только для чекеров фэйков и подбора паролей. Но этим заниматься не советую.

Рассмотрим сначала способ без использования библиотек, чтобы понять суть и технологию работы. Делается это при помощи создания окна браузера, где проходит авторизация или проверка на авторизованность аккаунта. Следом сделаем запрос на получение нужных нам данных.

Выглядит это так:


        private Form main_form;
        private string access_token = null;
        private string user_id = null;

        const int AppID = 1;
        const string vkMethodURL = "https://api.vkontakte.ru/method/";

        public string AccessToken
        {
            get { return this.access_token; }
        }
        public string UserID
        {
            get { return this.user_id; }
        }

        public vkAPI(Form main_form)
        {
            this.main_form = main_form;
        }

        public bool isAuthorized()
        {
            if (access_token == null || user_id == null) return false;

            //дописать проверку на время действия access_token, чтобы не посылать всегда лишний запрос

            string profiles = vkMethodURL+"getProfiles?uid=1&access_token=" + access_token;

            System.Net.WebRequest reqGET = System.Net.WebRequest.Create(profiles);
            System.Net.WebResponse resp = reqGET.GetResponse();
            System.IO.Stream stream = resp.GetResponseStream();
            System.IO.StreamReader sr = new System.IO.StreamReader(stream);
            string s = sr.ReadToEnd();

            JObject o = JObject.Parse(s);
            JObject error = (JObject)o["error"];

            if (error == null) return true;
            else return false;
        }

        public bool Authorize()
        {
            if (isAuthorized()) return true;

            AuthForm authform = new AuthForm();
            WebBrowser browser = (WebBrowser)authform.Controls["webBrowser"];
            browser.Navigated += new WebBrowserNavigatedEventHandler(Authorize_proceed);
            browser.Navigate("http://api.vkontakte.ru/oauth/authorize?client_id="+AppID.ToString()+
                "&scope=photos&redirect_uri="+
                "http://api.vkontakte.ru/blank.html&display=popup&response_type=token&hash=0");
            authform.ShowDialog();

            if (access_token == null || user_id == null)
            {
                MessageBox.Show("Авторизация не пройдена!\r\nДля работы программы вы должны авторизироваться!\r\nЗапрос авторизации появится автоматически.","Внимание!",MessageBoxButtons.OK,MessageBoxIcon.Warning);
                return false;
            }
            else return true;
        }

        private void Authorize_proceed(object sender, WebBrowserNavigatedEventArgs e)
        {
            string[] parts = e.Url.AbsoluteUri.Split('#');
            WebBrowser browser = (WebBrowser)sender;
            AuthForm authform = (AuthForm)browser.Parent;

            if (parts[0] == "http://api.vkontakte.ru/blank.html")
            {
                if (parts[1].Substring(0, 5) == "error") authform.Close();

                else if (parts[1].Substring(0, 12) == "access_token")
                {
                    //MessageBox.Show("Complete!");
                    parts = parts[1].Split('&');

                    access_token = parts[0].Split('=')[1];
                    user_id = parts[2].Split('=')[1];
                    authform.Close();
                }
            }
            else
            {
                parts = e.Url.AbsoluteUri.Split('?');
                if (parts[0] == "http://api.vkontakte.ru/oauth/grant_access")
                    browser.Navigate("http://api.vkontakte.ru/oauth/authorize?client_id=" + AppID.ToString() + "&scope=photos&redirect_uri=http://api.vkontakte.ru/blank.html&display=popup&response_type=token&hash=0");
            }
        }

        //Тестовая функция API
        public string[] GetMyProfile()
        {
            Authorize();

            string profiles = vkMethodURL + "getProfiles?uid=" + user_id + "&fields=photo_medium_rec,sex,bdate,online&access_token=" + access_token;

            System.Net.WebRequest reqGET = System.Net.WebRequest.Create(profiles);
            System.Net.WebResponse resp = reqGET.GetResponse();
            System.IO.Stream stream = resp.GetResponseStream();
            System.IO.StreamReader sr = new System.IO.StreamReader(stream);
            string s = sr.ReadToEnd();
            //MessageBox.Show(s);
            JObject o = JObject.Parse(s);
            JArray response = (JArray)o["response"];

            string[] profile = new string[6];
            profile[0] = (string)response[0]["first_name"];
            profile[1] = (string)response[0]["last_name"];
            //profile[2] = (string)response[0]["sex"];
            if ((int)response[0]["sex"] == 1) profile[2] = "Женский";
            else profile[2] = "Мужской";
            profile[3] = (string)response[0]["photo_medium_rec"];
            profile[4] = (string)response[0]["bdate"];
            if ((int)response[0]["online"] == 1) profile[5] = "онлайн";
            else profile[5] = "не онлайн";

            return profile;
        }


Эти функции можно перенести в отдельный класс и дать ему название vkAPI.
После этого к нашему классу можно обращаться и извлекать полученные данные.
Покажу пример на своей форме:


    public partial class MainForm : Form
    {
         //Объявляем наличие класса
        vkAPI api;

        public MainForm()
        {
            InitializeComponent();
            //Создаём экземпляр класса
            api = new vkAPI(this);
            api.Authorize();
        }

        private void GetProfile_Click(object sender, EventArgs e)
        {
            string[] prof=api.GetMyProfile();
            //MessageBox.Show(prof[2]);
            pictureBox1.ImageLocation = prof[3];
            label1.Text = prof[0];
            label2.Text = prof[1];
            label3.Text = prof[2];
            label4.Text = prof[4];
            label5.Text = prof[5];
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string[] prof = api.GetHisProfile(textBox1.Text);
            //MessageBox.Show(prof[3]);
            pictureBox1.ImageLocation = prof[3];
            label1.Text = prof[0];
            label2.Text = prof[1];
            label3.Text = prof[2];
            label4.Text = prof[4];
            label5.Text = prof[5];
        }
        
    }

Сама форма в моём случае выглядела так:


Вот исходник этого проекта C#.
vk.rar 454 KB

Далее рассмотрим уже другой пример, с использованием библиотеки vk api core, которую можно скачать тут.

ApiCore.dll 63.0 KB
Для данной работы я выбрал уже готовый исходник, который нашёл когда-то давно в интернете.

Программа умеет отправлять на стену сообщение тому, чей ID будет указан. Сработает если аккаунт авторизован и если всё будет удовлетворять настройкам приватности.

Вот функция, которая делает авторизацию. Она использует при работе библиотеку apicore.dll. Импорт делать обязательно.


        private void Connect()
        {
            if (!this.isLoggedIn)
            {
                SessionManager sm = new SessionManager(2834598, Convert.ToInt32(ApiPerms.ExtendedWall));
                this.sessionInfo = sm.GetSession();
                if (this.sessionInfo != null)
                {
                    this.isLoggedIn = true;
                    manager = new ApiManager(this.sessionInfo);
                    manager.Timeout = 10000;
                    wallFactory = new WallFactory(manager);
                    panel1.Visible = true;
                }
            }



        private void button1_Click(object sender, EventArgs e)
        {
            try
            {
                Connect();

            }
            catch
            {
                MessageBox.Show("Internal error");
            }
        }



Далее пример функции, которая отправляет сообщение на стену:


        private void PostWall()
        {
            try
            {
                if (this.sessionInfo != null)
                {
                    idUser = textBox1.Text;
                    messtext = textBox2.Text;

                    idnum = Convert.ToInt32(idUser);
                    wallFactory.Post(idnum, messtext);
                }
            }
            catch (ApiRequestErrorException ex)
            {
                MessageBox.Show(ex.Code.ToString() + "\n" + ex.Description);
            }
        }
        private void button2_Click(object sender, EventArgs e)
        {
            PostWall();
        }

Обязательно надо объявить в самом начала переменные, которые используются в программе. Если это вызывает трудности, то вот фрагмент кода, где они все есть:

        private SessionInfo sessionInfo;
        private ApiManager manager;

        private bool isLoggedIn = false;
        private string idUser;
        private int idnum;
        private string messtext;

        public bool onstat;
        private WallFactory wallFactory;

Вставить их надо перед этим:

        public Form1()
        {
            InitializeComponent();  
            
        }

Таким образом выглядит форма у меня:


Вот исходник данного проекта:

vkwall.rar 64.3 KB

Точно также можно использовать любые функции библиотеки apicore.
Их список и описание можно посмотреть в обозревателе объектов.

5 коммент.:

Анонимный комментирует...

почему 2 способ не работает? не могу авторизироватся нажимаю разрешить и никаких действий..

Unknown комментирует...

+1

Анонимный комментирует...

Пожалуйста перезалейте архивы!

Анонимный комментирует...

Перезалейте архивы плиз.

Unknown комментирует...
Этот комментарий был удален автором.

Отправить комментарий

TROCKII БЛОГ Copyright © 2012 | Template created by Lev Trockii |