Имя: Пароль:
1C
1C 7.7
v7: Ошибка при отправке файла как base64binary по SOAP
0 bahamut13
 
07.05.13
20:50
Здравствуйте, помогите разобраться.
В 1с7 выполняется следующий vbscript:
|Sub Send()
|Dim B64str
|set SOAPClient = createobject(""MSSOAP.SOAPClient30"")
|SoapClient.MSSOAPInit("""+ПутьКСервису+""")
|B64str = ""строка с закодированными в base64 данными""
|CALL SoapClient.SendBinary("""+login+""","""+password+""","""+gln+""","""+relation+""",""" +Имя+ """,B64str)
|End Sub

SendBinary  в WSDL файле:
<s:element name="SendBinary">
<s:complexType>
<s:sequence>
<s:element maxOccurs="1" minOccurs="0" name="Name" type="s:string"/>
<s:element maxOccurs="1" minOccurs="0" name="Password" type="s:string"/>
<s:element maxOccurs="1" minOccurs="0" name="PartnerIln" type="s:string"/>
<s:element maxOccurs="1" minOccurs="0" name="DocumentType" type="s:string"/>
<s:element maxOccurs="1" minOccurs="0" name="FileName" type="s:string"/>
<s:element maxOccurs="1" minOccurs="0" name="Data" type="s:base64Binary"/>
</s:sequence>
</s:complexType>
</s:element>

Ошибка:
Client: Client:Type conversion failure for element Data  HRESULT=0x80020005: Несовпадение типов.
- Client:Unspecified client error. HRESUL

Т.е. он вроде как не может привести строку B64str к типу base64binary? Но почему и как от этого избавиться?
На 1с8 все работает норм:
Данные = Base64Строка(Новый ДвоичныеДанные(Temp+ИмяФайла));
ВебСервис.SendBinary(Пользователь,Пароль,GLN,Реляция,ИмяФайла,Данные)
Хотя Данные также имеют тип Строка, но нужно чтобы и на 1с7 работало.
Поможет ли замена MSSOAP.SOAPClient30 на к-л другой? Или же вставку делать не на vbscript?
1 Ковычки
 
07.05.13
21:00
в 77 базе 64 делается без мсскриптконтрола
2 bahamut13
 
07.05.13
21:10
(1) да-да, я нашел несколько внешних компонент и даже метод 1с который конвертирует в base64 - но вопрос не в этом, а в том почему в данном примере возникает ошибка несоответствия типов.
То что SendBinary вызывается из vbscript прошу принять как данность - так надо и меняться если и будет, то разве что язык сей вставки.
3 ЧеловекДуши
 
08.05.13
06:19
4 ЧеловекДуши
 
08.05.13
06:24
DIME и бинарные вложения

Поскольку XML представляет собой текстовый формат, для передачи бинарных данных требуется их перекодировка, например, в кодировку base64. Это означает, что в случае передачи бинарных данных, во-первых, увеличивается время вызова, так как перекодировка в base64 занимает некоторое время, а, во-вторых, увеличивается объем данных, которые необходимо передать по HTTP.

SOAP Toolkit, начиная с версии 3.0, поддерживает новый формат HTTP-запросов, называемый DIME – Direct Internet Message Encapsulation. DIME является по сути бинарным форматом передачи данных и не требует их перекодировки. Сообщение в формате DIME представляет собой совокупность DIME-записей. Каждая запись состоит из заголовка и бинарных данных. Заголовок записи включает в себя длину записи, тип данных и идентификатор записи. Такая организация позволяет быстро найти нужную запись и прочитать данные из нее.

SOAP Toolkit использует формат DIME для передачи бинарных вложений. Преимущество передачи бинарных данных в виде вложений заключается в том, что данные будут передаваться более эффективно и на их обработку потребуется меньше времени и ресурсов.
5 ЧеловекДуши
 
08.05.13
06:26
Dim o As MSSOAPLib30.SoapClient30
Set o = New MSSOAPLib30.SoapClient30
o.MSSoapInit "D:\Projects\SOAP\Sample2\IIS\Sample2.WSDL"
Dim f As FileAttachment30
Set f = New FileAttachment30
f.FileName = "D:\as331003.zip"
o.PutFile f
6 sttt
 
08.05.13
06:37
у тебя процедура называется CALL SoapClient.SendBinary - ПередатьБинарник а ты ему строку передаешь))
7 bahamut13
 
08.05.13
09:44
(5) Угу, так было бы намного проще... но файл должен передаваться на сервер как параметр <s:element maxOccurs="1" minOccurs="0" name="Data" type="s:base64Binary"/> а не как вложение и менять серверную часть я не могу
(6) А вы знаете другое представление base64binary в vb? Я нет, потому и передаю в виде строки. Тем более что на 1с8 передача строки проходит нормально, а тут он ругается на несоответствие типов))
У кого еще какие идеи по поводу того что 1с8 воспринимает строки такого типа "0YHRgtGA0L7QutCwINGBINC30LDQutC+0LTQuNGA0L7QstCw0L3QvdGL0LzQuCDQsiBiYXNlNjQg0LTQsNC90L3Ri9C80Lg=" как base64binary, а 1с7 и vbscript не хотят?
8 Ковычки
 
08.05.13
09:57
0YHRgtGA0L7QutCwINGBINC30LDQutC+0LTQuNGA0L7QstCw0L3QvdGL0LzQuCDQ
siBiYXNlNjQg0LTQsNC90L3Ri9C80Lg=
9 Ковычки
 
08.05.13
09:58
стр="0YHRgtGA0L7QutCwINGBINC30LDQutC+0LTQuNGA0L7QstCw0L3QvdGL0LzQuCDQ" "siBiYXNlNjQg0LTQsNC90L3Ri9C80Lg=";
10 bahamut13
 
08.05.13
11:50
(9) А это вообще к чему? Если про то что не пытался ли я делать что-то типа хардкодного
B64str = ""0YHRgtGA0L7QutCwINGBINC30LDQutC+0LTQuNGA0L7QstCw0L3QvdGL0LzQuCDQsiBiYXNlNjQg0LTQsNC90L3Ri9C80Lg=""
то да - пытался, не прошло... может в vb есть специальный тип для base64binary?
11 Ковычки
 
08.05.13
11:56
читайте вниматель (8) и (9)
12 bahamut13
 
08.05.13
12:19
(11) И-и? Даже B64str = ""0Ks="" не отправляется. vb просто не хавает строки как base64biary. Любой длинны. Любого символьного состава. Как убедить vb или MSSOAP.SOAPClient30 что данная строка есть base64biary?
Неужели придется самому xml-запрос составлять (что-то такое где-то видел, но надо еще вспомнить и найти) для сервера и так работать?
13 Ковычки
 
08.05.13
13:06
//*******************************************
Процедура Сформировать()
   ХТМЛ = СоздатьОбъект("htmlfile");
   ХТМЛ.Open("text/html");
   //<-- Подготовим нужные методы
   ХТМЛ.Write("<script language='vbscript'>
   |function xxx(x):xxx=split(x,chr(0)):end function
   |</script><script language='javascript'>
   |МассивИзСтроки=function(x){return new VBArray(xxx(x.split('').join('\0')))}
   |</script>");
   Док=ХТМЛ.documentElement.document;
   // Все подготовке -->
   Это=Док.Script;

   Стр="0YHRgtGA0L7QutCwINGBINC30LDQutC+0LTQuNGA0L7QstCw0L3QvdGL0LzQuCDQsiBiYXNlNjQg0LTQsNC90L3Ri9C80Lg=";
   Сообщить(Это.МассивИзСтроки(Стр).ubound(1));
КонецПроцедуры
14 bahamut13
 
08.05.13
14:35
В общем думаю остановиться на следующем варианте:

Запрос=СоздатьОбъект("MSXML2.DOMDocument");
Запрос.loadXML("
|<soapenv:Envelope xmlns:soapenv=""http://schemas.xmlsoap.org/soap/envelope/"" xmlns:com=""http://www.comarch.com/"">
|<soapenv:Header/>
|<soapenv:Body>
|   <com:SendBinary>
|      <com:Name>"+login+"</com:Name>
|      <com:Password>"+password+"</com:Password>
|      <com:PartnerIln>"+iln+"</com:PartnerIln>
|      <com:DocumentType>"+relation+"</com:DocumentType>
|      <com:FileName>"+name+"</com:FileName>
|      <com:Data>"+data+"</com:Data>
|   </com:SendBinary>
|</soapenv:Body>
|</soapenv:Envelope>");
Попытка
xmlHttp = СоздатьОбъект("MSXML2.xmlHttp");
xmlHttp.OPEN ("POST", url, 0);
xmlHttp.setRequestHeader ("SOAPAction", action);
xmlHttp.setRequestHeader ("Host", host);
xmlHttp.setRequestHeader ("Content-type", "text/xml");
xmlHttp.SEND (Запрос);
Ответ=xmlHttp.responseText;
Исключение
Сообщить(ОписаниеОшибки());
Возврат;
КонецПопытки;

с помощью soapUI получил текст запроса и параметры setRequestHeader на основе wsdl файла... посмотрю еще максимальный размер отсылаемого файла и может придется опять все на vbscript переводить, но это не слишком сложно - главное не придирается к содержимому переменной data =)
15 ЧеловекДуши
 
08.05.13
14:37
(12) А зачем тебе это, попробуй фалик просто указать :)
Выдавать глобальные идеи — это удовольствие; искать сволочные маленькие ошибки — вот настоящая работа. Фредерик Брукс-младший