2016-03-03 56 views
0

的JSON反序列化过程中动态更改属性值,我需要在深对象图的反序列化JSON在动态更改属性值。我目前正在使用Newtonsoft.Json。这些值在序列化期间保留,只能在反序列化期间更改。我GOOGLE了,发现ReadJson()处理整个对象,而不是属性的属性。另一种可能的解决方案是使用反射来递归产生,然后由属性名称过滤所有属性和更改值,但是这可能会影响性能因为这里会有2个循环:Json的反序列化,然后反射。所以我相信在飞行中改变价值应该是一条路。任何指针,洞察力和评论表示赞赏。谢谢!深对象图

回答

0

除非你想编写自己的JSON解析器(提示:你没有),那么你就需要deserialisation后处理您的对象图。

你的主要反对这样做似乎是性能。在编写代码并对其进行分析之前,您不知道性能的影响。编写最简单的解决方案,然后测量性能。

如果有性能问题,然后发布你写的代码,我们也许能够给你加速它的提示。

0

我已经测试过,结果如下(只有递归反射): 36226字节需要8ms; 1905字节需要7ms

public T Deserialize<T, Value>(byte[] data, JsonSerializerSettings settings, Dictionary<string, Value> newValues = null, int offset = 0) 
{ 
    try 
    { 
     T data1 = Instance.Deserialize<T>(data, settings, offset); 
     return (data1 != null && newValues != null && newValues.Count() > 0) ? data1.Convert<T, Value>(newValues) : data1; 
    } catch (Exception e) { 
     log.Error($"JsonUtil.{nameof(Deserialize)}: Exception {e}"); 
    } 
    return default(T); 
} 
public T Deserialize<T, Value>(byte[] data, JsonSerializerSettings settings, string name, Value newValue, int offset = 0, object[] index = null) 
{ 
    try 
    { 
     data1 = Instance.Deserialize<T>(data, settings, offset); 
     return (data1 != null && !string.IsNullOrEmpty(name)) ? data1.Convert<T, Value>(name, newValue, index) : data1; 
    } catch (Exception e) { 
     log.Error($"JsonUtil.{nameof(Deserialize)}: Exception {e}"); 
    } 
    return default(T); 
} 
public static class PropertyConverter 
{ 
    private static readonly ILog log = LogManager.GetLogger("PropertyConverter"); 
    public static T Convert<T, Value>(this T data, Dictionary<string, Value> newValues) 
    { 
     Stopwatch sw = Stopwatch.StartNew(); 
     FixPropertyValues(data, newValues); 
     sw.Stop(); 
     return data; 
    } 
    public static T Convert<T, Value>(this T data, string name, Value newValue, object[] index = null) 
    { 
     FixPropertyValues(data, name, newValue, index); 
     return data; 
    } 
    private static void FixPropertyValues<T>(object obj, Dictionary<string, T> newValues) 
    { 
     if (obj != null) 
     try 
     { 
      Type objType = obj.GetType(); 
      PropertyInfo[] properties = objType.GetProperties(); 
      foreach (PropertyInfo property in properties) 
       if (newValues.ContainsKey(property.Name)) 
        property.SetValue(obj, newValues[property.Name], null); 
       else { 
        object propValue = property.GetValue(obj, null); 
        var elems = propValue as IList; 
        if (elems != null) 
         foreach (var item in elems) 
          FixPropertyValues(item, newValues); 
        else if (property.PropertyType.Assembly == objType.Assembly) 
         FixPropertyValues(propValue, newValues); 
       } 
     } catch (Exception e) { 
      log.Error($"{nameof(FixPropertyValues)}: Exception {e}"); 
     } 
    } 
    private static void FixPropertyValues<T>(object obj, string name, T newValue, object[] index = null) 
    { 
     if (obj != null) 
     try 
     { 
      Type objType = obj.GetType(); 
      PropertyInfo[] properties = objType.GetProperties(); 
      foreach (PropertyInfo property in properties) 
       if (property.Name == name) 
        property.SetValue(obj, newValue, null); 
       else { 
        object propValue = property.GetValue(obj, null); 
        var elems = propValue as IList; 
        if (elems != null) 
         foreach (var item in elems) 
          FixPropertyValues(item, name, newValue, index); 
        else if (property.PropertyType.Assembly == objType.Assembly) 
         FixPropertyValues(propValue, name, newValue, index); 
       } 
     } catch (Exception e) { 
      log.Error($"{nameof(FixPropertyValues)}: Exception {e}"); 
     } 
    } 
}