根据我的阅读,用于 ViewState 序列化的 LosFormatter 类会检查给定对象是否存在 TypeConverter 并使用它,因此您应该了解那里。
This article 描述了如何创建自己的 JavaScriptConverter 来执行自定义序列化。您必须实现的 Serialize 方法返回 IDictionary<string, object>,因此您可能必须为您的 Entity 类而不是您的 IdType 结构创建一个 JavaScriptConverter 类。下面是一个例子,虽然我还没有机会测试它:
注意:我帖子中的示例只是查找 IdType 的关联 TypeConverter 以便将其转换为字符串,但除非有特定原因这样做,否则您最好调用特定函数(例如覆盖ToString) 直接返回字符串表示,而不是像我的示例代码那样查找 TypeConverter。
public class EntityJsonConverter : System.Web.Script.Serialization.JavaScriptConverter
{
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
throw new NotImplementedException();
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
if (obj == null)
throw new ArgumentNullException("obj");
Entity entity = obj as Entity;
if (entity != null)
{
var values = new Dictionary<string, object>();
TypeConverter idTypeConverter = TypeDescriptor.GetConverter(entity.Id);
if (idTypeConverter != null)
{
if (idTypeConverter.CanConvertTo(typeof(string)))
values.Add("Id", idTypeConverter.ConvertTo(entity.Id, typeof(string)));
else
throw new SerializationException(string.Format("The TypeConverter for type \"{0}\" cannot convert to string.", this.GetType().FullName));
}
else
throw new SerializationException(string.Format("Unable to find a TypeConverter for type \"{0}\".", this.GetType().FullName));
values.Add("Data", serializer.Serialize(entity.Data));
return values;
}
else
throw new ArgumentException(string.Format("Expected argument of type \"{0}\", but received \"{1}\".", typeof(Entity).FullName, obj.GetType().FullName), "obj");
}
public override IEnumerable<Type> SupportedTypes
{
get { yield return typeof(Entity); }
}
}
如果您还想要为 XML 序列化描述的行为,您可以让 IdType 结构实现 IXmlSerializable 接口。下面是一个使用为 IdType 结构定义的 TypeConverter 的 WriteXml 方法实现示例:
void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
{
TypeConverter converter = TypeDescriptor.GetConverter(this);
if (converter != null)
{
if (converter.CanConvertTo(typeof(string)))
writer.WriteString(converter.ConvertTo(this, typeof(string)) as string);
else
throw new SerializationException(string.Format("The TypeConverter for type \"{0}\" cannot convert to string.", this.GetType().FullName));
}
else
throw new SerializationException(string.Format("Unable to find a TypeConverter for type \"{0}\".", this.GetType().FullName));
}