-2

I am trying to read a JSON string in C# (in fact, it is much longer, but just to show the structure...) This is the string that I receive.

42["cti-agentes","{
    \"6139\":{
        \"id_agents_interface\":\"453\",
        \"agent\":\"6139\",
        \"interface\":\"contact1\",
        \"logintime\":\"2019-11-26 15:08:46\",
        \"pausetime\":\"2019-12-31 13:28:36\",
        \"paused\":\"si\",
        \"id_pausa\":null,
        \"invalid\":\"no\",
        \"invalidtime\":null,
        \"fullcontact\":\"contact1\",
        \"textoterminal\":\"contact1\"
        },
    \"6197\":{
        \"id_agents_interface\":\"5743\",
        \"agent\":\"6197\",
        \"interface\":\"contact1\",
        \"logintime\":\"2020-01-16 10:16:17\",
        \"pausetime\":null,
        \"paused\":\"no\",
        \"id_pausa\":null,
        \"invalid\":\"no\",
        \"invalidtime\":null,
        \"fullcontact\":\"contact2\",
        \"textoterminal\":\"contact2\"
        }
}"]

The String is supposed to be an array of 'agents'. 6139 is one agent, with all its properties, and 6197 is another agent. In this example there are only two agents, but in the real string there are many of them.

I am not very familiar with the JSON format, but I tried to validate it in this web https://jsonformatter.curiousconcept.com/ and I can't make it work, so maybe I have to "clean" the string a little bit before parsing it? Hope you can help.

The aplication should be able to read the JSON string and parse it to a .NET object, I tried the JsonConvert.DeserializeObject() and JArray.Parse() functions but neither of them have worked for me.

Any help?

Asier Azkolain
  • 75
  • 1
  • 13
  • 1
    That "42" at the beginning shouldn't be there. Also you need to remove the backslashes that delimit the double quotes before putting it into a validator (I assume you copied this from a debug view where VS displays string with double quotes delimited) – juharr Feb 22 '21 at 15:01
  • 2
    This looks like an escaped string, perhaps taken from the debugger? Please provide the actual string. E.g. use option `Text Visualizer` in Visual Studio. – Peter B Feb 22 '21 at 15:01
  • Thanks for the quick answer! I forgot to mention, I receive that string as a response from a websocket connection, that is actually what I receive. Should I remove the 42 on the beginning and remove those backslashes? – Asier Azkolain Feb 22 '21 at 15:10
  • 3
    @AsierAzkolain the `42` at the beginning definately invalidates this json, so you might want to trim this. Are you sure this is 100% the string you receive? If you had a a look at the string in visual studio debugger it's probably the debugger appending the backslashes. But there are multiple issues with this json... For example the value for cti-agents is surrounded by "", which actually makes it a string instead of a json object. – Dominik Feb 22 '21 at 15:13
  • Im like the other, This response make no sense. Drop the 42 and you got a `List` where those string can be Json. And the Json seems to be a `dictionary ` as you can see those numbers as key are a hint for dictionary. – Drag and Drop Feb 22 '21 at 15:16
  • Yes 100% sure, if I take the response string from the websocket connection and write it to a file using File.WriteAllText(), that's what I get, I guess they had to escape it before sending it through the websocket or something. Btw, I tried removing the '42' and the backslashes and it still doesn't validate in https://jsonformatter.curiousconcept.com/# – Asier Azkolain Feb 22 '21 at 15:16
  • The string is a valid Json. `{ "6139":{ "id_agents_interface":"453", "agent":"6139", "interface":"contact1", "logintime":"2019-11-26 15:08:46", "pausetime":"2019-12-31 13:28:36", "paused":"si", "id_pausa":null, "invalid":"no", "invalidtime":null, "fullcontact":"contact1", "textoterminal":"contact1" } }` is valid. even with your tool you must have removed to mutch – Drag and Drop Feb 22 '21 at 15:19
  • 1
    If this is really what you receive then it is a badly broken JSON response and it should be fixed on the SERVER side. You should try hard to NOT accept it as valid data (because it is not) and have the OTHER side fix it. Escalate if needed. – Peter B Feb 22 '21 at 15:29
  • @DragandDrop okey, so I need to remove the `42["cti-agentes","` in the beggining and the `"]` in the end, and it validates, nice! Now, I need to parse this in C#, how can I make it? – Asier Azkolain Feb 22 '21 at 15:31
  • While that's your return. It does not answer the question. You made a call and got this answer great. Is it alsways 42? Does the size change . etc. You are focusing on valid/invalid and ignoring the question. To parse a valid json string you can use this https://stackoverflow.com/questions/21611674/how-to-auto-generate-a-c-sharp-class-file-from-a-json-string – Drag and Drop Feb 22 '21 at 15:33
  • @PeterB I've followed DragandDrop's recommendations and the string now validates, so I think that this is no longer a problem. Also, I have no other option than accepting that response and do my (our?) best :) – Asier Azkolain Feb 22 '21 at 15:34
  • 1
    @AsierAzkolain It's probably the best idea to call the "developer" who produces this crap and scream at him until he fixes it. I wouldn't be surprised if 42 was just there for the memes ;-) – Dominik Feb 22 '21 at 15:36
  • @DragandDrop as long as I know (if been doing tests for a couple of days), it is always 42, it doesn't change depending on the number of agents or any other variable. The "parts to remove" are always the same. – Asier Azkolain Feb 22 '21 at 15:37
  • @Dominik hahaha I would love to do that XD. I am reading your answer, I'll answer soon. – Asier Azkolain Feb 22 '21 at 15:43

2 Answers2

1

There are multiple issues with your text. I will try to elabroate on them in the following parts...

42 prepended to the string

Quite obvious to all of us - this just should not be there

Your json object is a list

Since your json object starts with [ it's actually a string list, that has to be separated by ,, e.g. ["a", "b", "c"], which is probably the reason for the next point...

Your json value objects are strings

First of all the following is kind of a mixture of a string list and a json object

"cti-agentes","{
\"6139\":{
    \"id_agents_interface\":\"453\",
    \"agent\":\"6139\",
    \"interface\":\"contact1\",
    \"logintime\":\"2019-11-26 15:08:46\",
    \"pausetime\":\"2019-12-31 13:28:36\",
    \"paused\":\"si\",
    \"id_pausa\":null,
    \"invalid\":\"no\",
    \"invalidtime\":null,
    \"fullcontact\":\"contact1\",
    \"textoterminal\":\"contact1\"
    },

But also if you wanted to have json objects, you may not have surrounding "'s around your objects. symbol because it makes it a string instead of a json object, e.g.

"employee_1": { "name": "dominik" } instead of

"employee_1": "{ "name": "dominik" }" like it is in your example.

Conclusion

The system providing you a "json" does not provide a json and instead some string that is kind of similar to a json. Why? I don't know - probably "42" lol :)

The best advice is probably to talk to the guy who made the api and fix it

What can I do now?

Maybe you can try to extract the value for cti-agentes, since the following is actually a valid json you should be able to parse.

{
\"6139\":{
    \"id_agents_interface\":\"453\",
    \"agent\":\"6139\",
    \"interface\":\"contact1\",
    \"logintime\":\"2019-11-26 15:08:46\",
    \"pausetime\":\"2019-12-31 13:28:36\",
    \"paused\":\"si\",
    \"id_pausa\":null,
    \"invalid\":\"no\",
    \"invalidtime\":null,
    \"fullcontact\":\"contact1\",
    \"textoterminal\":\"contact1\"
    },
\"6197\":{
    \"id_agents_interface\":\"5743\",
    \"agent\":\"6197\",
    \"interface\":\"contact1\",
    \"logintime\":\"2020-01-16 10:16:17\",
    \"pausetime\":null,
    \"paused\":\"no\",
    \"id_pausa\":null,
    \"invalid\":\"no\",
    \"invalidtime\":null,
    \"fullcontact\":\"contact2\",
    \"textoterminal\":\"contact2\"
    }
}
Dominik
  • 1,623
  • 11
  • 27
1

The first part seems to be an int, you have multiple way to remove it:

var withoutNumberPrefix = new string(input.SkipWhile(c=> Char.IsDigit(c)).ToArray());
var fixedSize = input.Substring(2, input.Length - 2);
var always42 = input.TrimStart(new[] { '4', '2' });

Once you have done that you have a List<string>, where the first value is the type and the second the "array" of that type.

var listResults = JsonConvert.DeserializeObject<string[]>(fixedSize);

You can deserialize the second part:

var result = JsonConvert.DeserializeObject<Dictionary<int,CtiAgentes>>(listResults[1]);

Into the matching type, created with a simple copy past using those tool
How to auto-generate a C# class file from a JSON string :

public partial class CtiAgentes
{
    [JsonProperty("id_agents_interface")]
    public int IdAgentsInterface { get; set; }

    [JsonProperty("agent")]
    public int Agent { get; set; }

    [JsonProperty("interface")]
    public string Interface { get; set; }

    [JsonProperty("logintime")]
    public DateTimeOffset Logintime { get; set; }

    [JsonProperty("pausetime")]
    public DateTimeOffset? Pausetime { get; set; }

    [JsonProperty("paused")]
    public string Paused { get; set; }

    [JsonProperty("id_pausa")]
    public object IdPausa { get; set; }

    [JsonProperty("invalid")]
    public string Invalid { get; set; }

    [JsonProperty("invalidtime")]
    public object Invalidtime { get; set; }

    [JsonProperty("fullcontact")]
    public string Fullcontact { get; set; }

    [JsonProperty("textoterminal")]
    public string Textoterminal { get; set; }
}

In this Live demo, you will notice that there is no string manipulation except "remove the 42". Not backslash not quote were modify. It's a json hardcoded in a string Store Hardcoded JSON string to variable

Nota bene: I used DateTimeOffset for Pausetime and Logintime, because there where no timezone in that input. You can use Datetime but it will be nice to know if it's gmt or localized data.

For all the null value I choosed object. because I don't know the type. And that will go boom sooner or later with data. One can assume that id is a int and invalid time a DateTimeOffSet, but I can't make that decision.

Drag and Drop
  • 2,672
  • 3
  • 25
  • 37
  • Hey thanks! I am trying that on my code, but `input.SkipWhile` doesn't seem to compile, why is that? The first 3 lines only remove the '42', right? – Asier Azkolain Feb 22 '21 at 15:58
  • Yes, 3 way of dealing with it . And `SkipWhile` is linq you miss a `using System.Linq;`It's for me the best solution as it will handle 123456789 and 0 as well. While the other two will fail if the size change or if it's not 42. Using `TrimStart` with all the digit is the second best. – Drag and Drop Feb 22 '21 at 15:59
  • And click the live demo and watch it run . it will answer most of your question – Drag and Drop Feb 22 '21 at 16:01
  • NICE, it works, thank you very much!! It was a bit of a headache ;) – Asier Azkolain Feb 22 '21 at 16:02
  • @AsierAzkolain, Well it was 5 line of codes and 1 copy past. I added a nota bene in the answer. Read it. Because I only assumed the type based on incomplete data like `null`. This may go boom with real data. – Drag and Drop Feb 22 '21 at 16:05
  • Okey thanks, I'll check those things, my only worry until this moment was to correctly parse that little json hahaha thank you very much! You made my day ;) – Asier Azkolain Feb 22 '21 at 16:08