Beispiel #1
0
    public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
    {
        // Logic adapted from JsonSerializerInternalReader.CreateDynamic()
        // https://github.com/JamesNK/Newtonsoft.Json/blob/master/Src/Newtonsoft.Json/Serialization/JsonSerializerInternalReader.cs#L1751
        // By James Newton-King https://github.com/JamesNK

        var contract = (JsonDynamicContract)serializer.ContractResolver.ResolveContract(objectType);

        if (reader.TokenType == JsonToken.Null)
        {
            return(null);
        }
        var jObj = JObject.Load(reader);
        var used = new HashSet <string>();
        var obj  = CreateObject(jObj, objectType, serializer, used);

        foreach (var jProperty in jObj.Properties())
        {
            var memberName = jProperty.Name;
            if (used.Contains(memberName))
            {
                continue;
            }
            // first attempt to find a settable property, otherwise fall back to a dynamic set without type
            JsonProperty property = contract.Properties.GetClosestMatchProperty(memberName);
            if (property != null && property.Writable && !property.Ignored)
            {
                var propertyValue = jProperty.Value.ToObject(property.PropertyType, serializer);
                property.ValueProvider.SetValue(obj, propertyValue);
            }
            else
            {
                object propertyValue;
                if (jProperty.Value.Type == JTokenType.Null)
                {
                    propertyValue = null;
                }
                else if (jProperty.Value is JValue)
                {
                    // Primitive
                    propertyValue = ((JValue)jProperty.Value).Value;
                }
                else
                {
                    propertyValue = jProperty.Value.ToObject <IDynamicMetaObjectProvider>(serializer);
                }
                // Unfortunately the following is not public!
                // contract.TrySetMember(obj, memberName, propertyValue);
                // So we have to duplicate the logic of what Json.NET has already done.
                CallSiteCache.SetValue(memberName, obj, propertyValue);
            }
        }
        return(obj);
    }
 public override object this[object target, string name]
 {
     get { return(CallSiteCache.GetValue(name, target)); }
     set { CallSiteCache.SetValue(name, target, value); }
 }