Много раз, это требуется во многих классах, когда проект больше.
Нам нужно, чтобы преобразование работало в обе стороны.Класс должен быть сериализован с использованием метода 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.");
}
}
Наконец, добавьте конвертер в класс запуска, передав его в параметрах JSON
services.AddMvc().AddJsonOptions(options =>
{
options.SerializerSettings.Converters.Add(new ToStringJsonConverter());
})
Примечание. Пожалуйста, проверьте показатели производительности для своего кода, чтобы увидеть, влияет ли это на вашу SLA производительности.