Почему веб-сервис 1С возвращает Неопределено и как исправить ошибку «Значение не является значением объектного типа (Name)»?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При интеграции систем на платформе 1С:Предприятие с внешними приложениями или другими базами данных разработчики часто выбирают механизм Web-сервисов (SOAP). Это надежное и стандартизированное решение, однако его настройка требует предельной точности. Малейшее несовпадение в конфигурации пакетов XDTO, URI пространств имен или метаданных веб-сервиса приводит к тому, что клиентское приложение получает пустое значение (Неопределено), порождая трудночитаемые ошибки в коде.

В этой статье мы подробно разберем, почему возникает популярная ошибка «Значение не является значением объектного типа (Name)», проанализируем исходный код интеграции, выявим архитектурные неточности и покажем пошаговый алгоритм их устранения.

Анализ исходной ситуации и кода

Рассмотрим ситуацию, с которой столкнулся разработчик. В базе-источнике опубликован веб-сервис со следующей функцией:


Функция GetOborotyScheta() 
    ЗаявкаТип = ФабрикаXDTO.Тип("http://192.16.0.176/request", "Schet");
    Заявка = ФабрикаXDTO.Создать(ЗаявкаТип);
    Заявка.Name = "11111";
    Возврат Заявка;
КонецФункции

В базе-приемнике написана обработка для получения этих данных:


Процедура ВыводДанныхИзВебСервиса()
    Определение = Новый WSОпределения("http://backup:****@172.16.0.176/buh1c_V831CDEV/ws/Vase/request.1cws?wsdl");
    Прокси = Новый WSПрокси(Определение, "http://172.16.0.176/request", "Vase" , "VaseSoap");       
    Прокси.Пользователь="backup";
    Прокси.Пароль="******";
    ДанныеЗаявки = Прокси.GetOborotyScheta();
    Предупреждение(Строка(ДанныеЗаявки.Name));
КонецПроцедуры

При выполнении этого кода система выдает ошибку:

{ВнешняяОбработка.ВнешняяОбработка1.Форма.Форма.Форма(15)}: Значение не является значением объектного типа (Name)

Давайте разберем по шагам, почему переменная ДанныеЗаявки оказалась равна Неопределено, и какие скрытые механизмы платформы 1С повлияли на этот результат.

Причина 1: Непонимание сути пространства имен (Namespace URI)

Обратите внимание на адреса, которые используются в кодовой базе веб-сервиса и обработки:

Выясним причину этой нестыковки. Начинающие разработчики часто путают сетевой адрес сервера (физический IP-адрес) и URI пространства имен в пакете XDTO. URI пространства имен — это чисто логический уникальный идентификатор (строка), используемый XML-анализатором для разграничения типов данных. Он абсолютно не обязан быть реальной работающей веб-ссылкой и не должен меняться при переносе базы на другой сервер или изменении его IP-адреса.

Если в коде метода ФабрикаXDTO.Тип() указан URI, который хотя бы на один символ отличается от пространства имен, прописанного в свойствах вашего пакета XDTO в конфигураторе, метод вернет Неопределено. Соответственно, попытка выполнить ФабрикаXDTO.Создать(Неопределено) завершится неудачей или вернет пустой объект, который не сможет быть передан клиенту.

Причина 2: Неверная настройка возвращаемого типа операции в метаданных

Чтобы платформа 1С могла корректно упаковать (сериализовать) сложный объект XDTO и передать его через SOAP-протокол, ей необходимо точно знать его тип еще на этапе разбора WSDL-схемы.

Проанализируем свойства операции веб-сервиса в конфигураторе. Очень часто разработчики совершают ошибку, оставляя свойство «Тип возвращаемого значения» пустым, либо выбирая там базовые типы вроде string или anyType (из стандартного пространства имен XML-схем).

Если функция веб-сервиса возвращает сложный объект (в нашем случае тип Schet), а в свойствах операции возвращаемый тип настроен неверно, платформа не сможет преобразовать объект XDTO в XML-пакет. В результате при вызове метода через WSПрокси на стороне клиента будет получено значение Неопределено.

Причина 3: Кэширование WSDL-описаний веб-сервером

При изменении структуры XDTO-пакетов или настроек операции веб-сервиса в конфигураторе изменения могут не вступать в силу на клиенте. Почему это происходит?

Публикация веб-сервиса происходит на стороне веб-сервера (IIS или Apache). Эти серверы очень жестко кэшируют файлы описания SOAP-сервисов (файлы с расширением .1cws и их схемы WSDL). Даже если вы обновили конфигурацию базы данных и перезапустили сеанс 1С, веб-сервер может продолжать отдавать клиентам старую структуру схемы. Клиент обращается к методу по устаревшим правилам, не находит нужных свойств и возвращает Неопределено.

Пошаговый алгоритм решения проблемы

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

Шаг 1: Приведение пространств имен к единому стандарту

Откажитесь от использования динамических IP-адресов в качестве пространств имен XDTO-пакетов. Задайте вашему пакету XDTO постоянное, уникальное символическое имя.

Например, в свойствах пакета XDTO в конфигураторе установите:

ПространствоИмен: http://www.mycompany.ru/buh/request

После этого скорректируйте код создания объекта в модуле веб-сервиса:


Функция GetOborotyScheta() 
    // Используем жестко заданное пространство имен, независимое от IP сервера
    ЗаявкаТип = ФабрикаXDTO.Тип("http://www.mycompany.ru/buh/request", "Schet");
    
    Если ЗаявкаТип = Неопределено Тогда
        ЗаписатьЛогСобытий("Не удалось инициализировать тип 'Schet'. Проверьте XDTO-пакет!");
        Возврат Неопределено;
    КонецЕсли;
    
    Заявка = ФабрикаXDTO.Создать(ЗаявкаТип);
    Заявка.Name = "11111";
    Возврат Заявка;
КонецФункции

Шаг 2: Настройка свойств операции веб-сервиса в конфигураторе

Откройте свойства операции веб-сервиса в дереве метаданных конфигурации:

  1. Найдите ваш Web-сервис, разверните ветку Операции и выберите нужную функцию (например, GetOborotyScheta).
  2. В палитре свойств найдите поле Тип возвращаемого значения.
  3. Нажмите на кнопку выбора и найдите ваш XDTO-пакет http://www.mycompany.ru/buh/request.
  4. Выберите из него тип данных Schet.
  5. Убедитесь, что свойство Возможно пустое значение установлено в соответствии с бизнес-логикой вашей задачи.

Шаг 3: Сброс кэша веб-сервера и очистка определений

После внесения изменений в конфигурацию базы данных обязательно выполните следующие действия:

  1. Обновите конфигурацию базы данных (нажмите F7 в конфигураторе).
  2. Перезапустите веб-сервер. Если вы используете IIS, выполните в командной строке от имени администратора команду iisreset. Если используется Apache, перезапустите соответствующую службу Windows или процесс демона в Linux.
  3. На стороне клиента принудительно очистите кэш WS-определений. При создании объекта WSОпределения платформа кэширует WSDL локально. Чтобы этого избежать при отладке, можно временно отключать кэширование или использовать динамическое имя файла.

Шаг 4: Корректный вызов веб-сервиса на стороне клиента

На стороне вызывающей системы (клиента) мы должны использовать фабрику XDTO конкретного прокси-объекта, а не глобальную фабрику конфигурации. Это защитит нас от несоответствия версий метаданных. Перепишем клиентскую процедуру:


Процедура ВыводДанныхИзВебСервиса()
    
    // Подключаемся к опубликованному веб-сервису
    ПутьКWsdl = "http://172.16.0.176/buh1c_V831CDEV/ws/Vase/request.1cws?wsdl";
    
    Попытка
        Определение = Новый WSОпределения(ПутьКWsdl, "backup", "******");
        
        // Важно: Пространство имен в WSПрокси должно строго соответствовать пространству имен веб-сервиса в метаданных!
        Прокси = Новый WSПрокси(Определение, "http://www.mycompany.ru/buh/request", "Vase", "VaseSoap");
        Прокси.Пользователь = "backup";
        Прокси.Пароль = "******";
        
        // Получаем данные от сервера
        ДанныеЗаявки = Прокси.GetOborotyScheta();
        
        Если ДанныеЗаявки = Неопределено Тогда
            ВызватьИсключение "Сервер вернул пустое значение. Проверьте отладчиком внутреннее состояние серверного метода.";
        КонецЕсли;
        
        // Выводим полученное значение свойства
        Предупреждение("Получено значение свойства Name: " + Строка(ДанныеЗаявки.Name));
        
    Исключение
        ЗаписьЖурналаРегистрации("Интеграция.WebСервисы", УровеньЖурналаРегистрации.Ошибка, , , ПодробноеПредставлениеОшибки(ИнформацияОбОшибке()));
        ВызватьИсключение "Произошла ошибка при обращении к Web-сервису: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
    КонецПопытки;
    
КонецПроцедуры

Как настроить отладку веб-сервиса для локализации ошибок

Если веб-сервис по-прежнему возвращает пустые данные, нам поможет серверная отладка. По умолчанию отладка веб-сервисов (которые исполняются в контексте фоновых заданий веб-сервера) отключена. Давайте включим её:

  1. Если база серверная, запустите службу агента сервера «1С:Предприятие» с ключом -debug.
  2. В конфигураторе базы-источника (где опубликован веб-сервис) перейдите в меню Отладка -> Подключение.
  3. В открывшемся окне нажмите кнопку Автоматическое подключение и установите флажок напротив пункта Web-сервисы.
  4. Поставьте точку останова на первой строчке вашей функции GetOborotyScheta() в модуле веб-сервиса.
  5. Запустите вызов из клиентской базы. Выполнение кода приостановится на сервере, и вы сможете в реальном времени через Табло проверить, возвращает ли метод ФабрикаXDTO.Тип() корректное описание типа или инициализирует его как Неопределено.

Применяя предложенные правила организации пространств имен и контроля типов, вы навсегда избавитесь от неожиданных ошибок сериализации в ваших интеграционных механизмах 1С.

← На главную