我在ViewModels中使用了一个结构,以简化它们自动序列化的方式。我想对其进行序列化以仅调用.ToString()
方法。当前,当它序列化为JSON时,它变成:“ {}
”。这是我的Date类:
public struct Date
{
private DateTime _date;
public Date(DateTime date)
{
_date = date;
}
public static implicit operator Date(DateTime date) => new Date(date);
public override string ToString() => _date.ToString("yyyy-MM-dd");
}
我认为可能存在某种属性可以用来装饰该结构,或者可以实现某些接口,但这似乎没有帮助。
答案 0 :(得分:1)
很多时候,当项目更大时,很多类都需要这样做。
我们需要转换才能双向工作。应该使用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有影响。
答案 1 :(得分:0)
经过进一步研究,MVC似乎使用JsonConverter
属性来序列化JsonResult
。下面的代码完成了我想做的事情。
[JsonConverter(typeof(DateToString))]
public struct Date
{
private DateTime _date;
public Date(DateTime date)
{
_date = date;
}
public static implicit operator Date(DateTime date) => new Date(date);
public override string ToString() => _date.ToString("yyyy-MM-dd");
}
public class DateToString : JsonConverter
{
public override bool CanConvert(Type objectType) => objectType == typeof(Date);
public override bool CanRead => false;
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
=> throw new NotImplementedException();
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer) =>
writer.WriteValue(value.ToString());
}