-3

I'm attempting to build a dynamic JSON request message using the following code. When attempting to remove the escape characters by deserializing the JSON string, I receive an exception. Please see the comments below for the specific message. How do I remove the escape characters? Is there a better way to produce the request message? The data is correct, it is only the JSON format that needs to be fixed.

Here is the test result JSON key pair values that I add to the test results message class that I serialize to get the request message sent to the API:

{[
  "{\"TestResultSequenceID\":\"1\",\"ActionInfoID\":\"4\",\"Description\":\"Motor 1 amparage draw:\",\"TimeStamp\":\"10/6/2021\",\"AmpDraw\":\"3.4 Amperage\"}",
  "{\"TestResultSequenceID\":\"2\",\"ActionInfoID\":\"5\",\"Description\":\"Motor 2 amparage draw:\",\"TimeStamp\":\"10/6/2021\",\"AmpDraw\":\"3.4 Amperage\"}",
  "{\"TestResultSequenceID\":\"3\",\"ActionInfoID\":\"6\",\"Description\":\"Fuel pump sock pressed onto assembly:\",\"TimeStamp\":\"10/6/2021\",\"PressedOnFlag\":\" True\"}",
  "{\"TestResultSequenceID\":\"4\",\"ActionInfoID\":\"7\",\"Description\":\"Component pump 1 serial barcode label:\",\"TimeStamp\":\"10/6/2021\",\"ComponentPump1SerialNumber\":\"20210930000001\"}",
  "{\"TestResultSequenceID\":\"5\",\"ActionInfoID\":\"8\",\"Description\":\"Component pump 2 serial barcode label:\",\"TimeStamp\":\"10/6/2021\",\"ComponentPump2SerialNumber\":\"20210930000002\"}",
  "{\"TestResultSequenceID\":\"6\",\"ActionInfoID\":\"9\",\"Description\":\"Fuel pump assembly serial number:\",\"TimeStamp\":\"10/6/2021\",\"AssemblySerialNumber\":\"20210930000003\"}"
]}

Here is the code that loads the test results to the JArray:

Note: the escape characters are being added at this point.

JArray testresultsjarray = new JArray();
JObject testresultsobj = new JObject();
//Loop through the test action log to build the test results dynamic json object
//var testactionlog = TestActionInfoLogCS.TestActionInfoLogGLRepository;
            
for (int i = 0; i < TestActionInfoLogCS.TestActionInfoLogGLRepository.Count - 1; i++)
{
   dynamic testresultobj = new JObject();
   //Code removed that get the attribute info and loads it to the AttributeInfoDT                                   
   if ((bool)TestActionInfoLogCS.TestActionInfoLogGLRepository[i].IsTestFlag)
   {
   //Attribute Driven Test Results Code
   //Use the attribute to set the attribute name as the key value when building the test results
   objtestresult = GetDynamicObject(new Dictionary<string, object>()
   {
     {
       AttributeInfoDT.Rows[0]["Attribute"].ToString(), //Attribute = AmpDraw
       TestActionInfoLogCS.TestActionInfoLogGLRepository[i].ScannedInValue 
       //ScannedInValue = 3.4 Amperage
      }
    });
    string testresultstring1 = JsonConvert.SerializeObject(objtestresult);
    //testresultstring1 = "{\"AmpDraw\":\"3.4 Amperage\"}"
    //var testresult1 = JsonConvert.DeserializeObject<string>(testresultstring1);
                                                        
    //JsonConvert.DeserializeObject throughs the following exception:
    //Unexpected character encountered while parsing value: {. Path '', line 1, position 1.
                                                       
    testresultobj.TestResultSequenceID = TestActionInfoLogCS.TestActionInfoLogGLRepository[i].TestResultSequenceID.ToString();
    testresultobj.ActionInfoID = TestActionInfoLogCS.TestActionInfoLogGLRepository[i].TestActionSequenceNumber.ToString();
    testresultobj.Description = TestActionInfoLogCS.TestActionInfoLogGLRepository[i].TestActionDescription;                  
    testresultobj.TimeStamp = Convert.ToDateTime(TestActionInfoLogCS.TestActionInfoLogGLRepository[i].AddedDateTime).ToString("d");
    string testresultstring2 = JsonConvert.SerializeObject(testresultobj, Formatting.None);
    //testresultstring2 = "{\"TestResultSequenceID\":\"1\",\"ActionInfoID\":\"4\",\"Description\":\"Motor 1 amparage draw:\",\"TimeStamp\":\"10/6/2021\"}"
    //var testresult2 = JsonConvert.DeserializeObject<string>(testresultstring2);
    //Unexpected character encountered while parsing value: {. Path '', line 1, position 1.
                
    string combindedtestresults = testresultstring2.Substring(0, testresultstring2.Length - 1) + "," + testresultstring1.Substring(1, testresultstring1.Length - 1);
            
    //var combindedtestresults = JsonConvert.DeserializeObject<string>(combindedtestresult);
                                                        
    testresultsjarray.Add(combindedtestresults);
  }
}

I call the load test results request message repository method:

TestResultRequestMessageInfoCS.LoadTestResultRequestMessageInfoGLRepository(testresultsjarray))                                   

Here is the load method:

public static bool LoadTestResultRequestMessageInfoGLRepository(object TestResults)
{
    TestResultRequestMessageInfoGLRepository.Add(new TestResultRequestMessageInfoCS
    {
        TransactionID = TestInfoLogCS.TestInfoLogGLRepository[0].TransactionID.ToString(),
        SerialNumber = TestActionInfoLogCS.TestActionInfoLogGLRepository[0].ScannedInValue.ToString(),
        TestInfoLogID = TestInfoLogCS.TestInfoLogGLRepository[0].TestInfoLogID.ToString(),
        TestInfoID = TestInfoLogCS.TestInfoLogGLRepository[0].TestInfoID.ToString(),
        BusinessUnitOverhead = TestInfoLogCS.TestInfoLogGLRepository[0].BusinessUnitOverhead.ToString(),             
        PID = TestInfoLogCS.TestInfoLogGLRepository[0].PID.ToString(),                        
        TestDescription = TestInfoLogCS.TestInfoLogGLRepository[0].TestDescription.ToString(),
        ProtocolInfoID = TestInfoLogCS.TestInfoLogGLRepository[0].ProtocolInfoID.ToString(),
        DeviceInfoID = TestInfoLogCS.TestInfoLogGLRepository[0].DeviceInfoID.ToString(),
        DeviceIPAddress = DeviceInfoCS.DeviceInfoGLRepository[0].DeviceIPAddress.ToString(),
        DevicePort = DeviceInfoCS.DeviceInfoGLRepository[0].DevicePort.ToString(),
        ProcessTestResultsServiceInfoID = TestInfoLogCS.TestInfoLogGLRepository[0].ProcessTestResultsServiceInfoID.ToString(),
        ProcessTestResultsServiceIPAddress = ProcessTestResultsServiceInfoCS.ProcessTestResultsServiceInfoRepository[0].ServiceIPAddress.ToString(),
        ProcessTestResultsServicePort = ProcessTestResultsServiceInfoCS.ProcessTestResultsServiceInfoRepository[0].ServicePort.ToString(),
        StartTesterServiceInfoID = TestInfoLogCS.TestInfoLogGLRepository[0].StartTesterServiceInfoID.ToString(),
        StartTesterServiceIPAddress = StartTesterServiceInfoCS.StartTesterServiceInfoRepository[0].ServiceIPAddress.ToString(),
        StartTesterServicePort = StartTesterServiceInfoCS.StartTesterServiceInfoRepository[0].ServicePort.ToString(),
        ClientTesterInfoID = TestInfoLogCS.TestInfoLogGLRepository[0].ClientTesterInfoID.ToString(),
        ClientTesterIPAddress = ClientTesterInfoCS.ClientTesterInfoGLRepository[0].ClientTesterIPAddress.ToString(),
        ClientTesterPort = ClientTesterInfoCS.ClientTesterInfoGLRepository[0].ClientTesterPort.ToString(),
        TestRequestListenerMiddlewareInfoID = TestInfoLogCS.TestInfoLogGLRepository[0].TestRequestListenerMiddlewareInfoID.ToString(),
        TestRequestListenerMiddlewareIPAddress = TestRequestListenerMiddlewareInfoCS.MiddlewareInfoGLRepository[0].MiddlewareIPAddress.ToString(),
        TestRequestListenerMiddlewarePort = TestRequestListenerMiddlewareInfoCS.MiddlewareInfoGLRepository[0].MiddlewarePort.ToString(),
        TestResultsListenerMiddlewareInfoID = TestInfoLogCS.TestInfoLogGLRepository[0].TestResultsListenerMiddlewareInfoID.ToString(),
        TestResultsListenerMiddlewareIPAddress = TestResultsListenerMiddlewareInfoCS.MiddlewareInfoGLRepository[0].MiddlewareIPAddress.ToString(),
        TestResultsListenerMiddlewarePort = TestResultsListenerMiddlewareInfoCS.MiddlewareInfoGLRepository[0].MiddlewarePort.ToString(),
        MESInfoID = TestInfoLogCS.TestInfoLogGLRepository[0].MESInfoID.ToString(),
        MESIPAddress = MESInfoCS.MESInfoGLRepository[0].MESIPAddress.ToString(),
        MESPort = MESInfoCS.MESInfoGLRepository[0].MESPort.ToString(),
        TestResults = TestResults,
        TestCompleteFlag = TestInfoLogCS.TestInfoLogGLRepository[0].IsTestCompleteFlag.ToString(),
        Success = TestInfoLogCS.TestInfoLogGLRepository[0].SuccessFlag.ToString(),
        Error = TestInfoLogCS.TestInfoLogGLRepository[0].Errorcode.ToString(),
    }) ;
    return true;
}  

Now I serialize the test results message repository to string

TestResultRequestMessageInfoCS.p_TestResultRequestMessage = JsonConvert.SerializeObject(TestResultRequestMessageInfoCS.TestResultRequestMessageInfoGLRepository, Formatting.None); 

Please find below the test results request message. It has the escape characters in the TestResult attribute. How can I get ride of them?

{"TransactionID":"06cea8a2-b4d3-40b0-8380-2ed79f9c1179","TestInfoLogID":"17","TestInfoID":"35","BusinessUnitOverhead":"M1422","PID":"PID123456","TestDescription":"Cleantech - 2 Fuel Pump Assembly","DeviceInfoID":"5","DeviceIPAddress":"192.168.50.115","DevicePort":"43700","ProcessTestResultsServiceInfoID":"21","ProcessTestResultsServiceIPAddress":"192.168.50.115","ProcessTestResultsServicePort":"89","StartTesterServiceInfoID":"20","StartTesterServiceIPAddress":"192.168.50.115","StartTesterServicePort":"86","ClientTesterInfoID":"12","ClientTesterIPAddress":"192.168.50.115","ClientTesterPort":"87","TestRequestListenerMiddlewareInfoID":"23","TestRequestListenerMiddlewareIPAddress":"192.168.50.115","TestRequestListenerMiddlewarePort":"85","TestResultsListenerMiddlewareInfoID":"24","TestResultsListenerMiddlewareIPAddress":"192.168.50.115","TestResultsListenerMiddlewarePort":"43600","MESInfoID":"11","MESIPAddress":"192.168.50.115","MESPort":"88","ProtocolInfoID":"2","SerialNumber":"20210923-000001","TestCompleteFlag":"True","TestCompleteDateTime":"10/6/2021 11:05:08 AM","TestResults":["{\"TestResultSequenceID\":\"1\",\"ActionInfoID\":\"4\",\"Description\":\"Motor 1 amparage draw:\",\"TimeStamp\":\"10/6/2021\",\"AmpDraw\":\"3.4 Amperage\"}","{\"TestResultSequenceID\":\"2\",\"ActionInfoID\":\"5\",\"Description\":\"Motor 2 amparage draw:\",\"TimeStamp\":\"10/6/2021\",\"AmpDraw\":\"3.4 Amperage\"}","{\"TestResultSequenceID\":\"3\",\"ActionInfoID\":\"6\",\"Description\":\"Fuel pump sock pressed onto assembly:\",\"TimeStamp\":\"10/6/2021\",\"PressedOnFlag\":\" True\"}","{\"TestResultSequenceID\":\"4\",\"ActionInfoID\":\"7\",\"Description\":\"Component pump 1 serial barcode label:\",\"TimeStamp\":\"10/6/2021\",\"ComponentPump1SerialNumber\":\"20210930000001\"}","{\"TestResultSequenceID\":\"5\",\"ActionInfoID\":\"8\",\"Description\":\"Component pump 2 serial barcode label:\",\"TimeStamp\":\"10/6/2021\",\"ComponentPump2SerialNumber\":\"20210930000002\"}","{\"TestResultSequenceID\":\"6\",\"ActionInfoID\":\"9\",\"Description\":\"Fuel pump assembly serial number:\",\"TimeStamp\":\"10/6/2021\",\"AssemblySerialNumber\":\"20210930000003\"}"],"Success":"True","Error":"","RequestMessageSource":"FuelPumpTester","RequestMessageType":"TestResult"}

                             

I resolved the issue by deserializing to dynamic jobject. Passed the jobject (test results) into the load repository method. After the test results request message was built then serialized the repository to string. This is what worked for me.

string testresultsarraystring = "[" + TestResultRequestMessageInfoCS.p_TestResultRequestMessage + "]";
dynamic data = JsonConvert.DeserializeObject<dynamic>(testresultsarraystring);
TestResultRequestMessageInfoCS.LoadTestResultRequestMessageInfoGLRepository(data);
Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
Paul
  • 93
  • 2
  • 11
  • 3
    You have to post your code too, otherwise how are you going to get any help? – Serge Oct 05 '21 at 17:54
  • 2
    But chances are either 1) Visual Studio has confused you by "helpfully" escaping the string and the JSON does not contain backslashes. To see the raw string, see [Copy value of watch variable in visual studio without escape characters](https://stackoverflow.com/q/2327540/3744182). 2) The JSON was double-serialized by the server. The best way to deal with that is to not double-serialize the JSON. See e.g. [Strings sent through Web API's gets wrapped in quotes](https://stackoverflow.com/q/33681978/3744182). – dbc Oct 05 '21 at 17:57
  • If you can't fix the server you will have to deserialize twice e.g. as shown in [Newtonsoft escaped JSON string unable to deseralize to an object](https://stackoverflow.com/q/52095457/344280). – dbc Oct 05 '21 at 17:59
  • 2
    Avoid working directly with JSON as strings. This is exactly the problem that serializers and deserializers are designed to solve. Create an object that represents your JSON data, populate the values, and serialize it. – Daniel Mann Oct 05 '21 at 18:00
  • Why are you serializing your inner object? Better make the wapper (`TestResultsRequestMessage` I guess) generic and use `public T TestResults { get; set; }` – Pieterjan Oct 05 '21 at 18:21

1 Answers1

0

Backslash in this case is an escape character for quotes. Json format requires key values to be within quotes. If we want to store json string in c# we cannot do this:

string jsonString = "{ "name" : "John" }";

for the language to store this json object as actual string we need to write

string jsonString = "{ \"name\": \"John\" }";
pallavdubey
  • 109
  • 6
  • Well that is a total bummer. Any suggestion on how I can accomplish loading the TestResult attribute with the test results shown above, without the escape characters? I cannot tell you how frustrating this is. All data is correct, it's just the json format that the problem. – Paul Oct 06 '21 at 16:38
  • The API that I'm send the request message to does not like the escape characters. That is why I need to remove them – Paul Oct 06 '21 at 16:45
  • Why does the following exception get thrown: string jsonString = "{ \"name\": \"John\" }"; var testresult = JsonConvert.DeserializeObject(jsonString); Unexpected character encountered while parsing value: {. Path '', line 1, position 1. – Paul Oct 06 '21 at 16:51
  • Problem resolved see edit post above – Paul Oct 06 '21 at 18:12