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

 
 
Опции темы Поиск в этой теме Опции просмотра
Старый 15.07.2020, 17:55   #1  
mazzy is offline
mazzy
Участник
Аватар для mazzy
Лучший по профессии 2015
Лучший по профессии 2014
Лучший по профессии AXAWARD 2013
Лучший по профессии 2011
Лучший по профессии 2009
 
29,123 / 4006 (192) ++++++++++
Регистрация: 29.11.2001
Адрес: Москва
Записей в блоге: 10
ax2012, JSON для WCF Service: binding="webHttpBinding"?
Уважаемые знатоки сервисов, WCF и AIF в аксапте.
на аксфоруме было несколько обсуждений как в Аксапте работать с JSON запросами. обсуждения сводились к сериализации-десериализации json-строки средствами X++.

но точно известно, что:
1. сервисы в ax2012 построены на Майкрософтовском фреймворке WCF
2. WCF вполне работает с JSON на уровне протокола.
В частности, см. https://docs.microsoft.com/en-us/dot...without-aspnet

Другими словами, я ожидаю, что для Аксаптовских сервисов можно поменять настройку биндинга, например, на webHttpBinding и сам WCF будет разбираться с JSON или XML на основании заголовка content-type. А сервис внутри Аксапты получит вполне десериализованный объект (возможно со слабой типизацией).

Цитата:
HTTP POST requests with a content-type of "application/json" are treated as JSON, and those with content-type that indicate XML (for example, "text/xml") are treated as XML.
Вопрос 1: кто-нибудь копал в эту сторону? какие подводные камни?

Вопрос 2: behaviorConfiguration="serviceBehaviorConfiguration", "dataContractSerializer". Есть что почитать на эту тему? Расскажите как это работает в ax2012?

см. также:
https://docs.microsoft.com/en-us/dot.../nettcpbinding
https://docs.microsoft.com/en-us/dot...webhttpbinding
Миниатюры
Нажмите на изображение для увеличения
Название: 1.PNG
Просмотров: 39
Размер:	60.4 Кб
ID:	12896  
__________________
GitHub, Facebook, mazzy.priot, mazzy.music, coub.

Последний раз редактировалось mazzy; 15.07.2020 в 18:37.
За это сообщение автора поблагодарили: Raven Melancholic (5).
Старый 17.07.2020, 23:14   #2  
DSPIC is offline
DSPIC
Боец
Аватар для DSPIC
MCP
Лучший по профессии 2017
Лучший по профессии 2014
Лучший по профессии 2009
 
1,023 / 1065 (38) ++++++++
Регистрация: 11.04.2008
Адрес: Минск
есть в d365 класс formjsonserializer, вполне работоспособный и для ах2012. Сериализует контракт класс и обратно. А вот для 2009 пришлось потрудиться, т.к. не поддерживаются аттрибуты класса - но и это решаемо. В гугле написано, что эта фишка WCF там ещё в свой псевдо-объект заворачивает, так что врядли без кастылей сработает.
__________________
Мой блог
Старый 06.08.2020, 12:15   #3  
Brave is offline
Brave
Участник
 
25 / 14 (1) ++
Регистрация: 13.09.2010
Адрес: Санкт-Петербург
Цитата:
Сообщение от DSPIC Посмотреть сообщение
есть в d365 класс formjsonserializer, вполне работоспособный и для ах2012. Сериализует контракт класс и обратно.
Пробовал работать с jsonserializer в AX2012. Не всякий JSON им можно разобрать, особенно если в JSON имеются вложенные структуры с одинаковыми названиями JSONObject, но несущие в себе разные сущности. Конечно же проблема в лютой реализации некоторых JSON API с которыми приходилось работать.
Старый 06.08.2020, 13:05   #4  
Brave is offline
Brave
Участник
 
25 / 14 (1) ++
Регистрация: 13.09.2010
Адрес: Санкт-Петербург
Для полноценной работы с форматом JSON, используйте прослойку в виде ASP.NET WEB API прилложения, развёрнутого на IIS, которое занимается перегонкой JSON <-> WCF и объединением различных сервисов DAX, так же оно является промежуточным секюрным слоем, можно добавить кастомную систему авторизации, отфильтровать спам и кривые запросы, сообщить о недоступности сервисов DAX, обработать всякие ситуации, с которыми в DAX порой разобраться будет невозможно. Хорошим плюсом так же является возможность автоматического документирования web API сервиса (используем Swagger).
Стоит не забывать о том, что для работы с WCF DAX необходима авторизация. Для некоторых методов API используется стандартный QueryService, с возможностью постраничного запроса данных. Для некоторых моментов можно использовать метаданные AX так же через стандартный сервис MetadataService. В общем одни плюсы.
В целом всё получается достаточно красиво при правильной организации проекта, примеры вызова:
Код:
 /// <summary>
    /// Методы клиента (покупателя)
    /// </summary>
    [RoutePrefix("api/Sales/v1")]
    [ShowInSwagger]
    public class CustomersController : ApiController
    {
        private CallContext context = ClientFactory.CreateContext<CallContext>();

        /// <summary>
        /// Список клиентов
        /// </summary>
        /// <param name="page">Страница</param>
        /// <param name="pageSize">Количество записей на странице</param>
        [HttpGet]
        [Route("Customers")]
        [SwaggerResponse(HttpStatusCode.OK, Description = "Список клиентов", Type = typeof(IEnumerable<Models.Sales.Customer.CustAccount>))]
        [SwaggerResponse(HttpStatusCode.NotFound, Description = "По запросу ничего не найдено")]
        [SwaggerResponse(HttpStatusCode.BadRequest, Description = "Ошибка AIF/WCF", Type = typeof(AifFaultError))]
        [ResponseType(typeof(QueryResult))]
        [CommonExceptionFilters]
        public IHttpActionResult GetCustomers([FromUri] long page = 1, int pageSize = 50)
        {
            if (page <= 0 || pageSize <= 0)
                return BadRequest();

            return new Queries.Customer.CustomerListQuery(Request, new Models.Common.PaginationMetadata(page, pageSize));
        }
        /// <summary>
        /// Информация о клиенте
        /// </summary>
        /// <param name="CustAccount">Счёт (код клиента)</param>
        [HttpGet]
        [Route("Customers/{CustAccount}")]
        [SwaggerResponse(HttpStatusCode.OK, Description = "Информация о клиенте", Type = typeof(Models.Sales.Customer.CustomerInfo))]
        [SwaggerResponse(HttpStatusCode.NotFound, Description = "По запросу ничего не найдено")]
        [SwaggerResponse(HttpStatusCode.BadRequest, Description = "Ошибка AIF/WCF", Type = typeof(AifFaultError))]
        [CommonExceptionFilters]
        public async Task<IHttpActionResult> GetCustomerInfo([FromUri] string CustAccount)
        {
            Models.Sales.Customer.CustomerInfo result;

            using (var client = ClientFactory.CreateClient<WebCustServicesClient>())
            {
                var request = await client.GetCustomerAsync(context, CustAccount);

                if (request.response == null)
                    return NotFound();

                result = new Models.Sales.Customer.CustomerInfo
                {
                    CustAccount = request.response.CustAccount,
                    CustName = request.response.CustName,
                    WebEmail = request.response.WebEmail,
                    InventLocation = request.response.InventLocation,
                    PersonnelNumber = request.response.PersonnelNumber,
                    RouteId = request.response.RouteId,
                    SegmentId = request.response.SegmentId,
                    Settings = new Models.Sales.Customer.CustSettings() 
                    { 
                        AccountStatement            = request.response.CustSettings.AccountStatement.ToCustAccountStatement(),
                        SalesLineRejectionSendEmail = request.response.CustSettings.SalesLineRejectionSendEmail.ToNoYes()
                    }
                };
            }
            return Ok(result);
        }
        /// <summary>
        /// Баланс клиента
        /// </summary>
        /// <param name="CustAccount">Счёт (код клиента)</param>
        /// <param name="cur">Валюта</param>
        [HttpGet]
        [Route("Customers/{CustAccount}/Balance")]
        [SwaggerResponse(HttpStatusCode.OK, Description = "Баланс клиента", Type = typeof(Models.Sales.Customer.CustBalance))]
        [SwaggerResponse(HttpStatusCode.NotFound, Description = "По запросу ничего не найдено")]
        [SwaggerResponse(HttpStatusCode.BadRequest, Description = "Ошибка AIF/WCF", Type = typeof(AifFaultError))]
        [CommonExceptionFilters]
        public async Task<IHttpActionResult> GetCustBalance([FromUri] string CustAccount,string cur = "")
        {
            Models.Sales.Customer.CustBalance result;
 
            using (var client = ClientFactory.CreateClient<WebCustServicesClient>())
            {
                var request = await client.GetCustBalanceAsync(context, CustAccount,cur);

                result = new Models.Sales.Customer.CustBalance()
                {
                    CustAccount = request.response.CustAccount,
                    Currency = request.response.CustCurrencyCode,
                    Balance = request.response.Balance,
                    ReservAmount = request.response.ReservAmount,
                    SalesOpenAmount = request.response.SalesOpenAmount
                };
            }
            return Ok(result);
        }
....
Пример обработки ошибок WCF AIF:
Код:
 else if (exceptionType == typeof(ActionNotSupportedException))
            {
                AifFaultError error = new AifFaultError();
                error.Infolog.Add(new InfoMsg()
                {
                    Type = Enum.GetName(typeof(InfologMessageType), InfologMessageType.Error),
                    Message = "Метод WCF сервиса не поддерживается. Возможно он был изменён или переименован в AX."

                });
                status = HttpStatusCode.BadRequest;
                message = new ObjectContent<AifFaultError>(error, new JsonMediaTypeFormatter());
            }
            else
            {
                AifFaultError error = new AifFaultError();
                error.Infolog.Add(new InfoMsg()
                {
                    Type = Enum.GetName(typeof(InfologMessageType), InfologMessageType.Error),
                    Message = actionExecutedContext.Exception.Message
                });

                message = new ObjectContent<AifFaultError>(error, new JsonMediaTypeFormatter());
            }
Теги
aif, ax2012, json, services, wcf

 

Похожие темы
Тема Автор Раздел Ответов Посл. сообщение
atinkerersnotebook: Using Service Management to Track Service Orders Blog bot DAX Blogs 1 25.08.2013 19:16
AIF: Microsoft Dynamics AX Services and Windows Azure Service Bus Blog bot DAX Blogs 0 24.07.2013 03:13
emeadaxsupport: AX for Retail 2012 R2: Installing the Real-time Service Blog bot DAX Blogs 0 19.12.2012 11:11
Dynamics AX: WCF: The Enterprise Service Bus for Dynamics AX and the rest of the Microsoft Stack Blog bot DAX Blogs 0 10.03.2009 16:05
Pokluda: Outbound web service (AIF) Blog bot DAX Blogs 0 28.10.2006 17:43
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск
Опции просмотра

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

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

Рейтинг@Mail.ru
Часовой пояс GMT +3, время: 14:13.
Powered by vBulletin® v3.8.5. Перевод: zCarot
Контактная информация, Реклама.