Home > Blockchain >  What's the best way to parse dynamic JSON data
What's the best way to parse dynamic JSON data

Time:11-30

Imagine a method accepting 2 string arguments:

public int Method(string expression, string variables) { ... }

"expression" is expected to be a math. expression (e.g. "1 2") that needs to be evaluated. And if there's something except for numbers & operators, I need to look up for that variable in "variables" string argument, to replace that variable with the number it represents. (There's no guarantee that the variable is defined in "variables", but I believe it's not important here).

Input example:

Method("351   x", "{ \"x\":69 }");
// Expected output: 420

Example of other valid "variables" values:

  • { "x":123 }
  • { "x":123, "y":420 }
  • { }
  • { "z":69 }
  • { "abc": 777 }

I wonder what's a good way to parse & retrieve data from a JSON (that may have a different structure each time (i.e. different number of properties & names)), to map it with the variable in "expression" string?

CodePudding user response:

Personally, I would go with Newtonsoft.Json and use a mapping to a Dictionary<string, object>:

using Newtonsoft.Json;

public int Method(string expression, string variables) 
{ 
    var varsDic = 
        JsonHelper.IsValidJson(variables)
            ? JsonConvert.DeserializeObject<Dictionary<string, object>>(variables);
            : new Dictionary<string, object>()

    // ...
}

Example, documentation.

With IsValidJson being something like this:

public static class JsonHelper
{
    public static bool IsValidJson(string json)
    {
        return IsValidJson(json, out _);
    }

    public static bool IsValidJson(string json, out Exception parseError)
    {
        if (string.IsNullOrWhiteSpace(json))
        {
            parseError = new Exception(Resources.JsonEmpty);
            return false;
        }

        json = json.Trim();
        if (json.StartsWith(@"{") && json.EndsWith(@"}") || //For object
            json.StartsWith(@"[") && json.EndsWith(@"]")) //For array
        {
            try
            {
                JToken.Parse(json);

                parseError = null;
                return true;
            }
            catch (JsonReaderException x)
            {
                parseError = x;
                return false;
            }
            catch (Exception x)
            {
                parseError = x;
                return false;
            }
        }
        else
        {
            parseError = new Exception(Resources.JsonNoStartEnd);
            return false;
        }
    }

See also.

  • Related