SqlTableProfileProvider,自定义ProfileBase类,为属性添加额外属性

时间:2011-07-09 19:58:55

标签: c# asp.net

我使用SqlTableProfileProvider作为我的配置文件提供程序,并使用一个名为“ProfileCommon”的自定义类继承自System.Web.Profile.ProfileBase。我的ProfileCommon类属性表示我的配置文件表中的列,每个属性都获得[CustomProviderData(“columnName; dbType”)]的属性。我正在尝试向特定列添加新属性,然后我将从SqlTableProfileProvider类中提取该信息。

团队和我正在寻找将外键(表)与我们的Profile表相关联。现在,我们的Profile表基本上存储了键值对,FirstName,LastName,Age等;但是,我们计划存储书签,指向喜爱文章的链接以及不会发布的内容,这些内容将显示在仪表板页面的列表中。我们喜欢使用SqlTableProfileProvider和我创建的ProfileCommon对象。我们所有的asp.net页面都从一个BasePage继承,一个名为Profile的属性获取了一个profile公共对象。

能够这样做会很好:

Profile.Bookmarks.Count; // to know if there are bookmarks

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

例如:

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?
        }
    }
}

SqlTableProfileProvider由Hao Kung实现。它继承自ProfileProvider。

其中一个方法GetPropertyValues返回一个SettingsPropertyValueCollection。有一个名为GetProfileDataFromTable的私有方法。在那里,我希望访问我创建的自定义属性。

问题:如何访问我在属性上指定的属性?

更新:07162011:1517,提问后7天,

我确实找到了办法。以下是我的做法:

// 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 < 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]);
                            }
                        }
                    }
                }
            }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

您只需要像示例中那样实现ProfileCommon,并确保属性正确。

对于专门的个人资料属性书签,您也可以像在示例中一样编写自己的个人资料类。在那里,您必须实现一个Count属性,该属性将在数据库中查询该用户的书签数量。

在数据库的“配置文件”表中,您将拥有一个具有合适FK类型的“书签”列,例如Guid,Int或BigInt,它们只不过是另一个可以命名为[dbo]的表的外键。[书签]这实际上包含每个用户的书签。此Bookmarks表应该有一个类似UserId的列,它将是ASP.NET UserId的FK。