AXForum  
Вернуться   AXForum > Microsoft Dynamics AX > DAX: Программирование
All
Забыли пароль?
Зарегистрироваться Правила Справка Пользователи Сообщения за день Поиск

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 27.07.2018, 01:39   #1  
alicedr is offline
alicedr
Участник
 
175 / 43 (2) +++
Регистрация: 06.07.2012
Адрес: Канада
D365 создать запись в таблице через OData из console application (.Net)
Несмотря на то, что в интернете есть несколько неплохих ссылок, я не могу добавить запись к таблице через одату из консольного приложения.
Также не получается получить значение определенного поля из энтити.

Если у кого получалось сделать под версию 8, буду благодарна за советы.

Я использовала подход который описан в статье StoneridgeSoftware (Working with the OData Endpoint in Dynamics 365 for Operations), аналогичное описание есть у Hitachi solutions (Dynamics 365 Roadmap: Dynamics 365 for Operations – How to Access Dynamics 365 for Operations Data Entities using OData Protocol and .NET) и "AX7/D365/Operations: Create customer postal address through data entity from .NET console application"

Описанный в статьях подход пришлось немного изменить в сторону асинхронности, например для вставки данных это SaveChangesAsync вместо SaveChanges.
Я не получаю никаких ошибок в дебаггере, я вижу в контексте другие энтити, но запись не добавляется!
Энтити рабочая - запись с такими же полями прекрасно вставляется через data management из excel файла.

Веб приложение зарегистрировано в портале, права добавлены, в самой аксапте приложение тоже добавлено с ретейл пользователем. В заголовке OAUTH номер токена вижу.

Идеи уже закончились. Из консольного дебаггера выглядит что запись вставилась, а в аксапте ее нет (
Старый 27.07.2018, 16:58   #2  
wojzeh is offline
wojzeh
Участник
Аватар для wojzeh
Соотечественники
 
674 / 512 (19) +++++++
Регистрация: 27.04.2006
Адрес: Montreal
"Из консольного дебаггера выглядит что запись вставилась, а в аксапте ее нет" - а это точно та аксапта, которую дебажите?
__________________
Felix nihil admirari
Старый 27.07.2018, 21:52   #3  
alicedr is offline
alicedr
Участник
 
175 / 43 (2) +++
Регистрация: 06.07.2012
Адрес: Канада
да, по query из watch window видно.
Старый 27.07.2018, 22:06   #4  
alicedr is offline
alicedr
Участник
 
175 / 43 (2) +++
Регистрация: 06.07.2012
Адрес: Канада
Проблему удалось решить.
Оказалось, что пользователь, на которого зарегистрировано приложение в аксапте, должен иметь компанию, которая используется из консольного приложения, и обычный RetailUser не прокатил.

Заодно в процессе гугления я нашла другой способ работы с одатой - WEB API.
Достаточно неплохо описан, как для микрософта, есть куча примеров. Ссылки бросать не буду, но отлично гуглится по строке "Microsoft Dynamics 365 Web API"

Недостаток - как ни странно, запрос по определенному клиенту почему-то выдает не одного клиента, а всех. Похоже на баг.
Если кому надо, код очень простой:
Код:
//this is called from Page_load method, which is obviously not async:
 //**** WEB API -  unfortunately gives a list of customers instead of one, looks like a bug
                
                AuthenticationResult token = OAuthHelper.GetAuthenticationHeader(true);
                string queryOptions =  "$select=Name,customerAccount";
                string queryFilter = "$filter" + " dataAreaId eq '" + dataAreaId + "' and CustomerAccount eq '" + accountIdVal + "'";
                string query = ODataEntityPath +"/"+ "Customers" + "?" + queryOptions + "&" + queryFilter;
                
                _Default app = new _Default();
                try
                {
                    Task.WaitAll(Task.Run(async () => await app.SendRequestAsync(HttpMethod.Get, query, token)));
                }
                catch (System.Exception ex) {  }
                finally
                {
                    if (app.httpClient != null)
                    { app.httpClient.Dispose(); }
                    Console.WriteLine("Press <Enter> to exit the program.");
                    Console.ReadLine();
                }
                
//********************
//this is async method
 ///<summary> Sends an HTTP request to the current service. </summary>
        ///<param name="method">The HTTP method to invoke</param>
        ///<param name="query">The HTTP query to execute (base URL is provided by client)</param>
        ///<param name="formatted">True to include formatted values in response; default is false.</param>
        ///<param name="maxPageSize">Number of records to display per output "page".</param>
        ///<returns>An HTTP response message</returns>
        private async Task<HttpResponseMessage> SendRequestAsync(HttpMethod method, string query, AuthenticationResult _token, Boolean formatted = false, int maxPageSize = 10)
        {
            HttpResponseMessage response;
            using (HttpClient httpClient = new HttpClient())
            {
                httpClient.Timeout = new TimeSpan(0, 2, 0);  // 2 minutes
                httpClient.DefaultRequestHeaders.Authorization =
                    new AuthenticationHeaderValue("Bearer", _token.AccessToken);
                HttpRequestMessage request = new HttpRequestMessage(method, query);  
                        //request.Headers.Add("Prefer", "odata.maxpagesize=" + maxPageSize.ToString());
                        //if (formatted)
                        //    request.Headers.Add("Prefer",
                        //        "odata.include-annotations=OData.Community.Display.V1.FormattedValue");
                response = await httpClient.SendAsync(request);
                var responseBodyAsText = response.Content.ReadAsStringAsync();
            }
            return response;
        }
За это сообщение автора поблагодарили: sukhanchik (4), gl00mie (3).
Старый 29.07.2018, 11:36   #5  
Alex_KD is offline
Alex_KD
Участник
AxAssist
MCBMSS
Соотечественники
 
522 / 362 (14) ++++++
Регистрация: 06.07.2006
Адрес: Melbourne, Down Under
Цитата:
Сообщение от alicedr Посмотреть сообщение
Код:
string queryFilter = "$filter" + " dataAreaId eq '" + dataAreaId + "' and CustomerAccount eq '" + accountIdVal + "'";
А если поменять на (обратите внимения на $filter=) -

Код:
string queryFilter = String.Format("$filter=dataAreaId eq '{0}' and CustomerAccount eq '{1}'", dataAreaId, accountIdVal);
__________________
AxAssist 2012 - Productivity Tool for Dynamics AX 2012/2009/4.0/3.0
За это сообщение автора поблагодарили: sukhanchik (2).
 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
ValidTimeStateMode = NoGap. Можно ли создать запись в действующем диапазоне Владимир Максимов DAX: Программирование 2 30.01.2018 21:19
dynamicsaxinsight: AX7/D365/Operations: Create customer postal address through data entity from .NET console application Blog bot DAX Blogs 0 20.09.2017 15:11
Глюк(?) при импорте в Excel через .Net Loengrinchik DAX: Программирование 1 14.08.2015 10:55
AX.NET: интеграция .NET-приложений с Аксаптой и (будущие) возможности облачных вычислений gl00mie DAX: Программирование 2 23.04.2010 00:47
Очень просто: создать новую запись в таблице Hobo DAX: Программирование 20 11.07.2006 13:02

Ваши права в разделе
Вы не можете создавать новые темы
Вы не можете отвечать в темах
Вы не можете прикреплять вложения
Вы не можете редактировать свои сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.
Быстрый переход

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 08:37.