16.09.2013, 14:35 | #1 |
Участник
|
DAX 2009 SP1 Business Connector: SEHException при вызове CallStaticClassMethod
Приветствую. Пытаюсь вызывать static метод аксапты из внешнего C#-пового приложения через Business Connector, в данном методе делается выборка из таблицы с последующей записью результата в Xml (XmlDocument), при вызове на стороне программки получаю SEHException.
Код: в AxCore_CallStatic(Char* , Char* , tagVARIANT* , Int32 , tagVARIANT* ) в Microsoft.Dynamics.BusinessConnectorNet.Axapta.CallStaticClassMethod(String className, String methodName, Object[] paramList) в RevSvc.AxConnector.CallAxMethod(String className, String methodName, Object[] parameters) Что можно сделать в этом случае? возращать контейнер не вариант, т.к. при 200000 элементах преобразование внутри коннектора выполняется около часа. P.S. Методы, где не используется XMLDocument вызываются из Business Connector'a прекрасно |
|
16.09.2013, 15:23 | #2 |
Участник
|
У вас вызываемый статический метод ведь, скорее всего, на сервере XML-ку формирует? А обратно возвращается именно Xml (строка) или же XmlDocument (ссылка на серверный объект)? Если просто из Аксапты джобиком дернуть этот же метод, нормально отрабатывает?
|
|
17.09.2013, 07:42 | #3 |
Участник
|
Цитата:
Цитата:
Джобиком эта функция прекрасно вызывается и возвращает требуемый результат |
|
17.09.2013, 10:16 | #4 |
Участник
|
Активно использую коннектор .Net для возврата XML и подобных проблем не замечено, думаю тут нужно смотреть уже конкретно ваш код статического метода и С#, опубликуйте.
|
|
17.09.2013, 14:39 | #5 |
Участник
|
А на какого размера XML-документах это все валится, любого или только на больших (>4Mb)? И если на больших, то джобиком вы тоже большой документ генерите или же просто мелкий тестовый?
|
|
18.09.2013, 09:11 | #6 |
Участник
|
Цитата:
X++: public server static container mel_getInventTableWithBarcodeListXml(RBOID _rboid, RBOItemHierarchy _rboitemhierarchy) { InventTable inventTable; InventItemBarcode inventItemBarcode; container con = connull(); XmlDocument ItmXml; XmlElement ItmRoot; XmlElement ItmNode; XmlElement ItmField; XmlDocument BarXml; XmlElement BarRoot; XmlElement BarNode; XmlElement BarField; ; ItmXml = XmlDocument::newBlank(); BarXml = XmlDocument::newBlank(); ItmRoot = ItmXml.createElement(@"DocumentElement"); BarRoot = BarXml.createElement(@"DocumentElement"); ItmXml.appendChild(ItmRoot); BarXml.appendChild(BarRoot); while select inventTable where inventTable.InventStatus == DKL_InventStatus::Active && (_rboItemHierarchy == RBOItemHierarchy::BusinessGroup && inventTable.MEL_BusinessGroup == _rboid) || (_rboitemhierarchy == RBOItemHierarchy::DivisionGroup && inventTable.MEL_DivisionGroup == _rboid) || (_rboitemhierarchy == RBOItemHierarchy::RetailDepartment && inventTable.MEL_ItemDepartment == _rboid) || (_rboitemhierarchy == RBOItemHierarchy::RetailGroup && inventTable.MEL_RetailGroup == _rboid) { ItmNode = ItmXml.createElement(@"I"); ItmRoot.appendChild(ItmNode); ItmField = ItmXml.createElement(@"ItemId"); ItmField.innerText(inventTable.ItemId); ItmNode.appendChild(ItmField); ItmField = ItmXml.createElement(@"Description"); ItmField.innerText(inventTable.ItemName); ItmNode.appendChild(ItmField); ItmField = ItmXml.createElement(@"Article"); ItmField.innerText(inventTable.MEL_Article); ItmNode.appendChild(ItmField); ItmField = ItmXml.createElement(@"Price"); ItmField.innerText(num2str(inventTable.dkl_baseRetailPrices().BasePrice, 0, 8, 1, 0)); ItmNode.appendChild(ItmField); while select inventItemBarcode where inventItemBarcode.itemId == inventTable.ItemId { BarNode = BarXml.createElement(@"B"); BarRoot.appendChild(BarNode); BarField = BarXml.createElement(@"ItemId"); BarField.innerText(inventTable.ItemId); BarNode.appendChild(BarField); BarField = BarXml.createElement(@"Barcode"); BarField.innerText(inventItemBarcode.itemBarCode); BarNode.appendChild(BarField); } } con = [ItmXml.toString(), BarXml.toString()]; return con; } Код: //вызов object Ret = ax.CallAxMethod("PosIsTransactionService", "mel_getInventTableWithBarcodeListXml", new object[] { BusinessGroup, ItemHierarchy }); //Обёртка public object CallAxMethod(string className, string methodName, params object[] parameters) { if (AxConn == null) return null; object res = null; try { log.Write("AxConn.CallAxMethod({0}, {1})", className, methodName); res = AxConn.CallStaticClassMethod(className, methodName, parameters); } catch (BusinessConnectorException bex) { log.Write("AxConn.Logon BusinessConnectorException: {0} {1}", bex.ToString(), bex.Message); log.Write("AxConn.Logon BusinessConnectorException stack: {0}", bex.StackTrace); return null; } catch (Exception ex) { log.Write("AxConn.CallAxMethod Exception: {0} {1}", ex.ToString(), ex.Message); log.Write("AxConn.CallAxMethod Exception stack: {0}", ex.StackTrace); return null; } return res; } Цитата:
P.S. Не пинайте сильно, я только учусь Последний раз редактировалось _sharky_; 18.09.2013 в 09:15. |
|
18.09.2013, 10:16 | #7 |
Участник
|
Я бы не стал использовать аксаптовский контейнер для возврата значений, это довольно специфичный тип данных, но если уж так хочется, тогда в C# надо использовать тип данных AxaptaContainer.
Возвращайте XML в виде текста. Для теста попробуйте переделать свой статический метод на возврат XML в виде string одного из ваших XML документов, должно работать. |
|
18.09.2013, 10:26 | #8 |
Участник
|
Дык ить!.. В этом-то и загвоздка: в 2009-й есть ограничение в 4Мб на размер данных, передаваемых по значению, см., например, Падает клиент при прикреплении файла, поэтому на маленьких объемах может прокатывать, а на больших - падать. А вообще, лучше включите трассировку на клиенте и на сервере и воспроизведите падение - по трассировке потом (с помощью TraceParcer'а) можно будет точно локализовать, в каком именно месте валится обработка.
|
|
18.09.2013, 11:53 | #9 |
Участник
|
Цитата:
Сообщение от gl00mie
Дык ить!.. В этом-то и загвоздка: в 2009-й есть ограничение в 4Мб на размер данных, передаваемых по значению, см., например, Падает клиент при прикреплении файла, поэтому на маленьких объемах может прокатывать, а на больших - падать. А вообще, лучше включите трассировку на клиенте и на сервере и воспроизведите падение - по трассировке потом (с помощью TraceParcer'а) можно будет точно локализовать, в каком именно месте валится обработка.
X++: public static container mel_getInventTableWithBarcodeList(RBOID _rboid, RBOItemHierarchy _rboitemhierarchy) { return PosIsTransactionService::mel_getInventTableWithBarcodeListXml(_rboid, _rboitemhierarchy); } |
|
Теги |
business connector, sehexception |
|
|