Serializing a IKVMC generated object to JSON

笑着哭i 提交于 2019-12-06 14:51:10

I suspect this is because there are no fields/properties exposed in the object that is generated by ikvmc

Yes.

Does anyone know if there's a workaround for this?

You can do it by writing a custom ContractResolver and ValueProvider as below

var obj = new ApiToken();
obj.setApiKey("X-X-X");
obj.setI(666);

var settings = new Newtonsoft.Json.JsonSerializerSettings() { 
                     ContractResolver = new MyContractResolver() 
               };

var json = JsonConvert.SerializeObject(obj, settings);
//json : {"ApiKey":"X-X-X","I":666}
var newobj = JsonConvert.DeserializeObject<ApiToken>(json, settings);

//Test class
public class ApiToken 
{
    private String apiKey;

    public String getApiKey()
    {
        return apiKey;
    }

    public void setApiKey(String apiKey)
    {
        this.apiKey = apiKey;
    }


    private int i;

    public int getI()
    {
        return i;
    }

    public void setI(int i)
    {
        this.i = i;
    }

    public string dummy()
    {
        return "abcde";
    }
}

public class MyContractResolver : Newtonsoft.Json.Serialization.DefaultContractResolver
{
    protected override IList<Newtonsoft.Json.Serialization.JsonProperty> CreateProperties(Type type, Newtonsoft.Json.MemberSerialization memberSerialization)
    {
        //Find methods.  setXXX getXXX
        var properties = type.GetMethods()
            .Where(m => m.Name.Length > 3)
            .GroupBy(m => m.Name.Substring(3))
            .Where(g => g.Count() == 2 && g.Any(x=>x.Name=="set" + g.Key) && g.Any(x=>x.Name=="get" + g.Key))
            .ToList();

        //Create a JsonProperty for each set/getXXX pair
        var ret = properties.Select(prop=>
                    {
                        var jProp = new Newtonsoft.Json.Serialization.JsonProperty();
                        jProp.PropertyName = prop.Key;
                        jProp.PropertyType = prop.First(m => m.Name.StartsWith("get")).ReturnType;
                        jProp.ValueProvider = new MyValueProvider(prop.ToList());
                        jProp.Readable = jProp.Writable = true;
                        return jProp;
                    })
                    .ToList();

        return ret;
    }
}

public class MyValueProvider : Newtonsoft.Json.Serialization.IValueProvider
{
    List<MethodInfo> _MethodInfos = null;
    public MyValueProvider(List<MethodInfo> methodInfos)
    {
        _MethodInfos = methodInfos;
    }
    public object GetValue(object target)
    {
        return _MethodInfos.First(m => m.Name.StartsWith("get")).Invoke(target, null);
    }

    public void SetValue(object target, object value)
    {
        _MethodInfos.First(m => m.Name.StartsWith("set")).Invoke(target, new object[] { value });
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!