Создание информационного блока, в который будут добавляться новости:
Для того чтобы начать что-то добавлять, нужно определиться куда мы будем это делать. В нашем случае необходим информационный блок с некоторыми свойствами. Для простоты возьмем уже готовый информационный блок "Новости магазина" из демо-версии "Бизнеса" 6.5. Запомним что его ID #33.
Создание компонента веб-сервиса для добавления новостей:
Теперь необходимо приступать непосредственно к созданию самого веб-сервиса.
При установке модуля "Веб-сервисов" создается новый компонент bitrix:webservice.server. Он предназначен для простого создания, тестирования и вывода в читабельном виде информации о ваших веб-сервисах. Для нашего веб-сервиса он будет являться "сервером".
Сначала создадим свой новый компонент. Для этого создадим новую папку в /bitrix/components/demo, назовем ее webservice.addnews. Как и любой другой компонент 2.0, наш компонент веб-сервиса должен содержать стандартные файлы описаний:
Файл .description.php:
<? if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die(); $arComponentDescription = array( "NAME" => "Веб сервис добавления новостей", "DESCRIPTION" => "Веб сервис добавления новостей", "CACHE_PATH" => "Y", "PATH" => array( "ID" => "service", "CHILD" => array( "ID" => "webservice", "NAME" => "Веб-сервис добавления новостей." ) ), ); ?> |
Файл .parameters.php:
<? if (!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die(); $arComponentParameters = array( "GROUPS" => array(), "PARAMETERS" => array(), ); ?> |
И исполняемый файл component.php. Создадим первоначально его в следующем виде:
<? if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true) die(); if(!CModule::IncludeModule("webservice") || !CModule::IncludeModule("iblock")) return; // наш новый класс наследуется от базового IWebService class CAddNewsWS extends IWebService { // метод GetWebServiceDesc возвращает описание сервиса и его методов function GetWebServiceDesc() { $wsdesc = new CWebServiceDesc(); $wsdesc->wsname = "bitrix.webservice.addnews"; // название сервиса $wsdesc->wsclassname = "CAddNewsWS"; // название класса $wsdesc->wsdlauto = true; $wsdesc->wsendpoint = CWebService::GetDefaultEndpoint(); $wsdesc->wstargetns = CWebService::GetDefaultTargetNS(); $wsdesc->classTypes = array(); $wsdesc->structTypes = Array(); $wsdesc->classes = array(); return $wsdesc; } } $arParams["WEBSERVICE_NAME"] = "bitrix.webservice.addnews"; $arParams["WEBSERVICE_CLASS"] = "CAddNewsWS"; $arParams["WEBSERVICE_MODULE"] = ""; // передаем в компонент описание веб-сервиса $APPLICATION->IncludeComponent( "bitrix:webservice.server", "", $arParams ); die(); ?> |
Это минимальное содержимое для определения веб-сервиса. Как видно он содержит наследованный от IWebService класс CAddNewsWS, переопределенный метод GetWebServiceDesc, возвращающий описание сервиса в формате CWebServiceDesc и вызов компонента bitrix:webservice.server, которому в качестве параметров передается описание нашего зарождающегося веб-сервиса.
Самое время посмотреть - работает или нет? Для этого создадим новую страницу, разместим наш новый компонент на нее и сохраним, например, под именем /ws_addnews.php:
Откроем ее на сайте:
Как мы видим, появилось описание нашего веб-сервиса. Но у него нет ни одного метода. Значит, приступим к его созданию. Для этого нам потребуется добавить в наш класс новый метод, который принимает на вход в качестве параметров некоторые поля новости, а в качестве результата возвращает ID добавленной новости или ошибку:
function AddNews($NAME, $DATE, $PREVIEW_TEXT, $DETAIL_TEXT, $KEYWORDS, $SOURCE) { $iblock_permission = CIBlock::GetPermission(33); if ($iblock_permission < "W") { $GLOBALS["USER"]->RequiredHTTPAuthBasic(); return new CSOAPFault('Server Error', 'Unable to authorize user.'); } $arFields = Array( "IBLOCK_ID"=>33, // инфоблок "Новости магазина" "NAME"=>$NAME, "DATE_ACTIVE_FROM"=>$DATE, "PREVIEW_TEXT"=>$PREVIEW_TEXT, "DETAIL_TEXT"=>$DETAIL_TEXT, "PROPERTY_VALUES" => Array( "KEYWORDS"=>$KEYWORDS, "SOURCE"=>$SOURCE, ) ); $ib_element = new CIBlockElement(); $result = $ib_element->Add($arFields); if($result>0) return Array("id"=>$result); return new CSOAPFault( 'Server Error', 'Error: '.$ib_element->LAST_ERROR ); } |
Зарегистрируем новый метод в массиве $wsdesc->classes:
$wsdesc->classes = array( "CAddNewsWS"=> array( "AddNews" => array( "type" => "public", "input" => array( "NAME" => array("varType" => "string"), "DATE" => array("varType" => "string"), "PREVIEW_TEXT" => array("varType" => "string"), "DETAIL_TEXT" => array("varType" => "string"), "KEYWORDS" => array("varType" => "string"), "SOURCE" => array("varType" => "string"), ), "output" => array( "id" => array("varType" => "integer") ), "httpauth" => "Y" ), ) ); |
В массиве содержится название класса и названия методов, с описанием входных и выходных параметров.
Вот и все, теперь если обновить страницу, на которой расположен компонент, то мы сможем увидеть, что появился новый метод и более того, можем протестировать его работу непосредственно из браузера:
Создание приложения:
Теперь можно приступать к завершающему этапу - созданию в Visual Studio простого Windows приложения. Для этого можно скачать и установить одну из бесплатных Express версий, например для C#.
Далее идем по шагам:
Создаем новый проект:
На вкладке Solution Explorer создаем новую "Web reference":
Указываем ссылку на страницу с компонентом, нажимаем "Go". В окне открывается уже знакомая нам страница с описанием сервиса, нажимаем на ней ссылку "описание службы", Visual Studio считывает доступные методы и предлагает нам создать для них прокси-классы, переименовываем название в myws.addnews и нажимаем "Add reference".
Теперь приступаем к созданию непосредственно самого окна ввода новости, для этого разместим на форме необходимые поля и кнопку "Отправить":
Двойным кликом по кнопке открываем обработчик события нажатия на кнопку и размещаем код сохраняющий новость на сайте:
private void button1_Click(object sender, EventArgs e) { bitrixwebserviceaddnews news = new bitrixwebserviceaddnews(); news.Credentials = new NetworkCredential("admin", "password"); try { string result = news.AddNews(DATE.Text, DETAIL_TEXT.Text, KEYWORDS.Text, NAME.Text, PREVIEW_TEXT.Text, SOURCE.Text); MessageBox.Show("Новость №"+result+" успешно добавлена."); } catch (System.Web.Services.Protocols.SoapHeaderException exception) { MessageBox.Show("Ошибка добавления новости [" + exception.Message + "]"); } } |
Компилируем приложение, запускаем, заполняем поля, нажимаем отправить:
Убедимся, что новость действительно попала к нам на сайт:
В данной статье я показал очень простой пример, чтобы не усложнять первое восприятие Конечно, данный веб-сервис можно дорабатывать, например, чтобы в параметрах компонента можно было управлять - в какой инфоблок, какую информацию добавлять, поддержку произвольных свойств и т.п. В свою очередь, Windows приложение можно доработать, например, чтобы оно выгружало новости на сайт "пачками", содержало больше полей и настроек. Все ограничено фантазией и временем, но зато, как видим, не ограничено возможностями и инструментами для воплощения их в жизнь.
Исходный код компонента:
Исходный код приложения:
PS: Кстати, попробовал создать аналогичное приложение для своего телефона htc p3300, получилось
Для этого придется на стороне Windows приложения читать файл, конвертировать его при помощи System.Convert.ToBase64String в BASE64, а на стороне компонента конвертировать назад функцией base64_decode, сохранять его во временный файл и передавать на вход методу CIBlockElement:Add(), как одно из полей. Помимо этого, нам необходимо знать на сервере как минимум расширение (тип) файла, поэтому вместе с содержимым будем передавать оригинальное имя файла.
Таким образом вот так будет выглядеть наш класс веб-сервиса в компоненте:
А вот так обработчик нажатия на кнопку в Windows приложении (IMAGE - это новый контрол на форме, в нем должен быть путь к файлу на диске):
The method or operation is not implemented.
и выделение желтым
string result = news.AddNews(
ACTIVE.Text,
DATE_ACTIVE_FROM.Text,
DATE_ACTIVE_TO.Text,
DETAIL_TEXT.Text,
KEYWORDS.Text,
base64String,
IMAGE.Text,
NAME.Text,
PREVIEW_TEXT.Text);
Знает ли кто-нибудь, можно ли создать Web reference в Delphi, C++ Builder?
Конечно можно каждый раз передавать логин и пароль (в чистом или шифрованном виде), но это скорее похоже на костыль, чем на решение.
Я всего лишь хотел показать, как просто создавать приложения для обмена данными и управления сайтом, используя модуль веб-сервисов и .NET. А ситуаций когда это действительно может кому-то пригодиться, я думаю, жизнь преподнесет еще не мало
Очень интересно и полезно!
Полет фантазии о возможностях использования сложно остановить...
Представленная технология очень полезна и перспективна!
У меня уже масса идей в голове по поводу применения всего этого.
Большое спасибо!!!
Error 1 The type or namespace name 'bitrixwebserviceaddnews' could not be found (are you missing a using directive or an assembly reference?)
и т.д
using System.Net;
using WindowsApplication2.myws.addnews;
Просто, когда в Visual Studio вводишь типы из новых пространств, то VS подчеркивает класс красной черточкой и предлагает вставить строки автоматически, поэтому фактически я этих строк и не писал.
событие на кнопку
в компоненте
В итоге получаю ошибку от БУС что не введено название, в какой последовательности передаются данные из приложения в бус ?
Ну или можно попробовать пересортировать параметры в методе вручную.
У меня проблемка с сервисом наоборот. Мне нужен сервис, который отдаст данные приложению.
Написал все так же, как и в статье. Опробовал через Веб-интерфейс. Работает.
Начинаю через приложение - ошибка XML-данных. Пространство имен в ответе пустое, в то время как при коннекте к Веб-сервису оно заполнено.
Приложение MS InfoPath.
Юрий, а можно ли дополнить рецепт добавлением в инфоблок из PDF-формы или формы InfoPath? Или это из другой серии?
З.Ы.: а исходники для коммуникатора есть?
Автору ПИВО! 8)
А как сделать редактирование допустим той же статьи?