Passing record to extension and back

Passing record to extension and back

  

I pass a record as an object to an extension. In the extension I change the value of one of the records fields like so (this is just some demo code):

public void MssCallProcedure(object ssOut) {

            foreach (FieldInfo fi in ssOut.GetType().GetFields())

            {

                string name = fi.Name;

                if (name.StartsWith("ss") || name.StartsWith("_ss"))

                {

                    object v = (Int32)12345;

                    fi.SetValue(ssOut, v);

                }

            }

}

The value for the field is set, I have checked. But the value is not returned to Outsystems. It looks like pass by reference is not working for a record. Any guidance how to get this working?

Please take in account that the ssOut var has to be a dynamic record. So I cannot set it as an output variable. I am using Outsystems Version  10.0.723.0 .NET

Hi Niek,

Records are always passed by value, so you can never change a record like that. The only way to do this is to pass a Record List, even if it's guaranteed to only have a single item.

Kilian, 

If he cannot set the record as an output variable, it will never be returned to Outsystems from the extension, right?


Abílio Matos

Hi Abilio,

Record Lists are passed to an Extension by reference, so any changes to them inside the Extension are reflected in the eSpace after calling. This behaviour is used extensively in Forge components like XMLRecords. If you want to change a Record you indeed need to specify an output parameter, but the problem that the OP has with this is that he passes an Object, as he needs a dynamic input (and you can't cast an Object back to a Record).

Hi Kilian,

Thanks for this! 

Could you create an example for me where you change the value of an field in the list? Because I tried to use the record list but it still did not return the value.

Thanks in advance.

Niek.

Hello,

If I am not mistaken, Lists are passed by reference only inside same module... The same for objects and binaries...

No?

In this case, you need to return the list/record in order to have the new value...

Cheers

Solution

@Eduardo: I'm afraid you're mistaken on this one. Lists and Record Lists are always passed by reference into an Extension. Otherwise Forge components like SortRecordList and XML Records wouldn't work :).

@Niek: I would advise you to take a look at the components I mentioned above. They both use reflection to get the structure of the List and Records, and change or build the list.

Solution

Thanks for the fix, Kilian :)

Okay, so that's an important information.


After a hour and a half trying to figure out what was going on, I finally got it.


I always knew lists and objects were passed by reference, but I did not realize it's only for actions inside the same module.


Whenever a list is passed to a referenced action (an action which belongs to a different module), the entire thing is copied over, so any changes made to that list inside the referenced action does not affect the original list!


Even extensions get the list by value and not by reference, except when we wrap the list in a ToObject function. So that's what I did: passed the list as object and made the desired changes through a .NET code.