March 17, 2025

Update admin user in Dev box

Old is gold,


MS removed admin user provising tool, but there is an old way where you can still add your user as admin, 

Go to the VM and open SQL management Studio, 

Step 1: Find admin user rec id in USERINFO table, 

select  * from USERINFO

Step 2: Get SID from earlier Database for your user

select  * from USERINFO
where RECID = 53755554576


Step 3: Update new Database with below query 

update USERINFO
set NETWORKALIAS = 'deepak.agarwal@theaxapta.com',
sid = 'S-1-19-18-####-####-####5192'
where RECID = 53755554576


Make sur eof choosing right Database of each query and use the right recid and other values. 


-Harry Follow us on Facebook to keep in rhythm with us. https:fb.com/theaxapta

January 24, 2025

Custom web service in D365FO - Part-I

Introduction

Custom services in Dynamics 365 Finance and Operations (D365FO) allow you to expose custom business logic and data to external systems. This first part of the blog post will walk you through the basics of creating and consuming custom services in D365FO. Custom services are used to expose X++ business logic to external systems via SOAP or RESTful endpoints. They are ideal for scenarios where you need to implement complex business processes that are not covered by standard services.

In later posts, we will discuss some complex scenarios and best practices around web services.

Architecture

Service Request Contract

The service contract defines the operations that the service will expose. This is done by creating a new class with the [DataContractAttribute] and [DataMemberAttribute] attributes. There must be two contract classes: one for the request message and another for the response message. (We will cover this in detail in future posts).

Example:

[DataContractAttribute]
public class TheAxaptaRequestContract
{
    private boolean isShipped;
    private String255 dataAreaId;
    private String255 storeNumber;
    private String255 trackingNumber1;

    [DataMember("TrackingNumber1")]
    public String255 parmTrackingNumber1(String255 _trackingNumber1 = trackingNumber1)
    {
        trackingNumber1 = _trackingNumber1;
        return trackingNumber1;
    }

    [DataMember("IsShipped")]
    public boolean parmIsShipped(boolean _isShipped = isShipped)
    {
        isShipped = _isShipped;
        return isShipped;
    }

    [DataMember("DataareaId")]
    public String255 parmdataAreaId(String255 _dataAreaId = dataAreaId)
    {
        dataAreaId = _dataAreaId;
        return dataAreaId;
    }

    [DataMember("StoreId")]
    public String255 parmStoreNumber(String255 _storeNumber = storeNumber)
    {
        storeNumber = _storeNumber;
        return storeNumber;
    }
}

Service Response Contract

Example:

[DataContractAttribute]
public class TheAxaptaResponseContract
{
    private boolean success;
    private str errorMessage;
    private str debugMessage;
    private System.String salesOrder;

    [DataMember("Message")]
    public str parmMessage(str _value = errorMessage)
    {
        if (!prmIsDefault(_value))
        {
            errorMessage = _value;
        }

        return errorMessage;
    }

    [DataMember("Success")]
    public Boolean parmSuccess(Boolean _value = success)
    {
        if (!prmIsDefault(_value))
        {
            success = _value;
        }

        return success;
    }

    [DataMember("DebugMessage")]
    public str parmDebugMessage(str _value = debugMessage)
    {
        if (!prmIsDefault(_value))
        {
            debugMessage = _value;
        }

        return debugMessage;
    }
}

Service Class

This is the class where the actual business operation executes. It takes the request message from the respective contract class and processes it to create a response message. Create a new class to implement the service. This class should extend the SysOperationServiceBase class and include the business logic for the service operations.

Example:

public class TheAxaptaService extends SysOperationServiceBase
{
    TheAxaptaResponseContract response = new TheAxaptaResponseContract ();
[AifCollectionType('salesOrder', Types::Class, classStr(TheAxaptaRequestContract)),
AifCollectionType('return', Types::Class, classStr(TheAxaptaResponseContract ))]
public processMsg() { TheAxaptaRequestContract request;
// Now you can access the parm methods of the request class to get different values from the request Str StoreId = request.paramStoreNumber(); response.parmSuccess(True); response.parmMessage("Message read"); } }

Register the Service

Register the service in the AOT (Application Object Tree) by creating a new service node. Set the class and method properties to point to your service implementation.

  1. In the AOT, right-click Services and select New Service. (e.g. TheAxaptaInterface)
  2. Set the Class property to your service class (e.g., TheAxaptaService).
  3. Set the Method property to the service method (e.g., processMsg).

Deploy the Service

Deploy the service to make it available for consumption. This can be done by right-clicking the service node in the AOT and selecting Deploy Service Group.

Consume the Service

A third part can consume this service using the below syntax

<EnvironmentURL>/API/services/TheAxaptaInterface/TheAxaptaService/processMsg

and send the request message in body.

If you want to setup postman to test your services by yourself, I would recommend to checkout this blog post,