SqlTableProfileProvider, custom ProfileBase class, add extra attributes to properties
<p>I am using SqlTableProfileProvider as my profile provider and a custom class called 'ProfileCommon' inheriting from System.Web.Profile.ProfileBase. My ProfileCommon class properties that represent the columns in my profile table each get an attribute of [CustomProviderData("columnName;dbType")]. I am trying to add a new attribute to specific column and then am going to pull that info from the SqlTableProfileProvider class.</p>

<p>The team and I are looking to associate a foreign key (table) with our Profile table. Right now, our Profile table stores, basically, key value pairs, FirstName, LastName, Age, etc; however, we are planning to store bookmarks, links to favorite articles and what not, that will be presented in a list on our dashboard page. We like using the SqlTableProfileProvider and the ProfileCommon object I created. All our asp.net pages inherit from a BasePage and a property called Profile gets the profile common object. </p>

<p>It would be nice to just be able to do: </p>

<pre><code>Profile.Bookmarks.Count; // to know if there are bookmarks

// to also just be able to foreach through them
foreach (Bookmark bk in Profile.Bookmarks) { ... }
</code></pre>

<p>Ex:</p>

<pre><code>public class ProfileCommon : System.Web.Profile.ProfileBase
{
    public static ProfileCommon GetProfile() { .... }

    [CustomProviderData("FirstName;varchar")]
    public virtual string FirstName
    {
        get
        {
            return ((string)(this.GetPropertyValue("FirstName")));
        }
        set
        {
            this.SetPropertyValue("FirstName", value);
        }
    }

    [CustomProviderData("LastName;varchar")]
    public virtual string LastName
    {
        get
        {
            return ((string)(this.GetPropertyValue("LastName")));
        }
        set
        {
            this.SetPropertyValue("LastName", value);
        }
    }

    [CustomProviderData("OtherColumn;int")]
    [TableNameData("OtherTable")]
    public virtual int OtherColumn
    {
        get ...
        set ...
    }
}

// My new attribute
[AttributeUsage(AttributeTargets.Property)]
public class TableNameData : Attribute
{
    private string _tableName;

    public TableNameData(string tableName)
    {
        _tableName = tableName;
    }

    public string TableName
    {
        get
        {
            return _tableName;
        }
    }
}

// Not my implementation, but looking to enhance it.
public class SqlTableProfileProvider : ProfileProvider
{
    public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyValueCollection svc, string username, SqlConnection conn)
    {
        ...
        foreach (SettingsProperty prop in properties)
        {
            ...
            // in here, gets CustomProviderData
            string persistenceData = prop.Attributes["CustomProviderData"] as string.

            // how do i get to mine?
        }
    }
}
</code></pre>

<p>The SqlTableProfileProvider was implemented by Hao Kung. It inherits from ProfileProvider. </p>

<p>One of the methods GetPropertyValues returns a SettingsPropertyValueCollection. There is a private method called GetProfileDataFromTable. In there, I wish to access my custom attribute that I created. </p>

<p>Question: How do I access my attribute that I have specified on my property?</p>

<p>UPDATE: 07162011:1517, 7 days after question asked,</p>

<p>I did find a way to do this. The following is how I did it:</p>

<pre><code>// In the default constructor add the following
public ProfileCommon()
{
    //  Get all properties for this class 'ProfileCommon'
    PropertyInfo[] propertyInfos = typeof(ProfileCommon).GetProperties();

    //  The ProfileBase, base class, has a property called Properties and 
    //  one can get to all attributes on that property but there are only
    //  a few attributes that ProfileBase looks for. If the developer wishes
    //  to use custom attributes on a property, it wont appear in the 
    //  ProfileCommon.Properties.Attributes list.
    //  
    //  So, what are we going to do, well, we are going to come up with a hack and solution to this problem
    //
    foreach (SettingsProperty settingsProperty in ProfileCommon.Properties)
    {
        foreach (PropertyInfo propertyInfo in propertyInfos)
        {
            if (settingsProperty.Name == propertyInfo.Name)
            {
                //  get all attributes from the associated property, but we are getting it from the propertyInfo variable
                //  which was retrieved through reflection and will list ALL attributes.
                    object[] attributes = propertyInfo.GetCustomAttributes(false);

                for (int i = 0; i &lt; attributes.Count(); i++)
                {
                    Type type = attributes[i].GetType();

                    PropertyInfo[] attributeClassProperities = type.GetProperties();

                    foreach (PropertyInfo attributeClassProperty in attributeClassProperities)
                    {
                        //  not intested in the TypeId property for the object
                        if (!attributeClassProperty.Name.Equals("TypeId"))
                        {
                            //  if the settingsProperty.Attributes does not contain our key value pair, then add it.
                            if (settingsProperty.Attributes[attributeClassProperty.Name] == null)
                            {
                                    settingsProperty.Attributes.Add(attributeClassProperty.Name, attributes[i]);
                            }
                        }
                    }
                }
            }
        }
    }
}
</code></pre>
