很多时候,当项目更大时,很多课程都需要这样做。
我们需要双向转换。一个类应该使用ToString() 方法进行序列化,并且该类应该从String 中反序列化。我们使用以下约定。
定义标记接口,让类明确遵守它们支持使用 ToString 方法进行序列化并支持从字符串到对象实例的反序列化的约定。
/// <summary>
/// Interface to convert string to a type T
/// </summary>
public interface IStringToTypeConverter<out T>
{
T ConvertToType(string stringToConvertFrom);
}
/// <summary>
/// Marker Interface to let Serialization/Deserialization work on the ToString Method of the class, Rather than
/// calling on the Instance properties
/// </summary>
public interface ITypeToStringConverter
{
}
接下来,定义通用转换器,它将为实现上述接口的类进行转换(序列化/反序列化)。
public class ToStringJsonConverter : JsonConverter
{
public override bool CanConvert(Type objectType)
{
var isTypeImplementStringToTypeConverter = objectType.GetInterfaces().Any(x =>
x == typeof(ITypeToStringConverter) ||
(x.IsGenericType &&
x.GetGenericTypeDefinition() == typeof(IStringToTypeConverter<>)));
return isTypeImplementStringToTypeConverter;
}
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
writer.WriteValue(value.ToString());
}
public override bool CanRead
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
// Load the JSON for the Result into a JObject
var stringValue = reader.Value.ToString();
if (string.IsNullOrWhiteSpace(stringValue))
{
var jObject = JObject.Load(reader);
stringValue = jObject.ToString();
}
MethodInfo parse = objectType.GetMethod("ConvertToType");
if (parse != null)
{
var destinationObject = Activator.CreateInstance(objectType,stringValue);
return parse.Invoke(destinationObject, new object[] { stringValue });
}
throw new JsonException($"The {objectType.Name} type does not have a public ConvertToType(string) method.");
}
}
最后,将 Converter 添加到启动类中,并在 JSON 选项中传递它
services.AddMvc().AddJsonOptions(options =>
{
options.SerializerSettings.Converters.Add(new ToStringJsonConverter());
})
注意:请测试您的代码的性能基准,看看它是否对您的性能 SLA 有任何影响。