Exception on Membership.GetAllUsers () after login: & ldquo; Item has already been added & rdquo;

advertisements

I have two sites running which share a membership provider. One of them is a ASP Playground site and the other is a site that have the ASP Playground Site Integration Package installed. Let's call them ASPPG site and SIP site.

I sometimes get an error when I run Membership.GetAllUsers() on the SIP site. This method is overruled by the SIP, so it is not the standard ASP.NET version.

It only occurs sometimes. I have noticed that it only occurs when there is some sort of change to one of the members. Then it must recreate the hashtable that all the users are stored in when calling Membership.GetAllUsers() and it is like this recreation goes wrong somehow.

In the exception that I have pasted below "administratoren" is the username of the login that has had some info changed.

It does not help to force the website to unload by updating the web.config. It does not help to restart the IIS or completely reboot the server. After the exception shows up, it keeps on showing up everytime Membership.GetAllUsers() is called. Suddenly, out of the blue, the exception disappears and it is again possible to log in and run Membership.GetAllUsers() without any exceptions. It pretty much looks like the error is in the database and a way to fix the error is by loading any page of the ASPPG site. Then the error gets fixed on the SIP site.

What causes the exception and how do I stop it?

The complete exception is this:

Server Error in '/' Application.
Item has already been added. Key in dictionary: 'administratoren' Key being added: 'administratoren' Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

Exception Details: System.ArgumentException: Item has already been added. Key in dictionary: 'administratoren' Key being added: 'administratoren'

Source Error:

Linje 116: MembershipUserCollection allUsers;
Linje 117: lock (objLock) {
Linje 118: allUsers = Membership.GetAllUsers();
Linje 119: }
Linje 120:

Source File: [WebsiteLocation]\App_Code\MemberInfo.cs Line: 118

Stack Trace: (Please not that the line numbers of MemberInfo.cs in this stacktrace can be a bit off.

[ArgumentException: Item has already been added. Key in dictionary: 'administratoren' Key being added: 'administratoren']
System.Collections.Hashtable.Insert(Object key, Object nvalue, Boolean add) +7484392
System.Collections.Hashtable.Add(Object key, Object value) +11
System.Web.Security.MembershipUserCollection.Add(MembershipUser user) +129
ASPPG.MembershipProviders.ASPPGSqlMembershipProvider.CreateMembershipUserCollectionFromDataView(DataView dv) in H:\My Document\Visual Studio 2008\Projects\forumu\MembershipProviders\ASPPGSqlMembershipProvider.vb:656 ASPPG.MembershipProviders.ASPPGSqlMembershipProvider.GetAllUsers(Int32 pageIndex, Int32 pageSize, Int32& totalRecords) in H:\My Document\Visual Studio 2008\Projects\forumu\MembershipProviders\ASPPGSqlMembershipProvider.vb:360 System.Web.Security.Membership.GetAllUsers(Int32 pageIndex, Int32 pageSize, Int32& totalRecords) +65 System.Web.Security.Membership.GetAllUsers() +26 MemberInfo.GetAllMembers() in d:\Faelles\SVN-exports\DFF-umbraco\App_Code\MemberInfo.cs:71 usercontrols_GetMemberTopList.LoadTopMembers() in d:\Faelles\SVN-exports\DFF-umbraco\usercontrols\GetMemberTopList.ascx.cs:16 usercontrols_GetMemberTopList.Page_Load(Object sender, EventArgs e) in d:\Faelles\SVN-exports\DFF-umbraco\usercontrols\GetMemberTopList.ascx.cs:11 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +35 System.Web.UI.Control.OnLoad(EventArgs e) +99 System.Web.UI.Control.LoadRecursive() +50 System.Web.UI.Control.LoadRecursive() +141 System.Web.UI.Control.LoadRecursive() +141 System.Web.UI.Control.LoadRecursive() +141 System.Web.UI.Control.LoadRecursive() +141 System.Web.UI.Control.LoadRecursive() +141 System.Web.UI.Control.LoadRecursive() +141 System.Web.UI.Control.LoadRecursive() +141 System.Web.UI.Control.LoadRecursive() +141 System.Web.UI.Control.LoadRecursive() +141 System.Web.UI.Control.LoadRecursive() +141 System.Web.UI.Control.LoadRecursive() +141 System.Web.UI.Control.LoadRecursive() +141 System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +627

Version Information: Microsoft .NET Framework Version:2.0.50727.3603; ASP.NET Version:2.0.50727.3618

Contents of MemberInfo.cs is here:

public class MemberInfo {

    public string Username { get; set; }
    public string FirstName { get; set; }
    public string MiddleName { get; set; }
    public string LastName { get; set; }
    public string Fullname { get; set; }
    public string AddressPrimary { get; set; }
    public string AddressSecondary { get; set; }
    public string Zip { get; set; }
    public string Country { get; set; }
    public string HomepageUrl { get; set; }
    public string Id { get; set; }
    public string MemberNo { get; set; }
    public Boolean IsApproved { get; set; }
    public string Email { get; set; }
    public Boolean IsNotMember { get; set; }
    public Boolean IsUpdated { get; set; }
    public Boolean HasReceivedWelcomeMail { get; set; }
    public int RandomNumber { get; set; }
    public int MemberType { get; set; }

    public MemberInfo() { 

    }

    public MemberInfo(string _username, string _id) {
        Username = _username;

        MembershipUser userRequested = Membership.GetUser(Username);

        ProfileBase profile = ProfileBase.Create(Username);

        IsApproved = userRequested.IsApproved;

        FirstName = profile.GetPropertyValue("Firstname").ToString();
        MiddleName = profile.GetPropertyValue("Middlename").ToString();
        LastName = profile.GetPropertyValue("Lastname").ToString();
        AddressPrimary = profile.GetPropertyValue("AddressPrimary").ToString();
        AddressSecondary = profile.GetPropertyValue("AddressSecondary").ToString();
        Zip = profile.GetPropertyValue("Zip").ToString();
        Country = profile.GetPropertyValue("Country").ToString();
        HomepageUrl = profile.GetPropertyValue("HomepageUrl").ToString();
        HasReceivedWelcomeMail = Boolean.Parse(profile.GetPropertyValue("WelcomeMailSent").ToString());

        if (FirstName.Length > 2) {
            string strFullName = FirstName + " " + MiddleName + " " + LastName;
            Fullname = strFullName.Replace("  ", " ");
        }
        else {
            Fullname = Username;
        }

        MemberNo = profile.GetPropertyValue("MemberNo").ToString();
        IsNotMember = Boolean.Parse(profile.GetPropertyValue("NotMember").ToString());
        Email = userRequested.Email;
        Id = _id;

        if (profile.GetPropertyValue("Description").ToString() != "") {
            IsUpdated = true;
        }
        else {

            if (umbraco.library.GetXmlNodeById("1352").Current.SelectSingleNode("node [@nodeName='" + Username + "']/node") == null) {
                IsUpdated = false;
            }
            else {
                IsUpdated = true;
            }

        }
        RandomNumber = ss.NumberStuff.GenerateRandomNumber(0, 10000000);

        MemberType = 1;

        if (IsApproved == false && HasReceivedWelcomeMail == false) { // Not yet approved
            MemberType = 1;
        }

        if (IsApproved == false && HasReceivedWelcomeMail == true) { // Deleted
            MemberType = 2;
        }

        if (IsApproved == true && IsNotMember == false) { // Members
            MemberType = 3;
        }

        if (IsApproved == true && IsNotMember == true) { // Administrators
            MemberType = 4;
        }

    }

    private static object objLock = new object();

    public List<MemberInfo> GetAllMembers() {
        return GetAllMembers(false);
    }

    public List<MemberInfo> GetAllMembers(Boolean bIncludeAdministrators) {

        MembershipUserCollection allUsers;
        lock (objLock) {
            allUsers = Membership.GetAllUsers();
        }

        List<MemberInfo> memberInfoList = new List<MemberInfo>();

        foreach (MembershipUser userCurrent in allUsers) {
            MemberInfo mInfo = new MemberInfo(userCurrent.UserName, userCurrent.ProviderUserKey.ToString());
            if (mInfo.Id == "0") {
                continue;
            }

            if (mInfo.IsNotMember == true && bIncludeAdministrators == false) {
                continue;
            }

            memberInfoList.Add(mInfo);
        }

        return memberInfoList;

    }

    public static String GetMemberTypeName(int intMemberType) {

        switch (intMemberType) {

            case 1: {
                return "Endnu ikke godkendt";
            }

            case 2: {
                return "Slettet";
            }

            case 3: {
                return "Medlem";
            }

            case 4: {
                return "Administrator";
            }

            default: {
                return "";
            }
        }

    }

}

Thanks in advance :)

Edit: Added new source of MemberInfo.cs and updated what error message I get. Notice that the stack trace is still the old one, so the line numbers it is referring to can be a little off.

Edit: A lot of info about the error has been changed. New MemberInfo.cs added. Removed code from the login method as I now know that this is not the cause of the error.


[ArgumentException: Item has already been added. Key in dictionary: 'administratoren' Key being added: 'administratoren']

It seems you have duplicate usernames in allUsers (var allUsers =...) but you the variable has just defined so there is no chance to put another 'administratoren' in it and get the exception at the same line unless something is happening at the same line. Since membership doesn't allow duplicate KEYs (usernames), the problem is with casting which is happening after retreiving users at the end of your single line of code :

Line 71: var allUsers = from u in Membership.GetAllUsers().Cast() select u;

change to:

Line 71: var allUsers = from u in Membership.GetAllUsers().Cast<MembershipUser>() select u;

Also using var or writing many statements in a single line of code are not good ideas.