Web-сервисы
Модераторы: m0p3e, edward_K, Модераторы
-
- Местный житель
- Сообщения: 370
- Зарегистрирован: 28 сен 2006, 15:43
- Откуда: Санкт-Петербург
- Контактная информация:
Из описания службы:
Код: Выделить всё
- <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>
-
- Местный житель
- Сообщения: 370
- Зарегистрирован: 28 сен 2006, 15:43
- Откуда: Санкт-Петербург
- Контактная информация:
Ну вот код:
Мне кажется, что-то я не настроил просто..
Код: Выделить всё
[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));
}
}
вот из рефлектора - это сборка VipServices.dll
как видно из GetInterface не выбрасывается UnauthorizedAccessException. Странно все это
Код: Выделить всё
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;
}
-
- Местный житель
- Сообщения: 370
- Зарегистрирован: 28 сен 2006, 15:43
- Откуда: Санкт-Петербург
- Контактная информация:
В общем, после всяческих манипуляций получил такую ошибку:
Код: Выделить всё
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)
-
- Местный житель
- Сообщения: 370
- Зарегистрирован: 28 сен 2006, 15:43
- Откуда: Санкт-Петербург
- Контактная информация:
Ну, в настройках безопасности виртуального каталога поставил анонимный доступ + разрешить управление паролем из IIS. Потом в файле C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\CONFIG\web.config прописал имя и пароль пользователя, под которым запускается ASP, Сервер приложения галки и клиента настроил на COM - протокол, в виртуальном каталоге в файле web.cfg задал настройки
В саппорте у этого пользователя поставил галочку напротив опции "может быть использован как клиент Web-сервиса".
Вроде все. После этого у меня заработал клиент из примера. А вообще с этими веб-сервисами еще долго разбираться, чет у них там все как-то сложно, а инфы никакой практически, лишь фразы типа "а подробности, извините, выходят за рамки данной документации". А где те рамки, в которые эти подробности входят, найти чет пока не получается..
Код: Выделить всё
<add key="Atlantis.VipService.ConnectUserName" value="<пользователь галактики>" />
<add key="Atlantis.VipService.DefaultUserName" value="пользователь галактики" />
<add key="Atlantis.VipService.ConnectPassword" value="пароль" />
Вроде все. После этого у меня заработал клиент из примера. А вообще с этими веб-сервисами еще долго разбираться, чет у них там все как-то сложно, а инфы никакой практически, лишь фразы типа "а подробности, извините, выходят за рамки данной документации". А где те рамки, в которые эти подробности входят, найти чет пока не получается..
Да, спасибо, оказывается действительно не хватало галочки "Может использоваться как внутренний пользователь web-сервиса". Иначе вылезает
дело в том, что с определением 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. Под кем реально будем работать можно прописать в коде. Вообще все исходники легко получаются рефлектором, обфускации там нет. При желании можно собрать свои проекты и в дебаге посмотреть, как проходят системные вызовы.
У меня тестовый код получился такой:
А вообще там такой огород, что лучше забить на это и лезть напрямую в базу из своего клиента. Данный способ будет полезен в случае, если логика работы vip интерфейса слишком хитрая, чтобы ее нельзя было воспроизвести самому - например получение складских остатков в различных разрезах
Всех этих граблей не было бы, если при получении соединения вызывалась функция Connect("user", "password"), а не ConnectAs("user", "password", "workUser")Сервер
VerifyPassword
ConnectAs rigths needed.
дело в том, что с определением 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);
}
}
}
}