The call to method ‘Deserialize’ needs to be dynamically dispatched, but cannot be because it is part of a base access expression

I just stumbled over the neat post about how to turning JSON into a ExpandoObject the other day about how to work with json-data on the server side using the new dynamic features in .NET 4.0.

What I wanted to achieve was to serialize my JavaScript view models into C#. I knew I could write a custom model binder for that but since the view model was quite complicated I figured that it would probably be best if I had full control over the deserialization. At least for now…

public class JsViewModel {
 
    public int Id {
        get; set;
    }
 
    public static JsViewModel CreateModelFromJson(dynamic json) {
        string type = json.type;
        string typeName = (typeof(JsViewModel).Namespace) + "." + type;
 
        try {
            var def = (JsViewModel)Activator.CreateInstance(Type.GetType(typeName));
            def.Deserialize(json);
            return def;
        } catch (Exception e) {
            //...
            return None;
        }
    }
 
    public virtual void Deserialize(dynamic json) {
        this.Id = json.id;
    }
}

The above code worked fine, I could pass in any type as long as it had a property called type.
But when I started implementing my view models I soon run into trouble.

public class MyJsViewModel: JsViewModelDefinition {
    public string Name { get; set; }
    public override void Deserialize(dynamic json) {
        base.Deserialize(json);
        Name = json.shortName;
    }
}

Error 66 The call to method ‘Deserialize’ needs to be dynamically dispatched, but cannot be because it is part of a base access expression. Consider casting the dynamic arguments or eliminating the base access.

Ouch, seems like you can’t really do the stuff I was hoping for and since giving up base access is out of the question for me I had to go with the casting option.
I knew that my json would be represented using the ExpandoObject (see the turning JSON into a ExpandoObject blog post above) so I could cast it directly into an that but that would break the ability to write simple test cases like JsViewModel.CreateModelFromJson(new{type=”MyJsViewModel”}) so I choose object instead.

public class JsViewModel {
    public int Id {
        get;
        set;
    }
 
    public static JsViewModel CreateModelFromJson(dynamic json) {
        String type = json.type;
        string typeName = (typeof(JsViewModel).Namespace) + "." + type;
 
        try {
            var def = (JsViewModel)Activator.CreateInstance(Type.GetType(typeName));
            def.Deserialize(json);
            return def;
        } catch (Exception e) {
            // handle error...
        }
    }
 
    public virtual void Deserialize(object jsonObject) {
        dynamic json = jsonObject;
        this.Id = json.id;
    }
}
 
public class MyJsViewModel: JsViewModel {
    public string Name { get; set; }
    public override void Deserialize(object jsonObject) {
        base.Deserialize(jsonObject);
        dynamic json = jsonObject;
        Name = json.shortName;
    }
}
No comments yet.

Leave a Reply