Подтвердить что ты не робот

Странный 64/32-разрядный идентификатор GUID в IIS7

Одна из моих команд недавно встретила интересный глюк в матрице. Если кто-нибудь сможет объяснить это, это будет здорово. Возможно, это сложно объяснить, так что несите меня.

Мы создаем приложение ASP.Net. В нем мы имеем простую инструкцию "if".

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

(где mRoles - это список и содержит "Admin" )

Это работает так, как ожидалось (например, adminID назначается mUserId). Однако при переписывании использовать тернарный оператор ниже этого нет! (adminID назначается Guid Empty)!

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

Разработчик, который обнаружил это, находится на 64-битной машине (IIS7/64-разрядная перспектива), и если он изменит свои настройки в IIS следующим образом... В разделе "Пул приложений по умолчанию" > "Дополнительные настройки" установите флажок "Включить 32-разрядные приложения". Теперь оба утверждения работают!

Мы считаем, что это возможно сделать с тем, что Guid является структурой, а не классом, и что значение каким-то образом смещается под 64-разрядный процесс.

Я подозреваю, что проблема подобна этой... http://www.mail-archive.com/[email protected]/msg00164.html Это может объяснить, почему работает первый простой оператор if. (поскольку создание переменной adminId возможно создание указателя, а тернарный оператор - нет?)

Если кто-нибудь может пролить свет на это, это будет здорово. Это ошибка совместимости? или наше непонимание объединения трехмерных операторов и структур?

Спасибо.

UPDATE

Объедините простое приложение и не сможете воспроизвести его в совершенно новом проекте, поэтому оно должно быть чем-то иным, чем GUID.

//Работает (назначает mUserId для adminId)

Guid adminId = true ? mUserId : Guid.Empty;

//Не работает (даже если t == true!!!!???)

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

Думаю, мы вернемся к чертежной доске. Спасибо всем за вашу помощь, и если мы получим еще больше, я отправлю обратно сюда снова.

Единственное, что, возможно, было не слишком ясным, это то, что mRoles не является строкой Generic List of Type. Это строка [], а метод Contains() - метод расширения LINQs, если это имеет какое-то значение, но не может понять, почему: -?

ОБНОВЛЕНИЕ 2

Мы посмотрели на IL, и это правильно (и теперь работает с перерывами!). Мы обнаружили, что, когда пул приложений по умолчанию загружает больше приложений, он снова начинает сбой. Единственное, о чем мы можем думать, это то, что некоторые из этих других приложений могут содержать какой-то неуправляемый код, который каким-то образом мешает нашему приложению, возможно ли это?

4b9b3361

Ответ 1

Кажется, это ошибка в IIS и кусок неуправляемого кода в другом запуске приложения в том же пуле приложений. На данный момент мы работаем над этим, и подпишем его с помощью Microsoft через наше партнерство. Когда он будет решен, я отправлю сюда, чтобы вы знали.

Спасибо всем за вашу помощь.

Ответ 2

Пожалуйста, попробуйте скобки вокруг вашего тернарного оператора, если вы этого еще не сделали.

У нас была аналогичная проблема, в которой код вроде вашего:

Guid adminId = t ? mUserId : Guid.Empty;

был скомпилирован в неправильном порядке:

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

Добавление скобок для указания исправления:

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

Я понял, что он делает, глядя на скомпилированный код с .NET Reflector.

Ответ 3

Может быть, это поможет конкретно сказать оператору присваивания, что возвращение от тернарного оператора Guid?

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

Просто дикая догадка...

Ответ 4

просто интересно, какой тип 64-битной машины считает mUserId? Предположительно, не руководство.

Ответ 5

Я не уверен, но я думаю, что при использовании теневой операции оба исполнения должны выполняться, но с GUID это может привести к тому, что два GUID будут оцениваться как.

Ответ 6

Вы пробовали следующее:

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

Любопытно, если по какой-либо причине mUserId внутренне распознан как другой тип в 64-битной операционной системе, и если бы явное литье помогло бы. Возможно также следующее:

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