2010-10-15 15 views
5

Tengo dos sitios en ejecución que comparten un proveedor de membresía. Uno de ellos es un sitio ASP Playground y el otro es un sitio que tiene instalado el Paquete de Integración del Sitio ASP Playground. Vamos a llamarlos sitio ASPPG y sitio SIP.Excepción en Membership.GetAllUsers() después de iniciar sesión: "El elemento ya se ha agregado"

A veces recibo un error cuando ejecuto Membership.GetAllUsers() en el sitio SIP. Este método es invalidado por el SIP, por lo que no es la versión estándar de ASP.NET.

A veces ocurre solo. Me di cuenta de que solo ocurre cuando hay algún tipo de cambio en uno de los miembros. Luego debe volver a crear la tabla hash en la que están almacenados todos los usuarios al llamar a Membership.GetAllUsers() y es como si la recreación no funcionara de alguna manera.

En la excepción que he pegado a continuación, "administratoren" es el nombre de usuario del inicio de sesión que ha tenido alguna información modificada.

No ayuda a forzar la descarga del sitio web actualizando el archivo web.config. No ayuda reiniciar el IIS o reiniciar completamente el servidor. Después de que aparezca la excepción, sigue apareciendo cada vez que se llama Membership.GetAllUsers(). De repente, de la nada, la excepción desaparece y de nuevo es posible iniciar sesión y ejecutar Membership.GetAllUsers() sin excepciones. Parece que el error está en la base de datos y una forma de corregir el error es cargar cualquier página del sitio ASPPG. Luego, el error se soluciona en el sitio SIP.

¿Qué causa la excepción y cómo la detengo?

La excepción completa es la siguiente:

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

Contenido de MemberInfo.cs está aquí:

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 ""; 
      } 
     } 

    } 

} 

Gracias de antemano :)

Editar: Se ha añadido nueva fuente de MemberInfo.cs y actualicé el mensaje de error que recibo. Observe que el trazado de pila sigue siendo el anterior, por lo que los números de línea a los que se refiere pueden estar un poco desajustados.

Editar: Mucha información sobre el error ha sido modificada. Nuevo MemberInfo.cs agregado. Se eliminó el código del método de inicio de sesión porque ahora sé que esta no es la causa del error.

+0

¿Puede ser cierto que nadie sabe nada al respecto? :( – EmKay

Respuesta

1

Resulta que el sitio almacena algunos datos de sesión en una tabla.
En algunos casos, esta tabla se caducará y el sitio se bloqueará.
He agregado un código de limpieza para limpiar la tabla si va a ocurrir un error.

Gracias a todos los que intentaron ayudarme :)

0

He leído su problema. No tengo mucha experiencia de trabajar en una aplicación de sitio web. Una cosa es que "Tabla Hash" puede contener solo valores únicos. cuando intenta ingresar la misma clave y si ya está allí en la tabla hash, le dará un error.

Por lo tanto, le sugiero que utilice su método de autenticación. cuando estamos usando la funcionalidad provista por Microsoft, no podemos tener control sobre ellos. así que mejor use su propia Autenticación y contrólelos.

+0

Exactamente ... No podría estar más de acuerdo con usted. Normalmente no utilizo los métodos de Autenticación integrados, pero desafortunadamente esto no es posible en este caso, ya que es un proyecto que me fue transferido después de que alguien más comenzó. :(El sitio web es bastante grande ahora, por lo que cambiar el procedimiento de inicio de sesión completo y la autenticación no es una opción. Solo quiero corregir el error en la implementación del método integrado. No puedo imaginar que el error está en el método incorporado ... – EmKay

+0

sí ... no estoy diciendo que haya un error en el método incorporado. Estoy diciendo que no podemos tener un buen control de esos métodos. Y entiendo tu situación Desafortunadamente no puedo ayudar ya que no tengo conocimiento de eso. –

0

Esto no está causado por el código de inicio de sesión. Parece que es un error en el archivo MemberInfo.cs. Este código se llama desde el control de usuario GetMemberTopList. Si publica ese código, podremos ayudarlo más, pero le sugiero que adjunte un depurador y mire la pila cuando se lanza la excepción.

+0

Se ha agregado el contenido de MemberInfo.cs .. – EmKay

+0

Voy a intentar con el depurador la próxima vez que se presente .. Simplemente no es el camino este proyecto está configurado :( – EmKay

+0

última vez Pensé que pasar el parámetro a la función lo obliga a agregar un administrador en el sistema. Ahora sin eso, obtienes el mismo error. Una suposición pesimista: Tal vez la biblioteca sea reemplazada por un pirata informático que está tratando de agregar un administrador predeterminado al sistema. Pero todavía creo que esta es una condición de carrera. Recuerde que el objeto interno (HashTable) es estático y debe colocar el candado sobre él, no su código. – Xaqron

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

Parece que tiene los nombres de usuario duplicados en allUsers (var = allUsers ...) pero la variable acaba de definir lo que no hay posibilidad de poner otra 'Administratoren' en ella y obtener la excepción a la misma línea a menos que algo esté sucediendo en la misma línea. Dado que la pertenencia no permite duplicados de las llaves (nombres de usuario), el problema es con colada que está sucediendo después de retreiving usuarios al final de su única línea de código:

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

cambio a:

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

También usar var o escribir muchas declaraciones en una sola línea de código no son buenas ideas.

+0

Usar var es una idea perfectamente buena. –

+0

Acabo de descubrir que solo si intento iniciar sesión en una página específica, se produce el error. Trataré de investigarlo y también separar el código un poco más en lugar de hacer mucho en una línea, como usted señala.Espero que llegue a algún lado con esto ...: S – EmKay

+0

Además, el código en realidad es como sugieres que debería ser (con MembershipUser después del Cast. Acaba de desaparecer cuando lo pegué aquí: S – EmKay

0

Puede ser que deba anular la igualdad y la operación de hash para su entidad. Por ejemplo, por Id.

0

@EDIT:

Retire static de la siguiente línea, o llame a la función sin bIncludeAdministrators:

Line 108: public static List GetAllMembers(Boolean bIncludeAdministrators) 

Motivo: Cada solicitud en ASP.NET se sirve de un hilo diferente de ASP Grupo de subprocesos .NET, si dos subprocesos alcanzan esta línea simultáneamente, se llama al GetAllMembers() desde dos subprocesos diferentes al mismo tiempo. Parece que este método no está implementado seguro para subprocesos y no proporciona un bloqueo sobre HashTable mientras agrega elementos a él. Luego, el último subproceso intentaría agregar la misma clave al HashTable.

+0

He intentado su solución. No funcionó :(También miré un poco sobre el tema de la seguridad de los hilos y puse un candado. Tampoco funcionó. La fuente actualizada con ambas correcciones se agregó anteriormente. – EmKay

Cuestiones relacionadas