Всем привет, не давно меня попросили настроить интеграцию с внешним сервисом, я приступил к работе и после подумал, возможно кому то может пригодиться такой функционал, т.к. по большей части все взаимодействия между системами не находящимися в одном домене или просто закрытые по соглашению с вендером, они частенько так делают, в договоре это обычно прописано. Но сейчас не об этом, в общем на примере, одного погодного сервиса покажу как обмениться данными через JSON между приложениями.
Кому лень читать, проект доступен для скачивания в конце статьи.
Остальные, поехали.
1) Заходим на сайт openweathermap.org и регистрируемся.
2) После регистрации вам придет письмо, примерно такое.
3) Что в нем важно, во первым там есть API Key, а во вторых пример обращения к удаленному сервису. Важный момент, если я правильно понял, у них какой то временной лаш между регистрацией нового ключа у себя и отправкой письма, письмо приходит практически сразу, а вот ключ точно будет действовать через 30 минут.
4) Переходим в Visual Studio и создаем WinForms проект.
5) Называем его WeatherJson
6) Переходим в код файла Form1.cs
7) Добавляем библиотеки System.Net и System.IO — первая нужна для отправки и получения запроса на сервер, вторая нужна для обработки ответа с сервера.
8) Также нам необходимо добавить к проекту внешнюю библиотеку Newtonsoft, для этого нужно сделать следующее:
9) Добавляем библиотеку Newtonsoft.Json;
10) Теперь переходим на форму и добавляем элемент TextBox, выставляем св-во Multiline значение true и растягиваем его по вертикали и горизонтали.
11) Теперь нажимаем на форму 2 раза левой кнопкой мыши, произойдет переход в код, там создаться метод private void Form1_Load(object sender, EventArgs e)
12) В нем пишем следующее:
13) Запускаем, проверяем — получаем ответ, такого вида:
14) Теперь давайте разберемся, что конкретно присылает сервер
***Важный момент с сайта необходимо скачать погодные иконки находятся здесь https://openweathermap.org/weather-conditions, положить нужно в проект(в папку debug).
15) Теперь нужно определить какого типа данные нам присылает сервер.
16) Теперь нам нужно создать все эти классы. Начнем с класса «coord»:
class coord { public double lat { get; set; } //Обязательно только public и только св-ва. public double lon { get; set; } //Обязательно только public и только св-ва. }
17) Теперь класс «weather»:
class weather { public int id { get; set; } public string main { get; set; } public string description { get; set; } public string icon { get; set; } public Bitmap Icon { get { return new Bitmap(Image.FromFile($"icon/{icon}.png")); } } }
18) Класс main:
class main { public double temp { get; set; } public int pressure { get; set; } public int humidity { get; set; } public double temp_min { get; set; } public double temp_max { get; set; } }
19) Класс «wind»
class wind { public int speed { get; set; } public int deg { get; set; } }
20) Класс «clouds»
class clouds { public int all { get; set; } }
21) Класс «sys»
class sys { public int type { get; set; } public int id { get; set; } public double message { get; set; } public string country { get; set; } public long sunrise { get; set; } public long sunset { get; set; } }
22) Теперь основной класс «openweather» в который будем записывать ответ сервера.
class openweather { public coord coord { get; set; } public weather[] weather { get; set; } [JsonProperty("base")] //так как слово base является ключевым для C# необходимо воспользоваться параметром, он как бы подменяет имя. public string base1 { get; set;} public main main { get; set; } public int visibility { get; set; } public wind wind { get; set; } public clouds clouds { get; set; } public long dt { get; set; } public sys sys { get; set; } public int id { get; set; } public string name { get; set; } public int cod { get; set; } }
23) Возвращаемся в файл Form1.cs и изменяем его.
private void Form1_Load(object sender, EventArgs e) { //В кавычки вам лучше вставить свою строку из письма, которое пришло вам на почту при регистрации, просто заменим London на Moskow и убрав uk. WebRequest req = WebRequest.Create(@"http://api.openweathermap.org/data/2.5/weather?q=Moscow&APPID=a5ca6c5692978d29d84474e9f351648c"); req.Method = "POST"; //Вот тут пришлось погуглить так как не редко тип у каждого свой, в итоге нашел в одном из проектов на github. req.ContentType = "application/x-www-urlencoded"; string str = ""; //!!!Новая строка openweather openweather;//!!!Новая строка. WebResponse response = req.GetResponse(); using (Stream s = response.GetResponseStream()) //Пишем в поток. { using (StreamReader r = new StreamReader(s)) //Читаем из потока. { str = r.ReadToEnd(); //!!!Изменения } } response.Close(); //Закрываем поток textBox1.Text = str; //Это оставляем для отладки. openweather = JsonConvert.DeserializeObject<openweather>(str); //Ключевой момент, загоняем ответ сервера в нашу переменную типа openweather. }
24) Добавляем на форму новые элементы для проверки — Кучу label и один panel для иконки.
25) Переходим обратно в Form1.cs и присваиваем значение label`ам и загоняем иконку в panel. Теперь файл Form1.cs выглядит так.
private void Form1_Load(object sender, EventArgs e) { //В кавычки вам лучше вставить свою строку из письма, которое пришло вам на почту при регистрации, просто заменим London на Moskow и убрав uk. WebRequest req = WebRequest.Create(@"http://api.openweathermap.org/data/2.5/weather?q=Moscow&APPID=a5ca6c5692978d29d84474e9f351648c"); req.Method = "POST"; //Вот тут пришлось погуглить так как не редко тип у каждого свой, в итоге нашел в одном из проектов на github. req.ContentType = "application/x-www-urlencoded"; string str = ""; openweather openweather; WebResponse response = req.GetResponse(); using (Stream s = response.GetResponseStream()) //Пишем в поток. { using (StreamReader r = new StreamReader(s)) //Читаем из потока. { str = r.ReadToEnd(); //!!!Изменения } } response.Close(); //Закрываем поток textBox1.Text = str; //Это оставляем для отладки. openweather = JsonConvert.DeserializeObject<openweather>(str); //Ключевой момент, загоняем ответ сервера в нашу переменную типа openweather. label7.Text = openweather.clouds.all.ToString(); //Облачность. label9.Text = openweather.main.pressure.ToString(); //Давление. label10.Text = openweather.wind.speed.ToString(); //Скорость ветра. label11.Text = openweather.main.temp.ToString(); //Тепмпература в фарингейтах сейчас. label12.Text = openweather.main.temp_min.ToString(); //Тепмпература в фарингейтах min на сегодня. label13.Text = openweather.main.temp_max.ToString(); //Тепмпература в фарингейтах max на сегодня. //Стоит помнить, что массив заполняется однократно, а значит все обращения будут только в 0 элементам массива weather. panel1.BackgroundImage = openweather.weather[0].Icon; //Иконка текущей погоды. }
25) Запускаем, проверяем.
А теперь, так сказать для интерактива, могу вам посоветовать, сделать полноценную программу, с выводом полной информации.
1) Уберите textBox1, отладка завершена, он дольше не нужен.
2) Переведите фаренгейты в градусы.
3) Добавьте к каждому значению, единицы измерения.
4) Добавить таймер чтобы получать актуальную информацию о погоде, но значение нужно рассчитать так чтобы кол-во запросов не превышало лимит в 40к.\месяц — отведенный для бесплатного использования.
Если нужно сделать еще примеры с использованием C#+JSON, но в другом разрезе, пишите в комментах, по возможности, реализую.
Спасибо за статью
Спасибо за «теплые» слова.
Спасибо за статью, но можете разобрать пример когда нужно из API достать JSON и записать данные в базу mssql(2012, до 16 т.к. в ней есть встроенная работа с Json) и обратно.
Приветствую, в ближайшее время сделаю расширенную версию с упором на ваши пожелания.
Добрый день! А если у меня класс динамичный?
К примеру :
{
«users»:{
«User_9239120321»: { // вот здесь меняются цифры после User_
}
}
}
Как мне получить именно эти цифры ?
Не уверен что это возможно, вам проще будет передать цифры в качестве одного из параметров на веб сервис, и внутри сервиса уже обрабатывать нужным образом.
А если так «JObject.ChildrenTokens, которое получает все дочерние элементы». Только я не понимаю, как применить.
sorry за спам, но вот. Через адские костыли. Я сделал.
JObject o = JObject.Parse(File.ReadAllText(@json));
string jselection = o.SelectToken(«users»).ToString();
string[] outputString = jselection.Split(‘,’);
string resultString = string.Join(string.Empty, Regex.Matches(outputString[0], @»\d+»).OfType().Select(m => m.Value));
на выходе получаем число в виде строки то, что надо «2312312312»
я сделал так
JObject o = JObject.Parse(File.ReadAllText(@jsonFile));
string parseString = o.SelectToken(«users»).ToString();
и получил вот это :
{
«USER_21123123» : {
и все, что внутри
}
}
осталось понять, как выдернуть строку с USER_ (USER_ не меняется, только числа)
ну а отделить числа от букв, это легко.
Спасибо за хороший пример.