locked
Deserialising problem RRS feed

  • Question

  • User-1458727574 posted

    I'm pushing data into a Sage application. The data is posted just fine. The response data comes back as a serialised JSON string.

    "{\r\n  \"@odata.context\": \"http://localhost//$entity\",\r\n  \"BatchNumber\": 140,\r\n  \"BatchDate\": \"2018-08-28T00:00:00Z\",\r\n  \"Description\": \"Freight AR Invoice\"\r\n}

    If I tidy it up a bit, you get:

    {
      "@odata.context": "http://localhost//$metadata#ARInvoiceBatches/$entity",
      "BatchNumber": 140,
      "BatchDate": "2018-08-28T00:00:00Z",
      "Description": "Freight AR Invoice"
    }

    Using JSON.NET from NewtonSoft, I then have some code to deserialise the data so I can interrogate it:

                dynamic dsBatch = JsonConvert.DeserializeObject(newBatch, new JsonSerializerSettings
                {
                    NullValueHandling = NullValueHandling.Ignore,
                    DefaultValueHandling = DefaultValueHandling.Ignore
                });
    

    dsBatch is a dynamic object. The reason being is because I don't need to create a series of classes to handle the returns. The JSON response is actually, much larger than the above, but I know it is valid and I know it is fine. Cutting things down for this post, I still get the same problem. When I interrogate dsBatch at runtime, I know I should have BatchNumber in it. So my code is:

    int batchNumber = dsBatch.BatchNumber;

    However, I get a runtime binder exception error:

    System.AggregateException
      HResult=0x80131500
      Message=One or more errors occurred.
      Source=System.Private.CoreLib
      StackTrace:
       at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken)
       at System.Threading.Tasks.Task.Wait()
       at ACLWebApi.Controllers.FFARInvoicesController.Post(AR0032_List FFARInvoice, String s) in E:\LSProjects\ACLWebApi\ACLWebApi\Controllers\FFARInvoicesController.cs:line 57
       at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
       at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
       at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionMethodAsync>d__12.MoveNext()
    

    Any ideas?

    There are design reasons why I'm relying on a dynamic object. It isn't my particular choice, but it is what it is and no I can't change it. I know that the batch number is in the response and I can deserialise it but I can't get anything out of it. If I copy the dsBatch value from visual studio's debugger I have this:

    {{
      "@odata.context": "http://localhost/Sage300WebApi/v1.0/-/DEVDAT/AR/$metadata#ARInvoiceBatches/$entity",
      "BatchNumber": 141,
      "BatchDate": "2018-08-28T00:00:00Z",
      "Description": "Freight AR Invoice",
    }}

    I don't know where the double braces are coming from.

    Tuesday, August 28, 2018 12:15 PM

Answers

  • User-1458727574 posted

    Ahh, it seems that when I am pulling other data out which I use later in a string.replace, the replace function doesn't work with runtime binding. If I return the string into a variable, then do a replace, it works! One of the gotcha's of runtime binding with dynamic objects!

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, August 28, 2018 1:27 PM