代码之家  ›  专栏  ›  技术社区  ›  Mathias F

配置文件系统:用户共享相同的id

  •  0
  • Mathias F  · 技术社区  · 14 年前

    我只需要一个点开始调试。我猜有一个cookie值映射到某个配置文件条目。有没有机会看看这个映射是如何工作的?

    这是我的个人资料提供者:

    using System;
    using System.Text;
    using System.Configuration;
    using System.Web;
    using System.Web.Profile;
    using System.Collections;
    using System.Collections.Specialized;
    using B2CShop.Model;
    using log4net;
    using System.Collections.Generic;
    using System.Diagnostics;
    using B2CShop.DAL;
    using B2CShop.Model.RepositoryInterfaces;
    [assembly: log4net.Config.XmlConfigurator()]
    namespace B2CShop.Profile
    {
        public class B2CShopProfileProvider : ProfileProvider
        {
            private static readonly ILog _log = LogManager.GetLogger(typeof(B2CShopProfileProvider));
            // Get an instance of the Profile DAL using the ProfileDALFactory
            private static readonly B2CShop.DAL.UserRepository dal = new  B2CShop.DAL.UserRepository();
            // Private members
            private const string ERR_INVALID_PARAMETER = "Invalid Profile parameter:";
    
            private const string PROFILE_USER = "User";
            private static string applicationName = B2CShop.Model.Configuration.ApplicationConfiguration.MembershipApplicationName;
    
            /// <summary>
            /// The name of the application using the custom profile provider.
            /// </summary>
            public override string ApplicationName
            {
                get
                {
                    return applicationName;
                }
                set
                {
                    applicationName = value;
                }
            }
    
    
            /// <summary>
            /// Initializes the provider.
            /// </summary>
            /// <param name="name">The friendly name of the provider.</param>
            /// <param name="config">A collection of the name/value pairs representing the provider-specific attributes specified in the configuration for this provider.</param>
            public override void Initialize(string name, NameValueCollection config)
            {
                if (config == null)
                    throw new ArgumentNullException("config");
    
                if (string.IsNullOrEmpty(config["description"]))
                {
                    config.Remove("description");
                    config.Add("description", "B2C Shop  Custom Provider");
                }
    
                if (string.IsNullOrEmpty(name))
                    name = "b2c_shop";
    
                if (config["applicationName"] != null && !string.IsNullOrEmpty(config["applicationName"].Trim()))
                    applicationName = config["applicationName"];
    
                base.Initialize(name, config);
    
            }
    
            /// <summary>
            /// Returns the collection of settings property values for the specified application instance and settings property group.
            /// </summary>
            /// <param name="context">A System.Configuration.SettingsContext describing the current application use.</param>
            /// <param name="collection">A System.Configuration.SettingsPropertyCollection containing the settings property group whose values are to be retrieved.</param>
            /// <returns>A System.Configuration.SettingsPropertyValueCollection containing the values for the specified settings property group.</returns>
            public override SettingsPropertyValueCollection GetPropertyValues(SettingsContext context, SettingsPropertyCollection collection)
            {
    
                string username = (string)context["UserName"];
                bool isAuthenticated = (bool)context["IsAuthenticated"];
                //if (!isAuthenticated) return null;
                int uniqueID = dal.GetUniqueID(username, isAuthenticated, false, ApplicationName);
    
    
    
                SettingsPropertyValueCollection svc = new SettingsPropertyValueCollection();
    
                foreach (SettingsProperty prop in collection)
                {
                    SettingsPropertyValue pv = new SettingsPropertyValue(prop);
    
                    switch (pv.Property.Name)
                    {
                        case PROFILE_USER:
                            if (!String.IsNullOrEmpty(username))
                            {
                                pv.PropertyValue = GetUser(uniqueID);
                            }
                            break;
                        default:
                            throw new ApplicationException(ERR_INVALID_PARAMETER + " name.");
                    }
    
                    svc.Add(pv);
                }
                return svc;
            }
    
    
            /// <summary>
            /// Sets the values of the specified group of property settings.
            /// </summary>
            /// <param name="context">A System.Configuration.SettingsContext describing the current application usage.</param>
            /// <param name="collection">A System.Configuration.SettingsPropertyValueCollection representing the group of property settings to set.</param>
            public override void SetPropertyValues(SettingsContext context, SettingsPropertyValueCollection collection)
            {
    
                string username = (string)context["UserName"];
                CheckUserName(username);
                bool isAuthenticated = (bool)context["IsAuthenticated"];
    
                int uniqueID = dal.GetUniqueID(username, isAuthenticated, false, ApplicationName);
                if (uniqueID == 0)
                {
                    uniqueID = dal.CreateProfileForUser(username, isAuthenticated, ApplicationName);
                }
    
                foreach (SettingsPropertyValue pv in collection)
                {
    
                    if (pv.PropertyValue != null)
                    {
                        switch (pv.Property.Name)
                        {
                            case PROFILE_USER:
                                SetUser(uniqueID, (UserInfo)pv.PropertyValue);
                                break;
                            default:
                                throw new ApplicationException(ERR_INVALID_PARAMETER + " name.");
                        }
                    }
                }
    
                UpdateActivityDates(username, false);
            }
    
    
            // Profile gettters
            // Retrieve UserInfo
            private static UserInfo GetUser(int userID)
            {
                return dal.GetUser(userID);
            }
    
    
    
    
            // Update account info
            private static void SetUser(int uniqueID, UserInfo user)
            {
                user.UserID = uniqueID;
                dal.SetUser(user);
            }
    
    
            // UpdateActivityDates
            // Updates the LastActivityDate and LastUpdatedDate values 
            // when profile properties are accessed by the
            // GetPropertyValues and SetPropertyValues methods. 
            // Passing true as the activityOnly parameter will update
            // only the LastActivityDate.
            private static void UpdateActivityDates(string username, bool activityOnly)
            {
                dal.UpdateActivityDates(username, activityOnly, applicationName);
            }
    
            /// <summary>
            /// Deletes profile properties and information for the supplied list of profiles.
            /// </summary>
            /// <param name="profiles">A System.Web.Profile.ProfileInfoCollection of information about profiles that are to be deleted.</param>
            /// <returns>The number of profiles deleted from the data source.</returns>
            public override int DeleteProfiles(ProfileInfoCollection profiles)
            {
    
                int deleteCount = 0;
    
                foreach (ProfileInfo p in profiles)
                    if (DeleteProfile(p.UserName))
                        deleteCount++;
    
                return deleteCount;
            }
    
            /// <summary>
            /// Deletes profile properties and information for profiles that match the supplied list of user names.
            /// </summary>
            /// <param name="usernames">A string array of user names for profiles to be deleted.</param>
            /// <returns>The number of profiles deleted from the data source.</returns>
            public override int DeleteProfiles(string[] usernames)
            {
    
                int deleteCount = 0;
    
                foreach (string user in usernames)
                    if (DeleteProfile(user))
                        deleteCount++;
    
                return deleteCount;
            }
    
            // DeleteProfile
            // Deletes profile data from the database for the specified user name.
            private static bool DeleteProfile(string username)
            {
                CheckUserName(username);
                return dal.DeleteAnonymousProfile(username, applicationName);   
            }
    
            // Verifies user name for sise and comma
            private static void CheckUserName(string userName)
            {
                if (string.IsNullOrEmpty(userName) || userName.Length > 256 || userName.IndexOf(",") > 0)
                    throw new ApplicationException(ERR_INVALID_PARAMETER + " user name.");
            }
    
            /// <summary>
            /// Deletes all user-profile data for profiles in which the last activity date occurred before the specified date.
            /// </summary>
            /// <param name="authenticationOption">One of the System.Web.Profile.ProfileAuthenticationOption values, specifying whether anonymous, authenticated, or both types of profiles are deleted.</param>
            /// <param name="userInactiveSinceDate">A System.DateTime that identifies which user profiles are considered inactive. If the System.Web.Profile.ProfileInfo.LastActivityDate value of a user profile occurs on or before this date and time, the profile is considered inactive.</param>
            /// <returns>The number of profiles deleted from the data source.</returns>
            public override int DeleteInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate)
            {
    
                string[] userArray = new string[0];
                 dal.GetInactiveProfiles((int)authenticationOption, userInactiveSinceDate, ApplicationName).CopyTo(userArray, 0);
    
                return DeleteProfiles(userArray);
            }
    
            /// <summary>
            /// Retrieves profile information for profiles in which the user name matches the specified user names.
            /// </summary>
            /// <param name="authenticationOption">One of the System.Web.Profile.ProfileAuthenticationOption values, specifying whether anonymous, authenticated, or both types of profiles are returned.</param>
            /// <param name="usernameToMatch">The user name to search for.</param>
            /// <param name="pageIndex">The index of the page of results to return.</param>
            /// <param name="pageSize">The size of the page of results to return.</param>
            /// <param name="totalRecords">When this method returns, contains the total number of profiles.</param>
            /// <returns>A System.Web.Profile.ProfileInfoCollection containing user-profile information
            //     for profiles where the user name matches the supplied usernameToMatch parameter.</returns>
            public override ProfileInfoCollection FindProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
            {
    
                CheckParameters(pageIndex, pageSize);
    
                return GetProfileInfo(authenticationOption, usernameToMatch, null, pageIndex, pageSize, out totalRecords);
            }
    
            /// <summary>
            /// Retrieves profile information for profiles in which the last activity date occurred on or before the specified date and the user name matches the specified user name.
            /// </summary>
            /// <param name="authenticationOption">One of the System.Web.Profile.ProfileAuthenticationOption values, specifying whether anonymous, authenticated, or both types of profiles are returned.</param>
            /// <param name="usernameToMatch">The user name to search for.</param>
            /// <param name="userInactiveSinceDate">A System.DateTime that identifies which user profiles are considered inactive. If the System.Web.Profile.ProfileInfo.LastActivityDate value of a user profile occurs on or before this date and time, the profile is considered inactive.</param>
            /// <param name="pageIndex">The index of the page of results to return.</param>
            /// <param name="pageSize">The size of the page of results to return.</param>
            /// <param name="totalRecords">When this method returns, contains the total number of profiles.</param>
            /// <returns>A System.Web.Profile.ProfileInfoCollection containing user profile information for inactive profiles where the user name matches the supplied usernameToMatch parameter.</returns> 
            public override ProfileInfoCollection FindInactiveProfilesByUserName(ProfileAuthenticationOption authenticationOption, string usernameToMatch, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords)
            {
    
                CheckParameters(pageIndex, pageSize);
    
                return GetProfileInfo(authenticationOption, usernameToMatch, userInactiveSinceDate, pageIndex, pageSize, out totalRecords);
            }
    
            /// <summary>
            /// Retrieves user profile data for all profiles in the data source.
            /// </summary>
            /// <param name="authenticationOption">One of the System.Web.Profile.ProfileAuthenticationOption values, specifying whether anonymous, authenticated, or both types of profiles are returned.</param>
            /// <param name="pageIndex">The index of the page of results to return.</param>
            /// <param name="pageSize">The size of the page of results to return.</param>
            /// <param name="totalRecords">When this method returns, contains the total number of profiles.</param>
            /// <returns>A System.Web.Profile.ProfileInfoCollection containing user-profile information for all profiles in the data source.</returns>      
            public override ProfileInfoCollection GetAllProfiles(ProfileAuthenticationOption authenticationOption, int pageIndex, int pageSize, out int totalRecords)
            {
                CheckParameters(pageIndex, pageSize);
    
                return GetProfileInfo(authenticationOption, null, null, pageIndex, pageSize, out totalRecords);
            }
    
            /// <summary>
            /// Retrieves user-profile data from the data source for profiles in which the last activity date occurred on or before the specified date.
            /// </summary>
            /// <param name="authenticationOption">One of the System.Web.Profile.ProfileAuthenticationOption values, specifying whether anonymous, authenticated, or both types of profiles are returned.</param>
            /// <param name="userInactiveSinceDate">A System.DateTime that identifies which user profiles are considered inactive. If the System.Web.Profile.ProfileInfo.LastActivityDate of a user profile occurs on or before this date and time, the profile is considered inactive.</param>
            /// <param name="pageIndex">The index of the page of results to return.</param>
            /// <param name="pageSize">The size of the page of results to return.</param>
            /// <param name="totalRecords">When this method returns, contains the total number of profiles.</param>
            /// <returns>A System.Web.Profile.ProfileInfoCollection containing user-profile information about the inactive profiles.</returns>
            public override ProfileInfoCollection GetAllInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords)
            {
                CheckParameters(pageIndex, pageSize);
    
                return GetProfileInfo(authenticationOption, null, userInactiveSinceDate, pageIndex, pageSize, out totalRecords);
            }
    
            /// <summary>
            /// Returns the number of profiles in which the last activity date occurred on or before the specified date.
            /// </summary>
            /// <param name="authenticationOption">One of the System.Web.Profile.ProfileAuthenticationOption values, specifying whether anonymous, authenticated, or both types of profiles are returned.</param>
            /// <param name="userInactiveSinceDate">A System.DateTime that identifies which user profiles are considered inactive. If the System.Web.Profile.ProfileInfo.LastActivityDate of a user profile occurs on or before this date and time, the profile is considered inactive.</param>
            /// <returns>The number of profiles in which the last activity date occurred on or before the specified date.</returns>
            public override int GetNumberOfInactiveProfiles(ProfileAuthenticationOption authenticationOption, DateTime userInactiveSinceDate)
            {
    
                int inactiveProfiles = 0;
    
                ProfileInfoCollection profiles = GetProfileInfo(authenticationOption, null, userInactiveSinceDate, 0, 0, out inactiveProfiles);
    
                return inactiveProfiles;
            }
    
            //Verifies input parameters for page size and page index.
            private static void CheckParameters(int pageIndex, int pageSize)
            {
                if (pageIndex < 1 || pageSize < 1)
                    throw new ApplicationException(ERR_INVALID_PARAMETER + " page index.");
            }
    
            //GetProfileInfo
            //Retrieves a count of profiles and creates a 
            //ProfileInfoCollection from the profile data in the 
            //database. Called by GetAllProfiles, GetAllInactiveProfiles,
            //FindProfilesByUserName, FindInactiveProfilesByUserName, 
            //and GetNumberOfInactiveProfiles.
            //Specifying a pageIndex of 0 retrieves a count of the results only.
            private static ProfileInfoCollection GetProfileInfo(ProfileAuthenticationOption authenticationOption, string usernameToMatch, object userInactiveSinceDate, int pageIndex, int pageSize, out int totalRecords)
            {
    
                ProfileInfoCollection profiles = new ProfileInfoCollection();
    
                totalRecords = 0;
    
                // Count profiles only.
                if (pageSize == 0)
                    return profiles;
    
                int counter = 0;
                int startIndex = pageSize * (pageIndex - 1);
                int endIndex = startIndex + pageSize - 1;
    
                DateTime dt = new DateTime(1900, 1, 1);
                if (userInactiveSinceDate != null)
                    dt = (DateTime)userInactiveSinceDate;
    
                /*
                foreach(CustomProfileInfo profile in dal.GetProfileInfo((int)authenticationOption, usernameToMatch, dt, applicationName, out totalRecords)) {
                    if(counter >= startIndex) {
                        ProfileInfo p = new ProfileInfo(profile.UserName, profile.IsAnonymous, profile.LastActivityDate, profile.LastUpdatedDate, 0);
                        profiles.Add(p);
                    }
    
                    if(counter >= endIndex) {
                        break;
                    }
    
                    counter++;
                }
                */
                return profiles;
            }
        }
    }
    

    我在控制器中是这样使用它的:

        public ActionResult AddTyreToCart(CartViewModel model)
        {
    
            string profile = Request.IsAuthenticated ? Request.AnonymousID : User.Identity.Name;
    
        }
    

    编辑

    下面是getuniqueid的代码

    public int GetUniqueID(string userName, bool isAuthenticated, bool ignoreAuthenticationType, string appName)
    {
    
      SqlParameter[] parms = {
                new SqlParameter("@Username", SqlDbType.VarChar, 256),
                new SqlParameter("@ApplicationName", SqlDbType.VarChar, 256)};
      parms[0].Value = userName;
      parms[1].Value = appName;
    
      if (!ignoreAuthenticationType)
      {
        Array.Resize(ref parms, parms.Length + 1);
        parms[2] = new SqlParameter("@IsAnonymous", SqlDbType.Bit) { Value = !isAuthenticated };
      }
    
      int userID;
    
      object retVal = null;
      retVal = SqlHelper.ExecuteScalar(ConfigurationManager.ConnectionStrings["SQLOrderB2CConnString"].ConnectionString, CommandType.StoredProcedure, "getProfileUniqueID", parms);
    
      if (retVal == null)
        userID = CreateProfileForUser(userName, isAuthenticated, appName);
      else
        userID = Convert.ToInt32(retVal);
      return userID;
    }
    

    这是SP:

    CREATE  PROCEDURE [dbo].[getProfileUniqueID]
    
    @Username VarChar( 256),
    @ApplicationName VarChar( 256),
    @IsAnonymous bit = null
    AS
    BEGIN
    
        SET NOCOUNT ON;
    /*
    [getProfileUniqueID]
    
    created 
    08.07.2009  mf
    
    Retrive unique id for current user
    
    */
    SELECT UniqueID FROM dbo.Profiles WHERE Username = @Username 
    AND ApplicationName = @ApplicationName
    AND IsAnonymous = @IsAnonymous or @IsAnonymous = null
    
    END
    
    4 回复  |  直到 14 年前
        1
  •  1
  •   37Stars    14 年前

    我还没有深入研究这个问题,但有一件事确实让我感到震惊。

    在where子句中

    @IsAnonymous = null
    

    @IsAnonymous IS NULL
    

    SELECT UniqueID FROM dbo.Profiles 
    WHERE Username = @Username 
        AND ApplicationName = @ApplicationName
        AND (IsAnonymous = @IsAnonymous OR @IsAnonymous IS NULL)
    

    你知道两个用户谁收到相同的配置文件数据?如果是这样,从那里开始。我会先通过存储过程运行它们。这样做既简单又快捷。

        2
  •  1
  •   EMP    14 年前

    在我们的例子中,这个问题最终变成了一个愚蠢的本地缓存机制。该应用程序将尝试将静态文件(如图像)缓存在ASP.NET饼干也在里面。在重载情况下,用户有时会用另一个用户的cookies加载一个图像,并假设另一个用户的身份。你的情况可能完全不同,但这可能会给你一些线索类型的东西寻找。

        3
  •  0
  •   Phil Rykoff    14 年前

    给定的源代码似乎还可以,但如果没有所有相应的源代码(例如,所有使用的B2类方法),我就无法做出深刻的陈述CShop.DAL.UserRepository用户存储库),甚至可能是数据库方案。

    首先是检查数据库中的数据是否已损坏,也就是说某些用户可能拥有相同的唯一id或相同的用户名/应用程序/isAnymous组合。如果uniqueid是主键,则可以排除此项。

        4
  •  0
  •   Rahul Soni    14 年前

    1. 隐藏物

    你能试着在没有静态变量的情况下编写这段代码并检查问题是否解决了吗?

    拉胡尔

    推荐文章