1

当我将“XmlAttribute/XmlElement”添加到接口中的属性并且 100 个其他类从该接口继承时,将对象序列化为 XML 时 - 为什么序列化后我输入的属性名没有显示在 XML 文件中?

interface Test
{
    [XmlAttribute("Name")]
    bool PropertyName { get; set; }
}

保存文件时,显示“PropertyName”而不是“Name”。

有没有办法让它工作,所以一个带有 XmlAttributes 添加到接口的属性会在任何地方更改 Value 而不是 Value 因为如果一些类从同一个接口继承,则需要花费大量时间将所有这些属性添加到所有这些类继承它,并且更改属性的名称而不是更改其中的 100 个会更容易。

4

4 回答 4

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”之类的属性以及此示例中特定类别的此类和其他属性。

于 2012-04-30T17:12:04.727 回答
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 . . .
于 2012-04-30T20:29:46.263 回答
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;
        }

}
于 2012-04-30T01:49:34.520 回答
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;
}

自己试试。让我知道它是否有效。

于 2012-04-30T18:18:26.297 回答