2009-08-27 8 views
11

Uno de los miembros de mi equipo se ha encontrado recientemente con un problema técnico interesante en la matriz. Si alguien puede ayudar a explicar esto, sería genial. Es posiblemente complicado de explicar, así que tengan paciencia conmigo.Extraño problema de GUID de 64/32 bits bajo IIS7

Estamos construyendo una aplicación ASP.Net. En él tenemos una declaración simple "si".

Guid adminId = Guid.Empty; 
if (mRoles.Contains("Admin")) 
{ 
    adminId = mUserId; 
} 

(donde mRoles es una lista y contiene “admin”)

Esto funciona como se espera (es decir adminid se le asigna el mUserId). Sin embargo, cuando se reescribe para usar un operador ternario debajo ¡no es así! (¡adminID tiene asignada la Guid Empty)!

Guid adminId = mRoles.Contains("Admin") ? mUserId : Guid.Empty; 

El desarrollador que descubrió esto es en una máquina de 64 bits (IIS 7 Vista/64 bits) y si cambia la configuración de IIS de la siguiente manera ... En "grupo de aplicaciones predeterminado"> "Avanzado Configuración "check" Habilita aplicaciones de 32 bits ". ¡Ahora ambas declaraciones funcionan!

Creemos que esto es algo que hacer posiblemente con el hecho de que un Guid es una estructura en lugar de una clase y que el valor de alguna manera se compensa con un proceso de 64 bits.

Sospecho que el problema es similar a esto ... http://www.mail-archive.com/[email protected]/msg00164.html Lo que puede explicar por qué funciona la primera instrucción if simple. (como la creación de la variable adminId es tal vez la creación de un puntero y el operador ternario no es?)

Si alguien pudiera arrojar alguna luz sobre esto, sería genial. ¿Es un error de compatibilidad? ¿o nuestra incomprensión de la combinación de operadores y estructuras ternarios?

Gracias.

ACTUALIZACIÓN

armar una aplicación sencilla y no pueden reproducirse en un proyecto completamente nuevo, así que debe haber algo más que los GUID.

// Obras (mUserId asigna a adminid)

Guid adminId = true ? mUserId : Guid.Empty; 

// No funciona (aunque t == true !!!! ???)

bool t = (mRoles.Contains("TenantAdmin"); 
Guid adminId = t ? mUserId : Guid.Empty; 

Creo que estamos Volveré al tablero de dibujo en esto. Gracias a todos por su ayuda y, si conseguimos más, volveré a publicar aquí.

Lo único que tal vez no era demasiado claro es que mRoles no es una cadena genérica de tipo de cadena. Es una cadena [] y el método Contiene() es el método de extensión de LINQ si hace alguna diferencia, pero no puede ver por qué: -?

ACTUALIZACIÓN 2

Hemos visto la IL y es correcto (y ahora funciona de manera intermitente!) Lo que hemos encontrado es que cuando el incumplimiento de la aplicación de la piscina cargas más aplicaciones que empieza a fallar de nuevo . La única otra cosa que podemos pensar es que algunas de estas otras aplicaciones pueden contener algún código no administrado que de alguna manera interfiere con nuestra aplicación, ¿podría ser posible?

+2

¿Puede reproducir el comportamiento en unas pocas líneas simples en un proyecto completamente nuevo? –

+0

+1. Muy distrubing – AnthonyWJones

+1

Compara el IL que se produce cuando las diferentes configuraciones están en vigor durante la compilación. – AakashM

Respuesta

0

Esto parece ser un error en IIS y un trozo de código no administrado en otra aplicación runnning en la misma piscina applcation. Hemos trabajado en esto por el momento y lo plantearemos a través de nuestra asociación. Cuando se resuelva, volveré a publicar aquí para informarte.

Gracias a todos por toda su ayuda.

0

Tal vez ayude específicamente decirle al operador de asignación que el retorno del operador ternario es Guid?

Guid adminId = (Guid)(mRoles.Contains("Admin") ? mUserId : Guid.Empty); 

Sólo una conjetura salvaje ...

+0

No. sigue sin funcionar. – ChrisV

+0

Conjetura similar, ¿podría ser este el orden de evaluación? Intenta poner paréntesis alrededor de la declaración ternaria para asegurarte de que no estás analizando la asignación como el condicional. – mpez0

0

preguntando qué tipo es la máquina de 64 bits piensa mUserId es? Presumiblemente no es un Guid.

+0

Definitivamente un System.Guid :-( – ChrisV

+0

Obtendría un error de compilación acerca de no poder determinar el tipo de devolución si mUserId no fuera un guid. – Mark

0

No estoy seguro, pero Creo que cuando se usa una operación tenary, ambas ramas deben ejecutarse; sin embargo, con GUID, esto puede causar que se evalúen dos GUID de alguna forma.

1

Por favor intente paréntesis alrededor de su operador ternario, si aún no lo ha hecho.

Hemos tenido un problema similar en el que un código como el suyo:

Guid adminId = t ? mUserId : Guid.Empty; 

fue compilado en el orden equivocado:

(Guid adminId = t) ? mUserId : Guid.Empty; 

Adición paréntesis para especificar el orden fijo que:

Guid adminId = (t ? mUserId : Guid.Empty); 

Me di cuenta de lo que estaba haciendo al mirar el código compilado con .NET Reflector.

0

Ha intentado lo siguiente:

Guid adminId = mRoles.Contains("Admin") ? (Guid)mUserId : Guid.Empty; 

curiosidad si, por cualquier razón, mUserId es reconocido mundialmente como un tipo diferente bajo un sistema operativo de 64 bits, y si la fundición de forma explícita ayudaría. Lo siguiente también puede ser una opción:

Guid adminId = mRoles.Contains("Admin") ? new Guid(mUserId.ToByteArray()) : Guid.Empty; 
Cuestiones relacionadas