1

I would like to run a Json Object through DynamicExpression but i am getting the error "No method 'SelectToken' exists on type 'System.Linq.Enumerable'."

the below rule i am trying to execute through DynamicExpression.

Rule: JObject.SelectToken(\"$.Dosage\").ToString()==\"25\"

my Json Object:

{
  "Dosage": 25,
  "Drug": "Indocin",
  "Patient": "David",
  "Date": "2019-05-22T22:06:50.4394817"
}

´Code:

//converted json to Json Object:

JArray jsonArray = JArray.Parse(jsonString);
JObject data = JObject.Parse(jsonArray[0].ToString());

bool r = CompareRules("JObject.SelectToken(\"$.Dosage\").ToString()==\"25\"", data);

public static bool CompareRules(string formula, params object[] objects)
{
    var result = false;
    try
    {
        var lstParams = objects.Select(o => Expression.Parameter(o.GetType(), o.GetType().Name)).ToArray<ParameterExpression>();
        var e = System.Linq.Dynamic.DynamicExpression.ParseLambda(lstParams, null, formula);
        result = (bool)e.Compile().DynamicInvoke(objects.ToArray());
    }
    catch (TargetInvocationException) { }
    catch (KeyNotFoundException) { }
    catch (Exception ex) { }

    return result;
}

i expect the output of JObject.SelectToken(\"$.Dosage\").ToString()==\"25\" is true if the value matches otherwise false.

OfirD
  • 9,442
  • 5
  • 47
  • 90
satish p
  • 11
  • 1
  • Why not get rid of all those error masking `catch` statements and see the actual error that occurs? – Uwe Keim Aug 19 '19 at 05:00

1 Answers1

0

I don't think Dynamic Linq is the right choice here, as you can't use it the way you want to without really abusing* its source code (i.e., by adding conditions that only apply to JToken). Here's why:

Your exception stems from Dynamic Linq's ParseAggregate (you'd see it if you'd debug into Dynamic Linq source code).
This method assumes that the parsed dynamic method (in your case it's SelectToken) can be parsed into an IEnumerable extension method (e.g., Where).

However, SelectToken is not an IEnumerable extension method, but a simple instance method declared in Newtonsoft.Json.Linq.JToken. Therefore, it's "not applicable", as the exception says.

For this reason, you'd also won't be able to use the steps given in this answer, as they only apply for IEnumerable extensions methods.

You should go with standard reflection programming.

*Note that you're already using ParseLambda in an unconventional way, as the expression you pass it as the last argument is not a lambda.

OfirD
  • 9,442
  • 5
  • 47
  • 90