我首先使用的是EF5数据库。为了序列化生成的POCO类,我需要使用XMLIgnore属性,如下所示
public partial class Demographics
{
public string KeyTract { get; set; }
public string CollectionYear { get; set; }
public string MSAFIPS { get; set; }
...
...
...
[XmlIgnore()]
public virtual ICollection<LoanApp> LoanApps { get; set; }
}
为了防止在每次我从数据库中重新创建模型时添加这个,我添加了一个“伙伴类”
[MetadataType(typeof(Demographic_Metadata))]
public partial class Demographics
{
}
public class Demographic_Metadata
{
[XmlIgnore()]
public virtual ICollection<LoanApp> LoanApps { get; set; }
}
但是当我尝试使用XmlSerializer序列化Demographics对象时,我得到“反映类型的错误......人口统计数据”。
在研究SO时,似乎XMLSerializer忽略了伙伴类。但有没有人找到一个解决方法,以避免每次重新生成POCO类时添加XMLIgnore属性?
答案 0 :(得分:1)
您可以通过使用传递XmlAttributeOverrides的XmlSerializer重载来执行此操作。我们需要做的就是通过TypeDescriptor填充它并创建一个ICustomAttributeProvider。
首先,ICustomAttributeProvider是最简单的,主要是因为我只是忽略了inhert标志并且总是返回所有属性。我们的想法是,我们将传递我们希望XmlSerializer了解的属性。
public class CustomAttributeProvider : ICustomAttributeProvider
{
private readonly object[] _attributes;
public CustomAttributeProvider(params Attribute[] attributes)
{
_attributes = attributes;
}
public CustomAttributeProvider(AttributeCollection attributeCollection)
: this(attributeCollection.OfType<Attribute>().ToArray())
{
}
public object[] GetCustomAttributes(bool inherit)
{
return _attributes;
}
public object[] GetCustomAttributes(Type attributeType, bool inherit)
{
return _attributes.Where(attributeType.IsInstanceOfType).ToArray();
}
public bool IsDefined(Type attributeType, bool inherit)
{
return _attributes.Any(attributeType.IsInstanceOfType);
}
}
现在我要创建一个工厂方法来创建XMLAttributeOverrides。
我们需要告诉TypeDescriptor关于好友类以及将AssociatedMetadataTypeTypeDescriptionProvider添加到提供者列表的内容。
由此我们使用TypeDescriptor来读取类属性和属性。由于好友类不允许使用字段,TypeDescriptor也不会读取字段,所以我对字段使用反射。
public static class BuddyClass
{
public static XmlAttributeOverrides CreateXmlAttributeOverrides(Type type)
{
// Tell TypeDescriptor about the buddy class
TypeDescriptor.AddProvider(new AssociatedMetadataTypeTypeDescriptionProvider(type), type);
var xmlAttributeOverrides = new XmlAttributeOverrides();
xmlAttributeOverrides.Add(type, new XmlAttributes(new CustomAttributeProvider(TypeDescriptor.GetAttributes(type))));
foreach (PropertyDescriptor props in TypeDescriptor.GetProperties(type))
{
if (props.Attributes.Count > 0)
{
xmlAttributeOverrides.Add(type, props.Name, new XmlAttributes(new CustomAttributeProvider(props.Attributes)));
}
}
foreach (var field in type.GetFields())
{
var attributes = field.GetCustomAttributes(true).OfType<Attribute>().ToArray();
if (attributes.Any())
{
xmlAttributeOverrides.Add(type, field.Name, new XmlAttributes(new CustomAttributeProvider(attributes)));
}
}
return xmlAttributeOverrides;
}
}
你会称之为
var serializer = new XmlSerializer(typeof(Test), BuddyClass.CreateXmlAttributeOverrides(typeof(Test)));
然后就像你通常那样的用户序列化器。这不会处理参数或返回值的属性。