Подключение к веб-сервисам 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.