当我添加" XmlAttribute / XmlElement"在将对象序列化为XML时,接口中的属性和其他100个类继承了这一点 - 为什么我输入的属性名在序列化后不会显示在XML文件中?
interface Test
{
[XmlAttribute("Name")]
bool PropertyName { get; set; }
}
保存文件时,显示" PropertyName"而不是"姓名"。
有没有办法使它工作,所以添加到接口的XmlAttributes的proeprty改变Value到处而不是Value,因为如果一些类继承自同一个接口,则需要很多时间来将所有这些属性添加到所有继承它的类,更改属性的名称而不是更改其中的100个更容易。
答案 0 :(得分:1)
我更改了代码以更适合我的项目。我做的是这个:
public static XmlAttributeOverrides GetXmlAttributeOverrides(Type type)
{
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
foreach (Type derived in ClassHandler.GetImplementedInterfaces(type))
{
foreach (PropertyInfo propertyInfo in derived.GetProperties())
{
XmlAttributeAttribute xmlAttributeAttribute = ClassHandler.GetCustomAttribute<XmlAttributeAttribute>(propertyInfo, true) as XmlAttributeAttribute;
if (xmlAttributeAttribute == null) continue;
XmlAttributes attr1 = new XmlAttributes();
attr1.XmlAttribute = new XmlAttributeAttribute();
attr1.XmlAttribute.AttributeName = xmlAttributeAttribute.AttributeName;
overrides.Add(type, propertyInfo.Name, attr1);
}
}
return overrides;
}
我正在尝试使用属性实现接口的对象都有“[XmlAttributeAttribute(SomeName)]”。
但是,当我序列化它时会得到相同的结果。我没有从界面获取属性值。
这是我序列化的方式:
public static void SerializeFile(String filename, object obj, bool deleteIfExists = true)
{
if (deleteIfExists)
{
FileManager.DeleteFile(filename);
}
Type[] extraTypes = ClassHandler.GetPropertiesTypes(obj, true);
using (var stream = new FileStream(filename, FileMode.Create))
{
//XmlSerializer xmlSerialize = new XmlSerializer(obj.GetType(), extraTypes);
XmlSerializer xmlSerialize = new XmlSerializer(obj.GetType(), GetXmlAttributeOverrides(obj.GetType()), extraTypes, null, null);
xmlSerialize.Serialize(stream, obj);
}
}
我在ClassHandler类中使用的两种方法:
public static T GetCustomAttribute<T>(this PropertyInfo propertyInfo, bool inherit) where T : Attribute
{
object[] attributes = propertyInfo.GetCustomAttributes(typeof(T), inherit);
return attributes == null || attributes.Length == 0 ? null : attributes[0] as T;
}
public static List<Type> GetImplementedInterfaces(Type type)
{
Type[] types = type.GetInterfaces();
List<Type> lTypes = new List<Type>();
foreach(Type t in types)
{
lTypes.Add(t);
}
return lTypes;
}
类具有以下结构:
interface IAnimal
{
// Properties
// Methods
}
public abstract class Animal : IAnimal
{
// Implements IAnimal properties and methods
// This XmlElement gets written correctly when XML Serializing
// Example:
[XmlElement("AnimalAge")]
public double Age
{
get { return _age; }
set { _age = value; }
}
}
public abstract class Bird : Animal, IAttributeWings
{
// Implements Attributes common for all "Birds"
// Setting "override" here gives me error
public bool HasWings { get { return _hasWings; } set { _hasWings = value; } }
}
public class Pelican : Bird, IAttributeCanFly
{
// Implements Attributes common for all "Pelicans"
// Does not implement previous attribute IAttributeWings since Bird class does this
// Setting "override" here gives me error as well
public bool CanFly { get { return _canFly; } set { _canFly = value; } }
}
然后属性接口只有像“bool CanFly,bool hasWings”这样的属性,以及特定类别的其他属性,如本例所示。
答案 1 :(得分:1)
Deukalin,花了一些时间,并使用全面的类和接口树。
这是工作代码
public interface ITestX
{
[XmlAttribute("NameX")]
string PropertyNameX { get; set; }
}
public interface ITestY
{
[XmlAttribute("NameY")]
string PropertyNameY { get; set; }
}
public interface ITestZ
{
[XmlAttribute("NameZ")]
string PropertyNameZ { get; set; }
}
public abstract class TestC : ITestZ
{
public abstract string PropertyNameZ { get; set; }
}
public abstract class TestA : TestC, ITestX, ITestY
{
public abstract string PropertyNameX { get; set; }
public abstract string PropertyNameY { get; set; }
}
public class TestB : TestA
{
public override string PropertyNameX { get; set; }
public override string PropertyNameY { get; set; }
public override string PropertyNameZ { get; set; }
}
public static class ClassHandler
{
public static T GetCustomAttribute<T>(this PropertyInfo propertyInfo, bool inherit) where T : Attribute
{
object[] attributes = propertyInfo.GetCustomAttributes(typeof(T), inherit);
return attributes == null || attributes.Length == 0 ? null : attributes[0] as T;
}
public static void GetXmlAttributeOverrides(XmlAttributeOverrides overrides, Type type)
{
if (type.BaseType != null)
{
GetXmlAttributeOverrides(overrides, type.BaseType);
}
foreach (Type derived in type.GetInterfaces())
{
foreach (PropertyInfo propertyInfo in derived.GetProperties())
{
XmlAttributeAttribute xmlAttributeAttribute = ClassHandler.GetCustomAttribute<XmlAttributeAttribute>(propertyInfo, true) as XmlAttributeAttribute;
if (xmlAttributeAttribute == null)
continue;
XmlAttributes attr1 = new XmlAttributes();
attr1.XmlAttribute = new XmlAttributeAttribute();
attr1.XmlAttribute.AttributeName = xmlAttributeAttribute.AttributeName;
overrides.Add(type, propertyInfo.Name, attr1);
}
}
}
}
class Program
{
static void Main(string[] args)
{
XmlAttributeOverrides XmlAttributeOverrides = new XmlAttributeOverrides();
ClassHandler.GetXmlAttributeOverrides(XmlAttributeOverrides, typeof(TestB));
try
{
TestB xtest = new TestB() { PropertyNameX = "RajX", PropertyNameY = "RajY", PropertyNameZ = "RajZ" };
StringBuilder xmlString = new StringBuilder();
using (XmlWriter xtw = XmlTextWriter.Create(xmlString))
{
XmlSerializer serializer = new XmlSerializer(typeof(TestB), XmlAttributeOverrides);
serializer.Serialize(xtw, xtest);
xtw.Flush();
}
Console.WriteLine(xmlString.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
以下是上面样本的输出
<?xml version="1.0" encoding="utf-16"?><TestB xmlns:xsi="http://www.w3.org/2001/
XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" NameZ="RajZ" Na
meX="RajX" NameY="RajY" />
Press any key to continue . . .
答案 2 :(得分:0)
某些原因它在.NET中不起作用......但我想出了这个解决方案来克服你使用 XmlAttributeOverrides 的问题。有关它的更多信息,请访问以下链接
http://msdn.microsoft.com/en-us/library/system.xml.serialization.xmlattributeoverrides.aspx
您可以通过在应用程序中的某处重构/缓存此 GetXmlAttributeOverrides()方法来优化它。希望它有所帮助。
public interface ITest
{
[XmlAttribute("Name")]
string PropertyName { get; set; }
}
public class XTest : ITest
{
public string PropertyName
{
get;
set;
}
}
public class Program
{
static void Main(string[] args)
{
try
{
XTest xtest = new XTest() { PropertyName = "Raj" };
StringBuilder xmlString = new StringBuilder();
using (XmlWriter xtw = XmlTextWriter.Create(xmlString))
{
XmlSerializer serializer = new XmlSerializer(typeof(XTest), GetXmlAttributeOverrides(typeof(XTest)));
serializer.Serialize(xtw, xtest);
xtw.Flush();
}
Console.WriteLine( xmlString.ToString());
}
catch (Exception ex)
{
Console.WriteLine(ex.ToString());
}
}
public static XmlAttributeOverrides GetXmlAttributeOverrides(Type derivedType)
{
Type type = typeof(ITest);
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
XmlAttributes attr = new XmlAttributes();
foreach (PropertyInfo propertyInfo in type.GetProperties())
{
XmlAttributeAttribute xmlAttributeAttribute = propertyInfo.GetCustomAttribute(typeof(XmlAttributeAttribute), true) as XmlAttributeAttribute;
if (xmlAttributeAttribute == null) continue;
XmlAttributes attr1 = new XmlAttributes();
attr1.XmlAttribute = new XmlAttributeAttribute();
attr1.XmlAttribute.AttributeName = xmlAttributeAttribute.AttributeName;
overrides.Add(derivedType, propertyInfo.Name, attr1);
}
return overrides;
}
}
编辑:在您的应用中加入此扩展程序
public static class PropertyInfoEx
{
public static T GetCustomAttribute<T>(this PropertyInfo propertyInfo, bool inherit) where T : Attribute
{
object[] attributes = propertyInfo.GetCustomAttributes(typeof(T), inherit);
return attributes == null || attributes.Length == 0 ? null : attributes[0] as T;
}
}
答案 3 :(得分:0)
在您的代码中发现了一些问题。以下是更正后的代码
public static XmlAttributeOverrides GetXmlAttributeOverrides(Type type)
{
XmlAttributeOverrides overrides = new XmlAttributeOverrides();
// Get all interfaces that the "type" implements (is it same as "derivedType" from previously)?
foreach (Type derived in ClassHandler.GetImplementedInterfaces(type))
{
foreach (PropertyInfo propertyInfo in derived.GetProperties())
{
XmlAttributeAttribute xmlAttributeAttribute = ClassHandler.GetCustomAttribute<XmlAttributeAttribute>(propertyInfo, true) as XmlAttributeAttribute;
if (xmlAttributeAttribute == null) continue;
XmlAttributes attr1 = new XmlAttributes();
attr1.XmlAttribute = new XmlAttributeAttribute();
attr1.XmlAttribute.AttributeName = xmlAttributeAttribute.AttributeName;
overrides.Add(type, propertyInfo.Name, attr1);
}
}
return overrides;
}
亲自尝试。如果有效,请告诉我。