IIS7下奇怪的64/32位GUID问题

发布于 2024-08-03 00:40:22 字数 1717 浏览 2 评论 0原文

我的一个团队最近在矩阵中发现了一个有趣的故障。如果有人可以帮助解释这一点那就太好了。解释起来可能很复杂,所以请耐心等待。

我们正在构建一个 ASP.Net 应用程序。其中我们有一个简单的“if”语句。

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

(其中 mRoles 是一个列表并包含“Admin”)

这将按预期工作(即 adminID 被分配给 mUserId)。然而,当重写为使用下面的三元运算符时,它就不会了! (adminID分配的Guid为空)!

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

发现此问题的开发人员使用的是 64 位计算机(IIS7/64 位 vista),如果他按如下方式更改 IIS 中的设置... 在“默认应用程序池”>下“高级设置”勾选“启用32位应用程序”。现在这两种说法都有效!

我们认为这可能与 Guid 是一个结构而不是一个类以及该值在 64 位进程下以某种方式偏移有关。

我怀疑这个问题与此类似...... http://www.mail-archive.com/ [电子邮件受保护]/msg00164.html 这可以解释为什么第一个简单的 if 语句有效。 (因为创建 adminId 变量可能是创建一个指针,而三元运算符不是?)

如果有人能对此有所了解,那就太好了。 是兼容性bug吗?还是我们对三元运算符和结构体组合的误解?

谢谢。

更新

将一个简单的应用程序放在一起,无法在全新的项目上重现它,因此必须是 GUID 之外的其他内容。

// 有效(将 mUserId 分配给 adminId)

Guid adminId = true ? mUserId : Guid.Empty;

// 无效(即使 t == true !!!!!!???)

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

我想我们将回到绘图板上。感谢大家的帮助,如果我们有任何进展,我会再次发帖回到这里。

唯一可能不太清楚的是 mRoles 不是类型字符串的通用列表。它是一个 string[],Contains() 方法是 LINQ 扩展方法(如果这有什么区别的话),但不明白为什么:-?

更新 2

我们查看了 IL,它是正确的(现在可以间歇性地工作!)我们发现,当默认应用程序池加载更多应用程序时,它会再次失败。我们唯一能想到的另一件事是,其中一些其他应用程序可能包含一些非托管代码,这些代码以某种方式干扰我们的应用程序,这可能吗?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

行雁书 2024-08-10 00:40:22

如果您还没有这样做,请尝试在三元运算符周围添加括号。

我们遇到了类似的问题,其中像您这样的代码

Guid adminId = t ? mUserId : Guid.Empty;

以错误的顺序编译:

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

添加括号来指定顺序修复了它:

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

我通过使用 .NET Reflector 查看编译后的代码来弄清楚它在做什么。

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.

腻橙味 2024-08-10 00:40:22

也许专门告诉赋值运算符三元运算符的返回值是 Guid 会有所帮助?

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

只是一个疯狂的猜测...

Maybe it will help to specifically tell the assignment operator that the return from the ternary operator is Guid?

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

Just a wild guess...

七月上 2024-08-10 00:40:22

只是想知道64位机器认为mUserId是什么类型?大概不是指南。

just wondering what type the 64bit machine thinks mUserId is? Presumably not a Guid.

淤浪 2024-08-10 00:40:22

我不确定,但是我认为在使用tenary操作时,两个括号都必须被执行,但是使用GUID,这可能会导致两个GUID以某种方式被评估。

I'm not sure, but I think when using a tenary operation, both brances have to be executed, however with GUID, this may cause two GUIDs to be evaluated some how.

掌心的温暖 2024-08-10 00:40:22

您是否尝试过以下操作:

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

只是好奇,无论出于何种原因,mUserId 在 64 位操作系统下是否被内部识别为不同的类型,以及显式转换是否会有所帮助。以下也可能是一种选择:

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

Have you tried the following:

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

Just curious if, for whatever reason, mUserId is internally recognized as a different type under a 64bit operating system, and if explicitly casting would help. The following might also be an option:

Guid adminId = mRoles.Contains("Admin") ? new Guid(mUserId.ToByteArray()) : Guid.Empty;
猫腻 2024-08-10 00:40:22

这似乎是 IIS 中的错误,也是同一应用程序池中运行的另一个应用程序中的一大块非托管代码。我们目前已经解决了这个问题,并将通过我们的合作伙伴关系向 Microsoft 提出这个问题。当问题得到解决后,我会发回此处通知您。

感谢大家的帮助。

This appears to be a bug in IIS and a chunk of unmanaged code in another application runnning in the same applcation pool. We have worked around it for now and will raise it with Microsoft via our partnership. When it gets resolved I'll post back here to let you know.

Thanks everyone for all your help.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文