Всё началось с того, что на один из тестовых серверов поставили 64-х битную ОС. Особых проблем это не вызвало, за исключением того, что обна из сборок использует COM -объекты и появилась необходимость её сборки для платформы x86. Вот сдесь уже начали появляться первые подводные камни.

Первым делом я в свойствах проекта поменял свойство Platform Target (посже оказалось что это нужно сделать для всех проектов в solution):

 

 
Но после этих изменений ошибка "Can not load assembly ..." не пропала.  Следующим шагом пошел смотреть свойства solution и...
 
 
... и, с удивлением, обнаружил, что в качестве Target Platform для всех проектов стоит "Any CPU", вместо необходимого "x86". Пришлось идти в Configuration Manager и создавать ноую платформу для текущего solution.
 
 
Но и после всех этих танцев с бубном сайт не заработал. Тут я решил заглянуть в настройки IIS, попутно вспониная создателей Microsoft, .NET и их родственников: и это вы называете кроссплатформенной средой? Здесь меня тоже ждал сюрприз в качестве одного из параметров Application Pool'а, а именно - Enable 32-Bitt Applications, который, по умолчанию, чтоб его конечно же равен False.
 
 
Хорошо что хоть это помогло, иначе я уже был готов перустанавливать Windows и/или избавляться от старой библиотеки, которая использует COM(в нашем случае можно обойтись без этого).
 
P.S. Немного оффтопа. Стало интересно, как это всё сможет работать на x64 системах, который вовсю сейчас продвигаются Microsoft. Ещё интересно где обещанная мультиплатформенность .NET? IMHO, считаю что её нет она находится в зачаточном состоянии, т.к. всё ещё можно скомнилить сборку толоько под x86 или x64. Понимаю, что это делалось только для "нормального" запуска exe-файлов, но зачем же это было делать такой ценой?

PlatrormTestWeb.zip (10.01 kb)


Всё началось с того, что в спецификации к проекту написали примерно такое: "Время продолжительности сэссии пользователя на сайте должно составлять 120 минут". После чего, в web.config была добавлена следующая строка: 

<sessionState mode="InProc" cookieless="false" timeout="120" />

А на страницу был добавлен такой мета-тег:

<meta http-equiv="Refresh" content="7200; URL=/EzRc/Pages/LogOn/SessionExpired.aspx" />

Следует упомянуть конфигурацию тестовых серверов: Windows Vista/2008, IIS7, .NET 3.5. Ничто не предвещало беды. Но, как и полагается, в один "прекрасный" день всеми людимые QA написали баг следующего содержания: "Session expiration occurs prior to 30 min (and as little as 10 min)." При этом повторить его было достаточно просто:

  • залогиниться на сайт
  • оставить браузер в покое на 30 минут

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

Ещё раз убедившись в правильности настроек сэссии в web.config я реши воспроизвести этот баг на локальном (dev) компьютере. Как ни странно, но баг воспроизводился в 100% случаев. "Странно" - подумал я и налил ещё чашку кофе.

Запустив Fiddler2 и залогинившись на сайт я снова оставил его в покое на 30 минут. Через это время, убедившись, что cookie приходят валидные, я наал смотреть логи. Напервый взгляд всё было хорошо, но присмотревшись внимательно, увидел что отрабатывает событие ApplicationStart. Теперь понятно почему заканчивается сэссия. Осталось разобраться почему перезапускается приложение.

Из логов IIS:

Event code: 1002
Event message: Application is shutting down. Reason: Hosting environment is shutting down.
Event time: 6/8/2009 1:50:21 PM
Event time (UTC): 6/8/2009 10:50:21 AM
Event ID: 80d0faffb34547fea6299cfff8cf1c6f
Event sequence: 4
Event occurrence: 1
Event detail code: 50002
 
Application information:
    Application domain: /LM/W3SVC/1/ROOT/Web-1-128889305624881519
    Trust level: Full
    Application Virtual Path: /EzRc
    Application Path: C:\Src\Sites\Web\
    Machine name: localdev
 
Process information:
    Process ID: 6364
    Process name: w3wp.exe
    Account name: NT AUTHORITY\NETWORK SERVICE

 

 

После прочтения статьи из MSDN ASP.NET Application Life Cycle Overview ответ на интересующий вопрос не был получен, из чего был сделан вывод, что проблема находится уровне выше, а именно в IIS. Начал детально изучать настройки, которые могут повлиять на работу приложения и остановился на Application Pools. После чтения документации и нескольких неверных попыток был найден источник проблемы. Им оказался параметр Idle Time-out.

 



Оказалось, что при настройках по умолчанию, процесс, отвечающий за работу asp.net, тушится при условии, что к нему не обращаются в течении 20 минут. Это объясняло, почему проблему можно было не всегда воспроизвести на тестовом сервере.

Это же можно настроить и через файл machine.config. Подробнее описано здесь.


Уже немала было написано на эту тему, но в статье http://haacked.com/archive/2008/11/26/asp.net-mvc-on-iis-6-walkthrough.aspx пошли немного дальше: теперь url rewriting настроен таким образом, что нет необходимости в имени контроллера в пути прописывать расширение. Не буду утверждать что это что-то новое, но я до этого использовал пути вроде http://localhost/mvcsite/home.mvc.


e0ne's comments

A Web Developer's Blog!