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 :
Supply chain | Supply Chain Management, Commerce
Unanswered

Realtime InvokeMethod error: Exception: System.FormatException: String was not recognized as a valid Boolean

(0) ShareShare
ReportReport
Posted on by 1,457

I have a new retail server extension that does a realtime call. My call to the method in X++ is as follows. I followed the example of StoreHoursDataService and GetFulfillmentPackgingslipService examples.

"

InvokeExtensionMethodRealtimeRequest extensionRequest = new InvokeExtensionMethodRealtimeRequest(
                               "TMCGetReservedOrders",
                               request.WhseId);
            InvokeExtensionMethodRealtimeResponse response = await request.RequestContext.ExecuteAsync<InvokeExtensionMethodRealtimeResponse>(extensionRequest).ConfigureAwait(false);
            ReadOnlyCollection<object> results = response.Result;
            success = Convert.ToBoolean(results[0]);

"

I am supposed to be able to retrieve the "success" flag using Convert.ToBoolean(results[0]).

However the eventviewer for the Commerce-RetailServer gives the error:  

***

An error occurred during the Retail Server Request. RequestUri: <URL>/Commerce/ReservedOrders/TMCGetReservedOrdersAction?$top=250&api-version=7.3. RequestId: 947f1dd4-4fe8-c399-ec87-e3331596158b. Exception: System.FormatException: String was not recognized as a valid Boolean.
   at System.Boolean.Parse(String value)
   at System.String.System.IConvertible.ToBoolean(IFormatProvider provider)
   at TMCReservedOrdersViewCRT.GetReservedOrderService.<Process>d__0.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at Microsoft.Dynamics.Commerce.Runtime.CommerceRuntime.<Execute>d__38`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Microsoft.Dynamics.Commerce.Runtime.CommerceRuntime.<Execute>d__38`1.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at TMCRetailServer.GetReservedOrdersView.GetReservedOrdersController.<TMCGetReservedOrdersAction>d__0.MoveNext() in C:\Source\RetailSDK\TMCBackendExtensions\TMC_OrderFulfillmentProjects\TMCRetailServer.GetReservedOrdersView\GetReservedOrdersController.cs:line 31

***

If I change my approach and read "results" as follow, then the error disappears but the results.Count returns a 1 instead of 3:

int vCnt = 1;

foreach (object vObj in results)
{
        if (vCnt == 1)
        {
               bool vConverted = Boolean.TryParse(vObj.ToString(), out success);
                if (vConverted == false)
                {
                     success = false;
                 }
         }

break;

}

If I add a test job to my project in X++ and in its Main-method add the following code that calls the method that the InvokeExtensionMethod calls, then it returns values :

    static void main (Args _args)
    {
        boolean vOK       = true;
        str     vResult = '';
        str errorMessage  = '';
        InventLocationId whseId;
       
        whseId = 'KCY';
        [vOK, errorMessage, vResult] = RetailTransactionServiceEx::TMCGetReservedOrders(whseId);
    }
8535.pastedimage1599082265976v2.png
As you can see from the above image it returns a True for success and it returns 3 entries in the container.
So why won't the InvokeExtensionMethod not return the 3 values?
I even changed my class to extend from SingleAsynRequestHandler, same as GetFulfillmentPackgingslipService :
 public class GetReservedOrderService : SingleAsyncRequestHandler<GetReservedOrdersRequest>
I first had it as :  public class GetReservedOrderService : IRequestHandler , and called the InvokeExtensionMethod as following, but the error happens for both:
***
InvokeExtensionMethodRealtimeRequest extensionRequest = new InvokeExtensionMethodRealtimeRequest("TMCGetReservedOrders", request.WhseId);
                InvokeExtensionMethodRealtimeResponse response = request.RequestContext.Execute<InvokeExtensionMethodRealtimeResponse>(extensionRequest);
                ReadOnlyCollection<object> results = response.Result;

***

I'm running v10.0.12 in case it is important.

Any help is much appreciated to solve this error.

I have the same question (0)
  • André Arnaud de Calavon Profile Picture
    301,035 Super User 2025 Season 2 on at

    Moved to the Dynamics 365 Commerce forum.

  • ToddB Profile Picture
    on at

    Hi Retha,

    Sample code says :

                   bool success = Convert.ToBoolean(results[0]);

    In the code you listed there is no bool at the front:

               success = Convert.ToBoolean(results[0]);

    Can you try changing this to match the sample code?

    Thanks.

  • Retha Profile Picture
    1,457 on at

    Sorry it's not obvious from the code but I defined success before the invoke statement:

    bool success = false;

    I did the above when I started to try out different ways to read the result value seeing that it seems not to pass back a Boolean value

    I have tried different scenarios:

    ***

    string vMsg = string.Empty;
     bool success = false;
    string vError = string.Empty;
               
    try
                {
                    InvokeExtensionMethodRealtimeRequest extensionRequest = new InvokeExtensionMethodRealtimeRequest("TMCGetReservedOrders", request.WhseId);
                    InvokeExtensionMethodRealtimeResponse response = await request.RequestContext.ExecuteAsync<InvokeExtensionMethodRealtimeResponse>(extensionRequest).ConfigureAwait(false);
                    ReadOnlyCollection<object> results = response.Result;
                    //  success = Convert.ToBoolean(results[0]);
                    if (Convert.ToString(results[0]).ToLower() == "true")
                    {
                        success = true;
                    }
               
                    if (success == false)
                    {
                        vError = "Request.WhseId value: " + request.WhseId
                                + "; Count of ReadonlyCollection(Object): " + results.Count.ToString()
                                + "; " + Convert.ToString(results[0]);
                                //+ "; Error: " + Convert.ToString(results[1]);
                        throw new CommerceException("GetReservedOrderService", vError);
                    }

    ***

    The above then doesn't give the error that results[0], isn't Boolean, but it then went on and complain about results[1]. I get the following error:

    ***

    Microsoft.Dynamics.Commerce.Runtime.CommerceException: General exception: Index was out of range. Must be non-negative and less than the size of the collection.​

    ***

    If I comment out the reference to results[1]. then the event viewer shows in commerce-Retailserver the warning:

    ***

    Request handler (or trigger) has exceeded the configured execution threshold.

    ***

    There is nothing wrong with the X++ side because it does return the container with the 3 values.  I do call a version of GetFulfillmentLines , so it is in itself a bit slower because the standard FulFillmentLinesView is slower to retrieve the data, but it still should work.

    I'm starting to wonder if there isn't something wrong with the Dev environment because I remember when I deployed it (cloud-hosted environment on our subscription), and updated the environment after the deployment with the Developer's topology, it did not update the windows hosts file as it is supposed to. I had to manually update the hosts file, so what else didn't it set correctly.

    The Developer's topology (docs.microsoft.com/.../cloud-dev-box) in the link is supposed to do the following:

    ***

    The Developer topology prerequisites package installs Typescript 2.2.2 and updates the Windows host file with your Cloud POS URL. Deploying the package will take a few minutes.

    ***

    It did not update the hosts file automatically .

    The documentation isn't clear what the sequence is in deploying an environment.

    I usually click on "Add" under cloud-hosted environments and enter the information and then wait for the environment to be deployed. I never chose the Demo database data because I import a backup of UAT so that I can work on familiar data.

    I think with this one I immediately after the deployment applied the developer's topology. Don't know if I was supposed to first import the database, then set up Visual Studio with TFS and then apply the developers topology or if the sequence doesn't matter as long as I apply it and that something just went wrong with the application

  • ToddB Profile Picture
    on at

    Hi Retha,

    It appears a support incident was also created for this issue.

    Can you verify that?

    If so, I will let the engineer working on that incident continue troubleshooting.

    Thank you in advance.

  • Retha Profile Picture
    1,457 on at

    Yes I logged one this morning because I need to get this working, have spend too much time on it already with no success and there isn't anything obvious wrong

  • Retha Profile Picture
    1,457 on at

    I received and answer from MSFT.

    The issue was with the StoreHoursSample which wasn't correct and will be updated.

    InvokeExtensionMethod is only returning the Data portion.

    When we were still on v10.0.7 I used for one of my other realtime requests: transactionServiceClient.InvokeExtensionMethod

    But it was not advisable to call TransactionServiceclient directly and I switched to InvokeExtensionMethodRealtimeRequest on v10.0.12.

    For TransactionServiceClient I knew that the first 2 values returned were for internal use and thus had to only look at the 3rd one. But the StoreHours example through me for a loop and I thought InvokeExtensionMethodRealtimeRequest pass back all 3 seeing that StoreHours validate position [0] for success true/false and if false it uses position [2] to get the error message.

    Positions [1] and [2] is still kept for internal use only and only position [3] is returned which is then referenced as :

    string vXml = (string)results[0];

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 > Supply chain | Supply Chain Management, Commerce

#1
Laurens vd Tang Profile Picture

Laurens vd Tang 296 Super User 2025 Season 2

#2
Siv Sagar Profile Picture

Siv Sagar 178 Super User 2025 Season 2

#3
André Arnaud de Calavon Profile Picture

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

Last 30 days Overall leaderboard

Featured topics

Product updates

Dynamics 365 release plans