web
You’re offline. This is a read only version of the page.
close
Skip to main content

Notifications

Announcements

No record found.

Community site session details

Community site session details

Session Id :
Finance | Project Operations, Human Resources, ...
Unanswered

How to pass value from a Form to the service class (sysOperationFrameWork)

(0) ShareShare
ReportReport
Posted on by 1,965

Hi,

I have a code for a button inside the form. and inside this button i'm calling a sysOperationService class. However i want to be able to pass a value from the code of the button to the service class

So what i did is inside the controller, i created a method that takes the value that i want to pass

then i created a contract class with parameter that matches the value that i want to pass

Now inside the validate method in the controller i filled the contract parameter with the value

and now my service has a parameter with the contract so that i can access that value

This is the code for the button

[Control("Button")]
class ButtonControl
{
    guid    guidField = newguid();
    Table1  table1;
    update_recordset  table1
        setting Status = Status::B,
        TTTGuidFiled = guidField
    where table1.Status == Status::A;
    
    Table1_ds.research(true);
    TTTController controller = TTTController::construct();
    controller.setGuidFiled(guidField);  // i had to create this method in the controller to meet my needs
    controller.startOperation();
}
`

Here's my controller class

/// 
/// controller class 
/// 
class TTTController extends SysOperationServiceController
{
    guid guidField;  // i had to add this
    
    
    /// 
    ///   What method to call from the service class
    /// 
    protected void new()
    {
        super(classStr(TTTService),methodstr(TTTService,Send),SysOperationExecutionMode::ReliableAsynchronous);
    }

    public static TTTController construct()
    {
        TTTsController controller = new TTTController();
        controller.parmShowDialog(false);
        controller.parmShowProgressForm(false);
        controller.parmLoadFromSysLastValue(false);

        return controller;
    }
    
    protected boolean validate()
    {
        boolean ret = true;
        TTTContract contract;
        
        contract = this.getDataContractObject();
        contract.GuidField(this.getGuidField());  // i had to add this
        
        return ret;
    }

    public void setGuidField(guid _guidField)  // i had to add this
    {
        guidField = _guidField;
    }

    public guid getGuidField()  // i had to add this
    {
        return guidField;
    }

    protected ClassDescription defaultCaption()
    {
        return "@Label1";
    }

}

This is my service class

 public void Send(TTTContract _contract)
{

    guid guidField = _contract.GuidField();
}

My question is: is what i did the right thing to do? was it ok to fill the value in the validate method of the controller? or is there a better way to do what i want

I have the same question (0)
  • Siddy Mujumdar Profile Picture
    4 on at

    Hi IntegrationBeginner,

    it is not best practice to assign a value in validate method.

    alternate way to achieve you requirement is :

    [

       SysEntryPointAttribute

    ]

    public void process(MyDataContract _dataContract)

    {

       SysOperationServiceController   controller;

       // New instance of the Operation service controller

       controller = new SysOperationServiceController(

           classStr(MyClass),

           methodStr(MyClass, myProcess),

           SysOperationExecutionMode::ScheduledBatch

           );

       // Hardcoded text value. Using '', identifierStr(_dataContract), or a macro is just masking the problem

       contract = controller.getDataContractObject("_dataContract");

       // Instead we can use the collection class

       contract = controller.getDataContractObject(

           // to get classId of current object, and first parameter name of current method

           Global::getMethodParameterName(this, funcName()));

    }

    Thanks,

    Siddy

  • Siddy Mujumdar Profile Picture
    4 on at

    Hey this also a way to achieve a solution:

    public static void main(Args _args)

       {

           MyController controller = new MyController();

           controller.parmClassName(classStr(MyController));

           controller.parmMethodName(methodStr(MyController,

           myOperation));

           controller.parmExecutionMode(SysOperationExecutionMode::Synchronous);

           controller.startOperation();

       }

       public void myOperation(MyContract _contract)

       {

           container data = _contract.parmPackedData();

       }

    Thanks,

    siddy

  • Martin Dráb Profile Picture
    237,882 Most Valuable Professional on at

    validate() method is for validation, and this isn't a validation, therefore such logic doesn't balong to validate().

    I tend to follow the pattern established by report controllers (SRSReportRunController), which have methods prePromptModifyContract() and preRunModifyContract() for this purpose. If I need the same logic, I implement the same methods in my controllers.

    prePromptModifyContract() is called from startOperation() (before super()) and preRunModifyContract() is called (indirectly) from run() (before super()).

    Siddy Mujumdar, please use Insert > Insert Code (in the rich-formatting view) to paste source code.
  • Siddy Mujumdar Profile Picture
    4 on at

    ok martin i will keep this in mind.

  • .. Profile Picture
    1,965 on at

    Hi Martin,

    Would i still need the set and get method i created in the controller class for the guid field? Is it a best practice to create such random methods?

    And inside the prePromptModifyContract() i still need to call the getGuidField right?

    I think preRun and PrePromt will both work right?

    Hi Siddy, i'll take a look at ur code when i use my laptop it's difficult to trace without using the rich format view. Thanks alot for the help.

  • Martin Dráb Profile Picture
    237,882 Most Valuable Professional on at

    You need something to pass the value through. Using a method on the controller is one approach (not that the usual design in AX/F&O is combining get* and set* to a single parm* method). Another common design is passing data through Args class (either to main() method, or calling controller's parmArgs() method from outside.

    Whether you want to do it before or after the dialog (= the prompt) is up to you. Doing it ASAP looks more suitable to me in this case, but I don't know your detailed requirements.

  • .. Profile Picture
    1,965 on at

    Hi martin,

    How to pass the guidField usign args or parmArgs?

    Also what should i write inside prePromptModifyContract? 
    It also seems there is no prePromptModifyContract for sysOperationServiceController

  • Martin Dráb Profile Picture
    237,882 Most Valuable Professional on at

    For example, you could use Args.parmObject() to pass an object containing GUID.

    You're right - there is no prePromptModifyContract() in SysOperationServiceController class. As I mentioned above, it's defined in SRSReportRunController class and "if I need the same logic, I implement the same methods in my controllers". You don't have to implement prePromptModifyContract() if you don't want to mimic the approach used in SRSReportRunController.

    What you would put to prePromptModifyContract() is code to populate the data contract. Remember, you already have it in validate(); we're talking about where to move it.

  • .. Profile Picture
    1,965 on at

    Hi martin,

    Ok so u mean i should move the code i wrote in validate method yo a more meaningful method.

    But from where should i call this method? Should i call it inside the construct method?

    Or should i call it from outside and make it take a paramter for the guid field?

    Also what is the syntax for args.ParmObject(guidField) it's not working

  • Martin Dráb Profile Picture
    237,882 Most Valuable Professional on at

    Could you please read my first reply once more? You're again asking about something that I already mentioned there.

    "It's not working" is not a good description of any problem, fortunately your bug is visible from your code. The method accepts and object - that's why I told you that you could "pass an object containing GUID". That's not what you're doing - you're trying to passing the GUID directly, but guid isn't an object, therefore your code won't even compile.

    If you have no reason for using Args, simply don't do it. It's just an option.

Under review

Thank you for your reply! To ensure a great experience for everyone, your content is awaiting approval by our Community Managers. Please check back later.

Helpful resources

Quick Links

Responsible AI policies

As AI tools become more common, we’re introducing a Responsible AI Use…

Neeraj Kumar – Community Spotlight

We are honored to recognize Neeraj Kumar as our Community Spotlight honoree for…

Leaderboard > Finance | Project Operations, Human Resources, AX, GP, SL

#1
Martin Dráb Profile Picture

Martin Dráb 565 Most Valuable Professional

#2
André Arnaud de Calavon Profile Picture

André Arnaud de Cal... 450 Super User 2025 Season 2

#3
Sohaib Cheema Profile Picture

Sohaib Cheema 250 User Group Leader

Last 30 days Overall leaderboard

Product updates

Dynamics 365 release plans