Подключение к веб-сервисам NAV из C# при помощи Service Reference (вариант с написанием кода)

Прежде чем приступить к чтению этой статью, ознакомьтесь с заметкой


connecting to NAV Web Services from C# using Service Reference (config file version) .

Code is king

Как вы уже наблюдали в прошлой заметке, файл конфигурации – довольно сложен и, хотя он поддается редактированию вручную (во время инсталляции или позже), я все-таки предпочитаю прописать определенный набор установок прямо в коде, и только очень специфичные настройки править непосредственно в файле конфигурации (например, свойство BaseURL).

При работе с NAV, вам никогда не получить полный URL службы для всех служб (в файле конфигурации). Это означает, что вам придется поменять название фирмы в определенном числе мест в конфиге – ужасно.

Если взглянуть на конфиг еще раз, то видно, что есть т.н. «Binding Configuration», в которой указывается BasicHttpBinding с рядом настроек. Если мы хотим провести это связывание на уровне коде, нужно сделать примерно следующее:

// создаем NAV-совместимое связывание (binding)

BasicHttpBinding navWSBinding = new BasicHttpBinding();
navWSBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
navWSBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

Имея этот класс связывания, теперь создаем systemService Service Client:

SystemService_PortClient systemService = new SystemService_PortClient(navWSBinding, new EndpointAddress(baseURL + «SystemService»));

Задание адреса точки выхода (endpoint address) в конструкторе.

Все, что нам осталось сделать – это задать поведение в endpoint для разрешения делегирования. Это делается в коде следующим образом:

systemService.ClientCredentials.Windows.AllowedImpersonationLevel =
System.Security.Principal.TokenImpersonationLevel.Delegation;
systemService.ClientCredentials.Windows.AllowNtlm = true;

Применение данного кода фактически делает файл app.config рудиментом, и вы можете совсем удалить его при запуске приложения (ниже).

Полное приложение

Ниже приведен полный листинг консольного приложения, в котором все свойства задаются через код, а app.config не требуется (не используется):

using System;
using System.Net;
using testAppWCF.SystemServiceRef;
using testAppWCF.CustomerPageRef;
using System.ServiceModel;

namespace testAppWCF
{
class Program
{
static void Main(string[] args)
{
string baseURL = «http://localhost:7047/DynamicsNAV/WS/»;

// Create a NAV compatible binding
BasicHttpBinding navWSBinding = new BasicHttpBinding();
navWSBinding.Security.Mode = BasicHttpSecurityMode.TransportCredentialOnly;
navWSBinding.Security.Transport.ClientCredentialType = HttpClientCredentialType.Windows;

// Create the SystemService Client
SystemService_PortClient systemService = new SystemService_PortClient(navWSBinding, new EndpointAddress(baseURL + «SystemService»));
systemService.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Delegation;
systemService.ClientCredentials.Windows.AllowNtlm = true;

Console.WriteLine(«Companies:»);
string[] companies = systemService.Companies();
foreach(string company in companies)
Console.WriteLine(company);
string cur = companies[0];

string customerPageURL = baseURL + Uri.EscapeDataString(cur) + «/Page/Customer»;
Console.WriteLine(«\nURL of Customer Page: «+customerPageURL);

// Create the Customer Page Service Client
Customer_PortClient customerService = new Customer_PortClient(navWSBinding, new EndpointAddress(customerPageURL));
customerService.ClientCredentials.Windows.AllowedImpersonationLevel = System.Security.Principal.TokenImpersonationLevel.Delegation;
customerService.ClientCredentials.Windows.AllowNtlm = true;

Customer customer10000 = customerService.Read(«10000»);
Console.WriteLine(«\nName of Customer 10000: «+customer10000.Name);

Customer_Filter filter1 = new Customer_Filter();
filter1.Field = Customer_Fields.Country_Region_Code;
filter1.Criteria = «GB»;

Customer_Filter filter2 = new Customer_Filter();
filter2.Field = Customer_Fields.Location_Code;
filter2.Criteria = «RED|BLUE»;

Console.WriteLine(«\nCustomers in GB served by RED or BLUE warehouse:»);
Customer_Filter[] filters = new Customer_Filter[] { filter1, filter2 };
Customer[] customers = customerService.ReadMultiple(filters, null, 0);
foreach (Customer customer in customers)
Console.WriteLine(customer.Name);

Console.WriteLine(«\nTHE END»);
Console.ReadLine();
}
}
}

Если вам надо указать другое имя/пароль, это делается так же, как делалось для Service Reference’ов при использовании файлов конфигурации.

Наше приложение выдает ровно то же самое, что и приложение, использовавшее Service Reference’ы и файл конфигурации. То есть в итоге

This application will output exactly the same as the application using Service References and a config file, in the end the config file is just a number of settings which will be used to instantiate a number of classes from – giving the same result.

Надеюсь, что эта статья поможет вам в работе.

Удачи!

Оригинал заметки доступен здесь: http://blogs.msdn.com/b/freddyk/archive/2010/01/20/connecting-to-nav-web-services-from-c-using-service-reference-code-version.aspx

Автор:

В области Navision - с 2003 года. Профессиональные интересы: NAV, MS SQL, .NET, BPMN, IT-менеджмент. Предметная область: логистика, финансы, склады, 3PL.

Количество статей, опубликованных автором: 86.

Добавить комментарий