我想为控制器编写一个自定义的json序列化程序,当它遇到一个非原语(不包括字符串/日期时间)时,它会在该对象中查找ID字段/属性,然后不是序列化整个对象,而是编写一个{ID,Name}(其中ID是ID的值,Name是数据对象的名称)。
这背后的目的是我编写一个缓存查看器,但缓存项可能会变得很大。我可以使用ID字段并忽略UI中的其余部分,但随后我可能会遇到在响应中发送大量数据的问题。
我无法弄清楚我应该从哪里开始,所以请原谅这个问题,如果它有点广泛。
额外备注: 我需要序列化的数据项在一个单独的库中,我无法访问它们,但我保证它们都将使用ID字段。如果我错过了一些数据点,这是可以的,因为它们是非原始的,非日期时间,非字符串字段。
这是我到目前为止只写原语:
public class FieldsOnlyFormatterConfig : Attribute, IControllerConfiguration
{
public void Initialize(HttpControllerSettings settings,
HttpControllerDescriptor descriptor)
{
// Clear the formatters list.
settings.Formatters.Clear();
var formatter = new JsonMediaTypeFormatter();
formatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore;
formatter.SerializerSettings.ContractResolver = new CustomResolver();
// Add a custom media-type formatter.
settings.Formatters.Add(formatter);
}
}
class CustomResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty prop = base.CreateProperty(member, memberSerialization);
if (member.MemberType == MemberTypes.Field && (prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(string)))
{
prop.ShouldSerialize = obj => true;
}
else
{
prop.ShouldSerialize = obj => false;
}
return prop;
}
}
答案 0 :(得分:0)
因此,随着一些更多的摆弄,我能够弄清楚如何完成我想要的。
我更改了自定义解析程序以检测我的属性类型是否为DataItem,然后将prop.Converter设置为使用自定义jsonConverter:
class CustomResolver : DefaultContractResolver
{
protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization)
{
JsonProperty prop = base.CreateProperty(member, memberSerialization);
if (member.MemberType == MemberTypes.Field && (prop.PropertyType.IsPrimitive || prop.PropertyType == typeof(string)))
{
prop.ShouldSerialize = obj => true;
}
else if (prop.PropertyType.IsSubclassOf(typeof(DataItem)))
{
prop.ShouldSerialize = obj => true;
prop.Converter = new DataItemConverter();
}
else
{
prop.ShouldSerialize = obj => false;
}
return prop;
}
}
在自定义json转换器中,在WriteJson上我将对象转换为DataItem(一个我知道我想要的所有内容的类,其中有“id”字段我正在寻找)然后做了一些自定义写入:
class DataItemConverter: JsonConverter
{
public override bool CanConvert(Type objectType)
{
return true;
}
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)
{
var di = value as DataItem;
writer.WriteStartObject();
writer.WritePropertyName("id");
writer.WriteValue(di.Id);
writer.WriteEndObject();
}
}