2016-07-06 62 views
5

是否有任何方法從JsonSerializer類中取出設置並將它們重新實現爲新的JsonSerializer將JsonSerializerSettings從JsonSerializer複製到新的JsonSerializer

似乎沒有任何方法可以做這樣的事情。我發現的最好的方法是通過反射來調用的私人方法,ApplySerializerSettings

我試圖從WriteJson方法採取序列化程序,並將其複製到一個新的序列化器,調整了一下。具體而言,我想替換ContractResolver

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 

回答

3

看起來像最好的方法是將所有設置複製到一個新的對象。有很多,所以這裏有一個很好的擴展方法來處理(從8.0.3開始)。

public static class JsonSerializerExtensions 
{ 
    public static JsonSerializer DeepCopy(this JsonSerializer serializer) 
    { 
    var copiedSerializer = new JsonSerializer 
    { 
     Context = serializer.Context, 
     Culture = serializer.Culture, 
     ContractResolver = serializer.ContractResolver, 
     ConstructorHandling = serializer.ConstructorHandling, 
     CheckAdditionalContent = serializer.CheckAdditionalContent, 
     DateFormatHandling = serializer.DateFormatHandling, 
     DateFormatString = serializer.DateFormatString, 
     DateParseHandling = serializer.DateParseHandling, 
     DateTimeZoneHandling = serializer.DateTimeZoneHandling, 
     DefaultValueHandling = serializer.DefaultValueHandling, 
     EqualityComparer = serializer.EqualityComparer, 
     FloatFormatHandling = serializer.FloatFormatHandling, 
     Formatting = serializer.Formatting, 
     FloatParseHandling = serializer.FloatParseHandling, 
     MaxDepth = serializer.MaxDepth, 
     MetadataPropertyHandling = serializer.MetadataPropertyHandling, 
     MissingMemberHandling = serializer.MissingMemberHandling, 
     NullValueHandling = serializer.NullValueHandling, 
     ObjectCreationHandling = serializer.ObjectCreationHandling, 
     PreserveReferencesHandling = serializer.PreserveReferencesHandling, 
     ReferenceResolver = serializer.ReferenceResolver, 
     ReferenceLoopHandling = serializer.ReferenceLoopHandling, 
     StringEscapeHandling = serializer.StringEscapeHandling, 
     TraceWriter = serializer.TraceWriter, 
     TypeNameHandling = serializer.TypeNameHandling, 
     SerializationBinder = serializer.SerializationBinder, 
     TypeNameAssemblyFormatHandling = serializer.TypeNameAssemblyFormatHandling 
    }; 
    foreach (var converter in serializer.Converters) 
    { 
     copiedSerializer.Converters.Add(converter); 
    } 
    return copiedSerializer; 
    } 
} 

這很醜,但至少你只需要寫一次。 請稍微小心,因爲屬性本​​身不會被深度複製。

下面的答案取決於您的實施,特別是在解決合同時。保持它以防萬一它有助於某人。


所以,我不能完全複製設置,但我發現了一個很好的解決方法,可能需要考慮。您可以在鎖定的上下文中簡單地設置要更改的屬性,然後重新設置它們。

public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) 
{ 
    var thing = value as IThing; 

    if (thing == null) 
     throw new ArgumentException($"Writing Json failed because " + 
      "value was not a 'Thing' of type, {typeof(IThing).FullName}"); 

    JObject jsonThing; 
    //If your solution is multithreaded, 
    //and is using a shared serializer (which you probably are), 
    //you should lock the serializer so that it doesn't accidentally use 
    //the "CustomObjectResolver" 
    lock (serializer) 
    { 
     //Hold the original value(s) to reset later 
     var originalContractResolver = serializer.ContractResolver; 
     //Set custom value(s) 
     serializer.ContractResolver = new CustomObjectResolver(); 
     //Serialization with custom properties 
     jsonThing = JObject.FromObject(value, serializer); 
     //Reset original value(s) 
     serializer.ContractResolver = originalContractResolver; 
    } 

    //Finish serializing and write to writer. 
} 
+1

謝謝,省得我打出來!雖然我們必須這樣做,但實際上應該在Newtonsoft.Json中內置一些東西 – Tyson

相關問題