简体   繁体   English

使用反射C#获取自定义数据类型的属性的属性

[英]Get properties of property of a custom data type, with reflection c#

Short description: I need to sanitize some text before it is saved in the database. 简短说明:我需要先清理一些文本,然后再将其保存到数据库中。 We have a project that contain all the models that are used in our MVC application. 我们有一个项目,其中包含在MVC应用程序中使用的所有模型。 There's a Save(T record) method that saves the entity to the database. 有一个Save(T record)方法,可以将实体保存到数据库中。 What I was asked to do is to sanitize every property of type string of the incoming object, before saving it to the database. 我被要求做的是清理传入对象的字符串类型的每个属性,然后再将其保存到数据库中。 However, there's a problem: How do I sanitize the properties of the property of a custom data type, from the incoming entity? 但是,存在一个问题: 如何从传入实体中清除自定义数据类型的属性的属性?

Long description: Let's say I have a class of type Address and a class of type Person that has a property of type Address: 详细说明:假设我有一个地址类型的类和一个人类型的类,它具有地址类型的属性:

    public class Address
    {
        public string StreetName { get; set; }
        public string City { get; set; }
        public int StreetNumber { get; set; }
    }

    public class Person
    {
        public string PersonName { get; set; }
        public Address HomeAddress { get; set; }
    }

Before I was using this generic method to retrieve the properties of type string: 在使用此通用方法检索字符串类型的属性之前:

        public static void SanitizeObject<TEntity>(TEntity record)
        {
            var props =
                record.GetType().GetProperties()
                    .Where(x => x.CanRead && x.CanWrite)
                    .Where(x => x.PropertyType == typeof (string));
            foreach (var property in props)
            {
                string value = Convert.ToString(record.GetPropertyValue(property.Name));
                if (!string.IsNullOrEmpty(value))
                {
                    value = Sanitize(value);
                    record.SetPropertyValue(property.Name, value);
                }
            }
        }

In that case I will sanitize only the Person.PersonName , however, I need to sanitize also the Address.StreetName and the Address.City 在这种情况下,我将仅Person.PersonName ,但是,我还需要清理Address.StreetNameAddress.City

Is there a way to write this lambda expression to get the childrens' properties of type string also? 有没有一种方法可以编写此lambda表达式来获取字符串类型的孩子的属性? How should I perform this to get all the properties of type string so i could sanitize them? 我应该如何执行此操作以获取string类型的所有属性,以便对其进行清理?

It seems like you need a recursive method. 似乎您需要一个递归方法。

Pseudo-code: 伪代码:

public void SanitizeObject(object some)
{
    // We get properties which are of reference types because we don't want to iterate value types (do you want to sanitize an integer...?)
    foreach (PropertyInfo property in some.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance).Where(prop => !prop.PropertyType.IsValueType)
    {
        if (property.PropertyType == typeof (string))
        {
        // Do stuff to sanitize the string
        }
        else
        {
            // Get properties declared in the concrete class (skip inherited members)
            var properties = property.DeclaringType.GetProperties(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance);

            // Does the property type has properties?
            if (properties != null && properties.Length > 0)
            {
                // This gets the custom object and starts a recursion to sanitize its string properties if the object have string properties, of course...
                SanitizeObject(property.GetValue(some));
            }
        }
    }
}

Note that I removed the generic parameter. 请注意,我删除了通用参数。 I believe that, as you'll use reflection to get properties to sanitize, there's no advantage on using generics at all. 我相信,由于您将使用反射来清理属性,因此使用泛型根本没有任何优势。 And using this approach you'll be able to sanitize any objects instead of only supporting entity types. 使用这种方法,您将能够清理所有对象,而不仅仅是支持实体类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM