In C# how can I deserialize this json when one field might be a string or an array of strings?
Asked Answered
W

3

4

I have an asp.net-mvc website and i am reading in Json string from a Database. Here is the following json in a DB. It could look like this:

{"description": "Test", "contacts": ["[email protected]", "[email protected]"], "enabled": true}

or this:

{"description": "Test", "contacts": "[email protected], [email protected]", "enabled": true}

so as you can see, the contacts field is either:

  1. a string (with items separated by commas)
  2. an array of strings.

I want to convert to this class:

public class MyJob
{
    public string description;
    public string[] contacts;
    public string enabled;
}

when i try to assign just to a string (changing the above to this: public string contacts; ) using the JavascriptSerializer():

var serializer = new JavaScriptSerializer();
string contacts = serializer.Deserialize<MyJob>(theAboveJsonString).contacts;

I get this error in the cases where its an array: Type 'System.String' is not supported for deserialization of an array.

what is the best way to go about deserializing this to handle the case of:

  1. a string
  2. an array of strings.

for the contact field. I am happy to put any conditional logic needed . .

I tried this:

  var contacts = serializer.Deserialize<MyJob>(theAboveJsonString).contacts;
        if (contacts is string)
        {
            jobInfo.contacts = contacts;
        }
        else
        {
            jobInfo.contacts = String.Join("; ", contacts );
        }

but that didn't seem to fix as i am still getting the error above when its an array

Weber answered 13/4, 2012 at 13:20 Comment(2)
I don't suppose you could write a script to encode these values in a consistent manner in the database?Braxy
unfortunately not . i don't own the DB or the dataWeber
U
2

try

  var contacts = (new JavaScriptSerializer().DeserializeObject(theAboveJsonString) as Dictionary<string, object>)["contacts"];

  if (contacts is object[])
  {
      jobInfo.contacts = String.Join("; ", contacts as object[]);
  }
  else
  {
      jobInfo.contacts = contacts.ToString(); 
  }

For reference see MSDN and here.

Uralite answered 13/4, 2012 at 13:50 Comment(0)
P
0

You may be interested in some details here: JSON.net - field is either string or List<string>

If you're willing to use Json.NET, have this function:

public string[] getAsArray(JToken token)
{
    if (token.HasValues)
    {
        return token.Select(m => string(m)).ToArray();
    }
    else
    {
        return ((string)token).Split(",").Select(s => s.Trim()).ToArray();
    }
}

Then usage:

var json = "...";
JObject o = JObject.Parse(json);
string[] contacts = getAsArray(o["contacts"]);

For either JSON the result should be the same.

Pili answered 13/4, 2012 at 13:47 Comment(0)
E
-2

Try to deserialize contacts into a string array instead of a plain string:

string[] contacts = serializer.Deserialize<MyJob>(theAboveJsonString).contacts;

if the JSON variable is holding a plain string, use:

string[] contacts = serializer.Deserialize<MyJob>(theAboveJsonString).contacts.Split(',');
Ewing answered 13/4, 2012 at 13:32 Comment(4)
as per the question, it may be a string or it may be an array . .Weber
If the field is holding a string then use contacts.Split(',') to convert it into an array. Either way you need to assign it into a string array and not a plain string variable.Ewing
Matt - i think you are missing the point of the question . . the issue is that the field can be either data type . . the whole point of the question is how i deal with this situationWeber
Sorry. The best way to handle this would be to enter it into the database consistently. If you can't do that then test for it being an array first, if it's not an array then use string.Split(','). To test for an Array use contacts.GetType().IsArray;Ewing

© 2022 - 2024 — McMap. All rights reserved.