/// <summary> /// Обработка входящего сообщения /// </summary> /// <param name="message"></param> /// <param name="ctx"></param> /// <returns><c>true</c>, если сообщение было успешно обработано, иначе <c>false</c></returns> private bool ProcessMessage(Message message, ClientContext ctx) { var documentId = string.Empty; try { if (message.Documents.Length > 0) foreach (var document in message.Documents) { documentId = document.Id; ProcessIncomingDocument(message, document); } // обрабатываем подписи присланные от получателей документов var signsFromRecipient = message.Signs.Where(s => message.Documents.All(d => d.Id != s.DocumentId)).ToList(); foreach (var sign in signsFromRecipient) if (string.IsNullOrEmpty(sign.ParentId)) { documentId = sign.DocumentId; ProcessSign(sign); } return true; } catch (ServerException ex) { // при загрузке сообщений, загружаются все сообщения // включая те, которые содержат документы, к которым // нет доступа у текущего пользователя, поэтому при // обнаружении такого документа, пропускаем сообщение if (ex.Code == ServiceErrorCode.AccessDeniedError) { UserInput.Warning( "Не доступа к документу {0}. Загрузка сообщения {1} пропущена.", documentId, message.Id); return false; } throw; } }
/// <summary> /// Обработка запуска консольного приложения с параметрами командной строки /// </summary> /// <param name="args">аргументы \ параметры запуска из командной строки</param> public void Run(string[] args) { var url = args[0]; // Выбор нужной конечной точки в клиенте для возможности подключения по URL как по http, так и по https var configEndpointName = url.StartsWith("https") ? "WSHttpsBinding_IExchangeService" : "WSHttpBinding_IExchangeService"; // принять url var client = new Client(url, false, false, _applicationVersion, configEndpointName); try { _context = new ClientContext { ServiceClient = client }; // аутентификация Auth(client); // следующие команды ... var commandsMap = new Dictionary<string, Tuple<Action, string>> { {"get-boxes", Tuple.Create<Action,string>(Boxes, "Показать список ящиков")} , {"set-box", Tuple.Create<Action,string>(SetBox, "Выбрать ящик")} , {"load-messages", Tuple.Create<Action,string>(LoadMessages, "Загрузить и обработать входящие сообщения")}, {"send-docs", Tuple.Create<Action,string>(() => SendDocuments(FlowType.SentSigned), "Отправить документы")}, {"send-unsigned", Tuple.Create<Action,string>(() => SendDocuments(FlowType.SentUnsigned), "Отправить документы без подписи")}, {"send-forward", Tuple.Create<Action,string>(() => SendDocuments(FlowType.SentForward), "Переслать документы")}, {"send-internal", Tuple.Create<Action,string>(() => SendDocuments(FlowType.SentInternal), "Отправить документы подразделению")}, {"sign-document", Tuple.Create<Action,string>(SignDocument, "Подписать документ")}, {"reject-sign", Tuple.Create<Action,string>(RejectSign, "Отказать в подписании документа")}, {"move-docs", Tuple.Create<Action,string>(MoveDocuments, "Переместить документы в подразделение")}, {"get-doc-entries", Tuple.Create<Action,string>(GetDocumentEntries, "Список вхождений документов")}, {"get-doc-inner", Tuple.Create<Action,string>(GetInternalDocuments, "Список внутренних документов")}, {"get-doc-list", Tuple.Create<Action,string>(GetDocumentList, "Список документов")}, {"get-doc-info", Tuple.Create<Action,string>(GetDocumentInfo, "Загрузить документ")}, {"get-doc-flow", Tuple.Create<Action,string>(GetDocumentFlow, "Загрузить документ c вхождениями")}, {"get-draft-list", Tuple.Create<Action,string>(GetDraftMessageList, "Список черновиков")}, {"get-draft", Tuple.Create<Action,string>(GetDraftMessage, "Загрузить черновик")}, {"del-draft", Tuple.Create<Action,string>(DeleteDraftMessage, "Удалить черновик")}, {"get-contacts", Tuple.Create<Action,string>(GetActiveContacts, "Список активных контактов")}, {"del-contact", Tuple.Create<Action,string>(DeleteContact, "Удалить контакт")}, {"get-structure", Tuple.Create<Action,string>(GetOrganizationStructure, "Дерево орг.структуры")}, {"add-department", Tuple.Create<Action,string>(AddOrganizationStructureElement, "Добавить подразделение")}, {"edit-department", Tuple.Create<Action,string>(EditOrganizationStructureElement, "Изменить подразделение")}, {"del-department", Tuple.Create<Action,string>(DeleteOrganizationStructureElement, "Удалить подразделение")}, {"accept-reg", Tuple.Create<Action,string>(AcceptRegulation, "Принять Правила Synerdocs")}, {"add-doc-tag", Tuple.Create<Action,string>(AddDocumentTag, "Создать дополнительный статус(тэг) к документу")}, {"del-doc-tag", Tuple.Create<Action,string>(DeleteDocumentTag, "Удалить дополнительный статус(тэг), прикрепленный к документу")}, {"get-doc-tag", Tuple.Create<Action,string>(GetDocumentTag, "Показать информацию по дополнительному статусу(тэгу)")}, {"add-promocode", Tuple.Create<Action,string>(AddOrganizationPromoCode, "Добавить промокод в организацию")}, {"get-promocode-list", Tuple.Create<Action,string>(GetOrganizationPromoCodeList, "Список промокодов организации")}, {"get-promocode", Tuple.Create<Action,string>(GetPromoCodeByName, "Получить промокод")}, {"del-promocode", Tuple.Create<Action,string>(DeleteOrganizationPromoCode, "Удалить промокод")}, {"get-messages-without-content", Tuple.Create<Action,string>(GetMessagesWithoutDocumentsSignsContent, "Загрузить входящие сообщения без содержимого документов и подписей")}, {"send-revocation-offer", Tuple.Create<Action,string>(SendRevocationOffer, "Отправить ПОА")}, {"send-statement", Tuple.Create<Action,string>(SendStatementOfInvoiceReglament, "Отправить заявление об участии в ЭДО СФ")}, {"download-flow", Tuple.Create<Action,string>(DownloadDocumentFlowArchive, "Скачать документооборот в архиве")}, {"parse-document", Tuple.Create<Action,string>(TryParseDocumentContentFromFile, "Распарсить документ")}, {"download-pdf", Tuple.Create<Action,string>(DownloadPdfDocument, "Скачать документ в формате pdf")}, }; PrintAvailableCommnads(commandsMap); // выбираем первый доступный ящик var firstAvailableBox = client.GetBoxes().FirstOrDefault(); if (firstAvailableBox == null) { throw new InvalidOperationException("У пользователя нет доступа ни к одному ящику"); } _context.CurrentBox = firstAvailableBox.Address; _context.CurrentOrganizationId = firstAvailableBox.OrganizationId; _context.LoadLastProcessedMessageId(); _context.MessageFactory = new MessageFactory(_context.ServiceClient, _context.CurrentBox); if (string.IsNullOrWhiteSpace(_context.Login)) { var userInfo = client.GetUserInfo(_context.CurrentBox); _context.Login = userInfo.Login; } while (true) { UserInput.Write(ConsoleColor.White, ">"); var line = UserInput.ReadLine(); if (commandsMap.ContainsKey(line)) { try { commandsMap[line].Item1(); } catch (InputCanceledException) { Console.Out.WriteLine("Команда прервана"); } catch (Exception ex) { UserInput.Error("При выполнении команды произошла неожиданная ошибка"); UserInput.Error(ex.ToString()); } } else { UserInput.Error("Неправильно указано имя команды \"{0}\"", line); PrintAvailableCommnads(commandsMap); } } // интерактивная консоль для ввода // ввод значений списочных параметров по номерам // > auth // выберите сертификат // [email protected] [1] // [email protected] [2] // Сертификат [1]> // // Подтверждения // Отправить файлы? [Y/n]> } catch (InputCanceledException) { // Ctrl+C Console.Out.WriteLine(); Console.Out.WriteLine("Выход"); } catch (Exception ex) { UserInput.Error("Произошла неожиданная ошибка"); UserInput.Error(ex.ToString()); } }
/* Пример демонстрирует: * [+] авторизация по логину паролю * [+] авторизация по сертификату * [+] отправка подписанного НД * [+] подписание НД * [+] отказ от подписи под НД * [+] отправка ИОД для НД * [+] прием СД для НД (ИОП, УОУ, Подпись) * [+] отправка ЭСФ * [+] отправка СД для ЭСФ * [+] прием СД для ЭСФ * [+] работа с черновиками сообщений * [-] работа с контактами * [+] отправка нескольких документов * [+] обработка ошибок * [-] SSL * [+] загрузка большого документа (>1Мб) * [-] повторная отправка сообщения * [+-] загрузка, сохранение документа и документооборота на диск * [+] отображение подписи входящего документа */ public void Run(string[] args) { var url = args[0]; // Выбор нужной конечной точки в клиенте, т.к. конфиг не позволяет задать это одновременно простым способом // нужно, чтобы можно было заходить как по http, так и по https через консольный клиент // Bug 7733:В консольном клиенте не работает авторизация var configEndpointName = url.StartsWith("https") ? "WSHttpsBinding_IExchangeService" : "WSHttpBinding_IExchangeService"; // принять url var client = new Client(url, enableTracing: false, useStreamRequest: false, configEndpointName: configEndpointName); try { context = new ClientContext { ServiceClient = client, //MessageFactory = new MessageFactory(client) }; // аутентификация Auth(client); // следующие команды ... var commandsMap = new Dictionary<string, Tuple<Action, string>>() { {"get-boxes", Tuple.Create<Action,string>(Boxes, "Показать список ящиков")} , {"set-box", Tuple.Create<Action,string>(SetBox, "Выбрать ящик")} , {"load-messages", Tuple.Create<Action,string>(LoadMessages, "Загрузить и обработать входящие сообщения")}, {"send-docs", Tuple.Create<Action,string>(() => SendDocuments(FlowType.SentSigned), "Отправить документы")}, {"send-unsigned", Tuple.Create<Action,string>(() => SendDocuments(FlowType.SentUnsigned), "Отправить документы без подписи")}, {"send-forward", Tuple.Create<Action,string>(() => SendDocuments(FlowType.SentForward), "Переслать документы")}, {"send-internal", Tuple.Create<Action,string>(() => SendDocuments(FlowType.SentInternal), "Отправить документы подразделению")}, {"sign-document", Tuple.Create<Action,string>(SignDocument, "Подписать документ")}, {"reject-sign", Tuple.Create<Action,string>(RejectSign, "Отказать в подписании документа")}, {"move-docs", Tuple.Create<Action,string>(MoveDocuments, "Переместить документы в подразделение")}, {"get-doc-entries", Tuple.Create<Action,string>(GetDocumentEntries, "Список вхождений документов")}, {"get-doc-inner", Tuple.Create<Action,string>(GetInternalDocuments, "Список внутренних документов")}, {"get-doc-list", Tuple.Create<Action,string>(GetDocumentList, "Список документов")}, {"get-doc-info", Tuple.Create<Action,string>(GetDocumentInfo, "Загрузить документ")}, {"get-doc-flow", Tuple.Create<Action,string>(GetDocumentFlow, "Загрузить документ c вхождениями")}, {"get-draft-list", Tuple.Create<Action,string>(GetDraftMessageList, "Список черновиков")}, {"get-draft", Tuple.Create<Action,string>(GetDraftMessage, "Загрузить черновик")}, {"del-draft", Tuple.Create<Action,string>(DeleteDraftMessage, "Удалить черновик")}, {"get-contacts", Tuple.Create<Action,string>(GetActiveContacts, "Список активных контактов")}, {"del-contact", Tuple.Create<Action,string>(DeleteContact, "Удалить контакт")}, {"get-structure", Tuple.Create<Action,string>(GetOrganizationStructure, "Дерево орг.структуры")}, {"add-department", Tuple.Create<Action,string>(AddOrganizationStructureElement, "Добавить подразделение")}, {"edit-department", Tuple.Create<Action,string>(EditOrganizationStructureElement, "Изменить подразделение")}, {"del-department", Tuple.Create<Action,string>(DeleteOrganizationStructureElement, "Удалить подразделение")}, {"accept-reg", Tuple.Create<Action,string>(AcceptRegulation, "Принять Правила Synerdocs")}, // {"outmsg", OuntgoingMessages}, }; PrintAvailableCommnads(commandsMap); // // выбираем первый доступный ящик var firstAvailableBox = client.GetBoxes().FirstOrDefault(); if (firstAvailableBox == null) { throw new InvalidOperationException("У пользователя нет доступа ни к одному ящику"); } context.CurrentBox = firstAvailableBox.Address; context.CurrentOrganizationId = firstAvailableBox.OrganizationId; context.LoadLastProcessedMessageId(); context.MessageFactory = new MessageFactory(context.ServiceClient, context.CurrentBox); while (true) { UserInput.Write(ConsoleColor.White, ">"); var line = UserInput.ReadLine(); if (commandsMap.ContainsKey(line)) { try { commandsMap[line].Item1(); } catch (InputCanceledException) { Console.Out.WriteLine("Команда прервана"); continue; } catch (Exception ex) { UserInput.Error("При выполнении команды произошла неожиданная ошибка"); UserInput.Error(ex.ToString()); } } else { UserInput.Error("Неправильно указано имя команды \"{0}\"", line); PrintAvailableCommnads(commandsMap); } } // интерактивная консоль для ввода // ввод значений списочных параметров по номерам // > auth // выберите сертификат // [email protected] [1] // [email protected] [2] // Сертификат [1]> // // Подтверждения // Отправить файлы? [Y/n]> } catch (InputCanceledException) { // Ctrl+C Console.Out.WriteLine(); Console.Out.WriteLine("Выход"); } catch (Exception ex) { UserInput.Error("Произошла неожиданная ошибка"); UserInput.Error(ex.ToString()); } }