Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Strange 64/32-bit GUID issue under IIS7

One of my team has recently come across an interesting glitch in the matrix. If anyone can help explain this it'd be great. It is possibly a complicated to explain, so bear with me.

We are building an ASP.Net application. In it we have a simple "if" statement.

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

(where mRoles is a List and contains “Admin”)

This works just as expected (i.e adminID is assigned the mUserId). However, when rewritten to use a ternary operator below it doesn't! (adminID is assigned Guid Empty)!

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

The developer that discovered this is on a 64-bit machine (IIS7/64-bit vista) and if he changes his settings in IIS as follows... Under "Default Application Pool" > "Advanced Settings" check "Enable 32-bit applications." Now both statements work!

We think that this is something to do possibly with the fact that a Guid is a struct rather than a class and that the value is somehow being offset under a 64-bit process.

I suspect the problem is similar to this... http://www.mail-archive.com/[email protected]/msg00164.html Which may explain why the first simple if statement works. (as creating the adminId variable is maybe creating a pointer and the ternary operator is not?)

If anyone could shed any light on this that’d be great. Is it a compatibility bug? or our misunderstanding of combining ternary operators and structs?

Thanks.

UPDATE

Put together a simple application and cannot reproduce it on a completely new project, so must be something else than the GUIDs.

// Works (assigns mUserId to adminId)

Guid adminId = true ? mUserId : Guid.Empty;

// Not working (even though t == true !!!!???)

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

I think we'll be going back to the drawing board on this. Thanks everyone for your help and if we get any further I'll post back here again.

The only thing that maybe wasn't too clear was that mRoles is not a Generic List of Type string. It's a string[] and the Contains() method is LINQs extension method if that makes any difference, but can't see why :-?

UPDATE 2

We've looked at the IL and it is correct (and now works intermittently!) What we've found is that when the Default App pool loads more applications it starts to fail again. The only other thing we can think of is that some of these other applications may contain some unmanaged code which is somehow interfering with our application, could this be possible?

like image 955
ChrisV Avatar asked Aug 27 '09 09:08

ChrisV


1 Answers

Please try parenthesis around your ternary operator, if you haven't done so already.

We had a similar problem in which code like yours:

Guid adminId = t ? mUserId : Guid.Empty;

was compiled in the wrong order:

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

Adding parenthesis to specify the order fixed it:

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

I figured out what it was doing by looking at the compiled code with .NET Reflector.

like image 67
Paul Williams Avatar answered Oct 13 '22 00:10

Paul Williams