Web-сервисы

Программирование на Атлантисе (VIP, FCOM, ARD), FastReport

Модераторы: m0p3e, edward_K, Модераторы

galover
Местный житель
Сообщения: 794
Зарегистрирован: 16 ноя 2007, 13:52

Сообщение galover »

это тебе не поможет. У тебя уже какие-то методы web сервисов запускаются, например vOrganization_InitId (нашел, что это вызов конструктора с передачей KatOrg.NRec). Сейчас рефлектором гляну что там внутрях
Vik
Местный житель
Сообщения: 370
Зарегистрирован: 28 сен 2006, 15:43
Откуда: Санкт-Петербург
Контактная информация:

Сообщение Vik »

Из описания службы:

Код: Выделить всё

- <s:element name="IOrganization_getData">
- <s:complexType>
- <s:sequence>
  <s:element minOccurs="0" maxOccurs="1" name="handle" type="tns:ifcHandle" /> 
  </s:sequence>
  </s:complexType>
  </s:element>
Vik
Местный житель
Сообщения: 370
Зарегистрирован: 28 сен 2006, 15:43
Откуда: Санкт-Петербург
Контактная информация:

Сообщение Vik »

Ну вот код:

Код: Выделить всё

    [WebMethod(EnableSession = false)]
    public IOrganization[] IOrganization_getData (ifcHandle handle)
    {
       using (InterfaceLink ifc = Services.GetObject(this,handle))
       {
          IOrganization[] data;
          int rCode = IOrganizationDater.getData ((CORGANIZATIONLib.IOrganization)ifc.link,out data);
          if (rCode == 0) return data;
          throw new Exception (String.Format ("IOrganization_getData error = {0}",rCode));
       }
    }
Мне кажется, что-то я не настроил просто..
galover
Местный житель
Сообщения: 794
Зарегистрирован: 16 ноя 2007, 13:52

Сообщение galover »

вот из рефлектора - это сборка VipServices.dll

Код: Выделить всё

public static InterfaceLink GetObject(WebService service, ifcHandle handle)
{
    if (handle.isEmpty())
    {
        throw new Exception("this is nil");
    }
    ConnectedUser user = ConnectedUser.GetUser(GetUserName(service));
    if (user == null)
    {
        throw new UnauthorizedAccessException("invalid user name");
    }
    return user.GetInterface(handle);
}

...

public InterfaceLink GetInterface(ifcHandle handle)
{
    InterfaceLink link2;
    VipInterfaceList interfaceList = this.GetInterfaceList(handle);
    InterfaceLink interfaceLink = null;
    try
    {
        Services.currentUser = this;
        Services.currentList = interfaceList;
        interfaceLink = interfaceList.GetInterfaceLink();
        if (interfaceLink == null)
        {
            interfaceLink = interfaceList.GetInterfaceLink(this.GetConnection(), false);
        }
        if (InterfaceLink.Apply(ref interfaceLink.link, handle.properties) != ifcBindResult.Ok)
        {
            throw new Exception("error in processing properties: " + handle.ToString());
        }
        interfaceLink.myUser = this;
        link2 = interfaceLink;
    }
    catch (Exception exception)
    {
        if (interfaceLink != null)
        {
            interfaceLink.Close();
        }
        else
        {
            Services.currentList = null;
            Services.currentUser = null;
        }
        throw exception;
    }
    return link2;
}
как видно из GetInterface не выбрасывается UnauthorizedAccessException. Странно все это
Vik
Местный житель
Сообщения: 370
Зарегистрирован: 28 сен 2006, 15:43
Откуда: Санкт-Петербург
Контактная информация:

Сообщение Vik »

Может вам скинуть все, что у меня есть для компилляции с моими настройками и вы попробуете запустить?) Вдруг у вас получится, или разберетесь быстрее.. Если вам интересно, конечно)
galover
Местный житель
Сообщения: 794
Зарегистрирован: 16 ноя 2007, 13:52

Сообщение galover »

Vik
я тебе в ICQ напишу
Vik
Местный житель
Сообщения: 370
Зарегистрирован: 28 сен 2006, 15:43
Откуда: Санкт-Петербург
Контактная информация:

Сообщение Vik »

В общем, после всяческих манипуляций получил такую ошибку:

Код: Выделить всё

System.Web.Services.Protocols.SoapException: Серверу не удалось обработать запрос. ---> System.InvalidCastException: Невозможно привести COM-объект типа "System.__ComObject" к интерфейсному типу "C_WEBSERVICESLib.o_vGroupMC". Операция завершилась со сбоем, поскольку вызов QueryInterface COM-компонента для интерфейса с IID "{6166253F-6535-4B21-AB3C-33F3FF37F5F7}" возвратил следующую ошибку: Интерфейс не поддерживается (Исключение из HRESULT: 0x80004002 (E_NOINTERFACE)).
   в Atlantis.Vip.ConnectedUser.GetInterface(ifcHandle handle)
   в Atlantis.Vip.Services.GetObject(WebService service, ifcHandle handle)
   в C_WEBSERVICESService.IGroupMC_getData(ifcHandle handle)
Vik
Местный житель
Сообщения: 370
Зарегистрирован: 28 сен 2006, 15:43
Откуда: Санкт-Петербург
Контактная информация:

Сообщение Vik »

Все! Если долго мучаться, что-нибудь получится! Простейший пример с получением имени организации, ее апдейтом и с созданием новой у меня получился!
galover
Местный житель
Сообщения: 794
Зарегистрирован: 16 ноя 2007, 13:52

Сообщение galover »

Vik
напиши что и как сделал, всем полезно будет
Vik
Местный житель
Сообщения: 370
Зарегистрирован: 28 сен 2006, 15:43
Откуда: Санкт-Петербург
Контактная информация:

Сообщение Vik »

Ну, в настройках безопасности виртуального каталога поставил анонимный доступ + разрешить управление паролем из IIS. Потом в файле C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config прописал имя и пароль пользователя, под которым запускается ASP, Сервер приложения галки и клиента настроил на COM - протокол, в виртуальном каталоге в файле web.cfg задал настройки

Код: Выделить всё

    <add key="Atlantis.VipService.ConnectUserName" value="<пользователь галактики>" />
    <add key="Atlantis.VipService.DefaultUserName" value="пользователь галактики" />
    <add key="Atlantis.VipService.ConnectPassword" value="пароль" /> 
В саппорте у этого пользователя поставил галочку напротив опции "может быть использован как клиент Web-сервиса".
Вроде все. После этого у меня заработал клиент из примера. А вообще с этими веб-сервисами еще долго разбираться, чет у них там все как-то сложно, а инфы никакой практически, лишь фразы типа "а подробности, извините, выходят за рамки данной документации". А где те рамки, в которые эти подробности входят, найти чет пока не получается..
galover
Местный житель
Сообщения: 794
Зарегистрирован: 16 ноя 2007, 13:52

Сообщение galover »

Да, спасибо, оказывается действительно не хватало галочки "Может использоваться как внутренний пользователь web-сервиса". Иначе вылезает
Сервер
VerifyPassword
ConnectAs rigths needed.
Всех этих граблей не было бы, если при получении соединения вызывалась функция Connect("user", "password"), а не ConnectAs("user", "password", "workUser")
дело в том, что с определением workUser основная трабла, у меня он брался как пользователь рабочей станции, а нужен Галактический (да еще с указанной выше галочкой) :(
Вообще можно обойтись и без web-сервисов, или написать свой. Схема вообще довольно простая -> по res файлу получается COM proxy, с которым собственно и работает клиент (ну или тот же web-сервис).
Если пишем на .NET, в клиентском приложении нужны ссылки на следующие сборки (это если обращаемся напрямую, в обход web сервисов):
1) VipServices.dll - набор базовых классов, классов оберток, вспомогательных функций
2) %VipComponentName%Lib.dll - обертки для vip и obj интерфейсов
3) %VipComponentName%COM.dll - еще одни обертки для тех же vip и obj интерфейсов (здесь не уловил смысл) + функции-врапперы над функциями галактических фейсов, к которым мы собственно обращаемся
4) AtlantisComDrvLib.dll (обертка над COM объектами GalSrv.App и GalApp.App, которые и выполняют всю черновую работу - передача параметров-прием данных)
Не забываем прописать пользователя и пароль (под кем будем соединяться) в App.Config. Под кем реально будем работать можно прописать в коде. Вообще все исходники легко получаются рефлектором, обфускации там нет. При желании можно собрать свои проекты и в дебаге посмотреть, как проходят системные вызовы.
У меня тестовый код получился такой:

Код: Выделить всё

using System;
using Atlantis.Vip;
using CINVOICE;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main()
        {
            // Создаем описатель (хэндлер) vip интерфейса
            // InitId - конструктор (передаваемый параметр - NRec KatSopr-а)
            var ifc = new ifcHandle("CINVOICE", "vInvoice", "InitId", new Object[] { 85849867896771336 });
            
            // Получаем собственно данные по сопроводительному документу

            // Под кем собственно будем работать 
            // (под кем будем подключаться - задаем в App.Config)
            var user = ConnectedUser.GetUser("galUser"); 
            
            var ifcLnk = user.GetInterface(ifc);
            
            IInvoice[] data;
            IInvoiceDater.getData((CINVOICELib.IInvoice)ifcLnk.link, out data);
            
            foreach (var invoice in data)
            {
                var org = (invoice.Payer != null && invoice.Payer.Length != 0) ? invoice.Payer[0].Name : null;
                var orgPlat = (invoice.Payee != null && invoice.Payee.Length != 0) ? invoice.Payee[0].Name : null;

                Console.WriteLine("Сопроводительный документ {0}\nКонтрагент: {1}\nПлательщик: {2}", invoice.Name, org, orgPlat);
            }
        }
    }
}
А вообще там такой огород, что лучше забить на это и лезть напрямую в базу из своего клиента. Данный способ будет полезен в случае, если логика работы vip интерфейса слишком хитрая, чтобы ее нельзя было воспроизвести самому - например получение складских остатков в различных разрезах
Ответить