1

I want to create dynamic expressions for my web services to allow client applications to pass dynamic queries to filter the data as they require. To this end I'm trying to serialize / deserialize an Expression in C# / .NET. that the client application can pass into my web service. Unfortunately I'm getting the following error when I attempt to deserialize the expression.

System.MissingMethodException: No parameterless constructor defined for type of 'System.Linq.Expressions.Expression`1[[System.Func`2[[Common.Entities.ModuleEntityAdmins, Common, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]

The classes I am deserializing contain parameterless constructors and are decorated with the appropriate [DataContract] and [DataMember] attributes.

[DataContract]
public class ModuleEntityAdmins
{
    [DataMember]
    public List<ModuleEntityAdmin> Modules { get; set; }

    /// <summary>
    /// Default constructor
    /// </summary>
    public ModuleEntityAdmins()
    {
        this.Modules = new List<ModuleEntityAdmin>();
    }
}

[DataContract]
public class ModuleEntityAdmin
{
    [DataMember]
    public int Id { get; set; }
    [DataMember]
    public bool Active { get; set; }
    [DataMember]
    public string Name { get; set; }

    /// <summary>
    /// Default constructor
    /// </summary>
    public ModuleEntityAdmin()
    {
    }
}

I create a simple Expression to return a single instance of the class.

Expression<Func<ModuleEntityAdmins, ModuleEntityAdmin>> expr1 = m => m.Modules.Find(q => q.Id == 1);

I serialize the Expression using the following function.

public string SerializeObject(object objtoserialize)
{
    return JsonConvert.SerializeObject(objtoserialize);
}

At this point everythng is fine.

I then go to deserialize the string using the following function.

public T DeserializeObject<T>(string jsonObject)
{
    T result = default(T);
    if (!string.IsNullOrEmpty(jsonObject))
    {
        //errors on the line below!!
        result = new JavaScriptSerializer().Deserialize<T>(jsonObject);
    }
    return result;
}

It is when attempting to deserialize the Expression that I get the error.

I have correctly decorated the classes involved and they both have parameterless constructors so can't understand why I am getting the error.

Any ideas?

8
  • 4
    expression trees don't serialize worth a damn; they have a ToString() which gives a representation of the lambda, and that is probably what JsonConvert is outputting, but: there is zero chance of deserializing an expression tree trivially; it just doesn't work like that Commented May 15, 2020 at 8:32
  • FWIW: I can't even run your serialize code (copy pasting everything from the question); I get "Unhandled exception. Newtonsoft.Json.JsonSerializationException: Self referencing loop detected for property 'ManifestModule' with type 'System.Reflection.RuntimeModule'. Path 'Body.Method.Module.Assembly'." Commented May 15, 2020 at 8:35
  • to be clear: the error isn't telling you that ModuleEntityAdmin or ModuleEntityAdmins is lacking a particular constructor; it is telling you that the expression types are missing it. Commented May 15, 2020 at 8:36
  • There are various libraries to serialize expression trees, like this one and this one Commented May 15, 2020 at 8:38
  • What Marc said.. But just FYI it's not your classes without the parameterless constructor, it's Expression<Func<, >>. Unrelated, but I find it weird that you mix JsonConvert and JavascriptSerializer. The latter is "obsolete" - - not officially, but per MS' own docs. [man I type slow, refreshed and ya'll be me to it] Commented May 15, 2020 at 8:42

1 Answer 1

1

There is exists simple labrary Remote.Linq - https://github.com/6bee/Remote.Linq

You can try example code:

            Expression<Func<ModuleEntityAdmins, ModuleEntityAdmin>> expr1 = m => m.Modules.Find(q => q.Id == 1);

            var remoteExpression = expr1.ToRemoteLinqExpression();

            var s = SerializeObject(new RequestExp { Expression = expr1 });

            RequestExp requestExp = DeserializeObject< RequestExp > (s);

            Expression<Func<ModuleEntityAdmins, ModuleEntityAdmin>> expression = requestExp.Expression.ToLinqExpression<ModuleEntityAdmins, ModuleEntityAdmin>();           
Sign up to request clarification or add additional context in comments.

1 Comment

I'm getting an error on the RequestExp type. Is this part of Remote.Linq?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.