我正在编写JsonConverter
来执行我需要在读/写上完成的一些转换任务。特别是,我正在采用现有的序列化行为,并在读取时读取/读取这些附加属性时添加一些其他属性。
在JsonConverter
内,我想利用传递的JsonSerializer
实例来执行大部分转换功能。但是,当我这样做时,我最终进入一个递归循环,在这个循环中,串行器调用我的转换器调用进入转换器等的串行器。
我见过人们做的事情比如使用JsonConvert.SerializeObject
,传递序列化程序实例中的所有转换器,除了 this
。但是,这对我不起作用,因为它绕过了我在序列化程序上完成的所有其他自定义操作,例如自定义合约解析程序和DateTime
处理。
有没有办法可以:
答案 0 :(得分:3)
这是一个非常常见的问题。使用" JsonConvert.SerializeObject"不是一个坏主意。但是,在某些情况下(通常是集合)可以使用的一个技巧是在编写时转换到接口,并在读取时反序列化为简单的派生。
下面是一个简单的转换器,它处理可能被序列化为一组KVP而不是看起来像一个对象的字典(在这里显示我的年龄:))
注意" WriteJson"强制转换为IDictionary< K,V>和#34; ReadJson"使用" DummyDictionary"。你得到了正确的东西,但使用传递的序列化程序而不会导致递归。
/// <summary>
/// Converts a <see cref="KeyValuePair{TKey,TValue}"/> to and from JSON.
/// </summary>
public class DictionaryAsKVPConverter<TKey, TValue> : JsonConverter
{
/// <summary>
/// Determines whether this instance can convert the specified object type.
/// </summary>
/// <param name="objectType">Type of the object.</param>
/// <returns>
/// <c>true</c> if this instance can convert the specified object type; otherwise, <c>false</c>.
/// </returns>
public override bool CanConvert(Type objectType)
{
if (!objectType.IsValueType && objectType.IsGenericType)
return (objectType.GetGenericTypeDefinition() == typeof(Dictionary<,>));
return false;
}
/// <summary>
/// Writes the JSON representation of the object.
/// </summary>
/// <param name="writer">The <see cref="JsonWriter"/> to write to.</param>
/// <param name="value">The value.</param>
/// <param name="serializer">The calling serializer.</param>
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
var dictionary = value as IDictionary<TKey, TValue>;
serializer.Serialize(writer, dictionary);
}
/// <summary>
/// Reads the JSON representation of the object.
/// </summary>
/// <param name="reader">The <see cref="JsonReader"/> to read from.</param>
/// <param name="objectType">Type of the object.</param>
/// <param name="existingValue">The existing value of object being read.</param>
/// <param name="serializer">The calling serializer.</param>
/// <returns>The object value.</returns>
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
Dictionary<TKey, TValue> dictionary;
if (reader.TokenType == JsonToken.StartArray)
{
dictionary = new Dictionary<TKey, TValue>();
reader.Read();
while (reader.TokenType == JsonToken.StartObject)
{
var kvp = serializer.Deserialize<KeyValuePair<TKey, TValue>>(reader);
dictionary[kvp.Key] = kvp.Value;
reader.Read();
}
}
else if (reader.TokenType == JsonToken.StartObject)
// Use DummyDictionary to fool JsonSerializer into not using this converter recursively
dictionary = serializer.Deserialize<DummyDictionary>(reader);
else
dictionary = new Dictionary<TKey, TValue>();
return dictionary;
}
/// <summary>
/// Dummy to fool JsonSerializer into not using this converter recursively
/// </summary>
private class DummyDictionary : Dictionary<TKey, TValue> { }
}
答案 1 :(得分:-3)
您确实可以使用传递给转换器的序列化程序实例,并排除当前转换器。但是,这将不是线程安全的(请参阅此答案的注释)
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
serializer.Converters.Remove(this);
serializer.Serialize(writer, value);
serializer.Converters.Add(this);
}
答案 2 :(得分:-4)
抱歉,但也许我感到困惑。我使用这种方法来序列化我的对象:
using System;
using Newtonsoft.Json;
namespace Utilities
{
public static class serializer
{
public static string SerializeObject(object objectModel) {
return JsonConvert.SerializeObject(objectModel);
}
public static object DeserializeObject<T>(string jsonObject)
{
try
{
return JsonConvert.DeserializeObject<T>(jsonObject);
}
catch (Exception ex) { return null; }
}
}
}
&#13;
我使用了这段代码:
userLoged = (modelUser)serializer.DeserializeObject<modelUser>((string)Session["userLoged"]);
&#13;
我希望这会有所帮助。