如何使用反射通过列表显示 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;
}
}
}
}
}
我在 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;
}
}
}
}
}