如何使用反射通过列表显示 Web 服务的属性<CustomClass>

How to use reflection to show properties of Web Service with a List<CustomClass>

我在 this question 上成功实施了答案。但是,当我有一个列表时它不起作用。当我 运行 通过时,这是我得到的结果:

AccountDataResult: 'AccountFound'
AccountList: 'CustomWebService.TestApplication.ServiceMethods.CustomClassOutputData+DataList[]'

此列表中有 X 个项目,我需要列出每个项目的所有属性。实现此目标的最佳方法是什么?

这是我今天的内容:

void AddPropertiesToTextbox(object output, TextBox txt)
{
   PropertyInfo[] piData = null;
   piData = Utility.GetPublicProperties(output.GetType());

   foreach (PropertyInfo pi in piData)
   {
      if (pi.Name.ToLower() != "extensiondata")
      {
         textResult.Text += string.Format("{0}: '{1}'", pi.Name, pi.GetValue(output, null));
         textResult.Text += Environment.NewLine;
      }
   }
}

这是我的网络服务模型:

[DataContract]
public class OutputData
{
    [DataContract]
    public class AccountData
    {
        [DataMember]
        public string AccountStatus { get; set; }

        [DataMember]
        public string FirstName { get; set; }

        [DataMember]
        public string LastName { get; set; }

    }

    [DataContract]
    public enum AccountDataResults
    {
        [EnumMember]
        None,
        [EnumMember]
        AccountFound,
        [EnumMember]
        NoAccounts
    }

    [DataMember]
    public List<AccountData> DataList { get; set; }

    [DataMember]
    public AccountDataResults AccountDataResult { get; set; }
}

您可以查看 PropertyInfo's PropertyType type definition by calling GetGenericTypeDefinition()

if(pi.PropertyType.GetGenericTypeDefinition() == typeof(List<>))
{
   // recurse through properties
}

演示:

class Program
{
    static void Main(string[] args)
    {
        object test = new Test { DemoProperty = "Some", DemoListProperty = new List<int> { 1, 2, 3, 4 } };

        Type type = typeof(Test);
        foreach (var pi in type.GetProperties())
        {
            if (pi.PropertyType.IsGenericType && pi.PropertyType.GetGenericTypeDefinition() == typeof(List<>))
            {
                IEnumerable objects = pi.GetGetMethod().Invoke(test,null) as IEnumerable;
                foreach (var o in objects)
                {
                    Console.WriteLine(o); //may want to do recursion here and iterate over these properties too
                }
            }
        }
    }
}

class Test
{
    public string DemoProperty { get; set; }
    public List<int> DemoListProperty { get; set; }
}

为了让它正常工作,我不得不放弃我的初始设置。这就是我现在正在做的。这对我来说非常有用!这用于将我关心的所有属性 拉入结果列表。

获取任何类型的所有属性:

public static PropertyInfo[] GetPublicProperties2(this Type type)
{
    return type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
}

然后我有了这个方法,它对任何 属性 都是通用的,它在有数组时调用自身。

void AddPropertiesToTextbox(object output, string rootNamespace = "")
    {
        PropertyInfo[] piData = null;
        piData = Utility.GetPublicProperties2(output.GetType());

        foreach (PropertyInfo pi in piData)
        {
            if (pi.PropertyType.IsArray == true)
            {
                Array subOutput = (Array)pi.GetValue(output);


                for (int i = 0; i < subOutput.Length; i++)
                {
                    textResult.Text += string.Format("{0}------------------------{0}", Environment.NewLine);
                    object o = subOutput.GetValue(i);
                    AddPropertiesToTextbox(o, pi.Name);
                }
            }
            else
            {
                if (pi.Name.ToLower() != "extensiondata")
                {
                    if (string.IsNullOrWhiteSpace(rootNamespace) == false) {
                        textResult.Text += string.Format("{2}.{0}: '{1}'", pi.Name, pi.GetValue(output, null), rootNamespace);
                    textResult.Text += Environment.NewLine;
                    } else {
                        textResult.Text += string.Format("{0}: '{1}'", pi.Name, pi.GetValue(output, null));
                    textResult.Text += Environment.NewLine;
                    }

                }
            }
        }
    }