Проблема была в том, что у нас были отдельные папки в App_Code
для разных языков кода. Вот почему в сообщении об ошибке говорится «App_SubCode_CS ...» вместо «App_Code ...», потому что определенный класс пришел из папки с кодом CS (для кода c #). Каждая из этих папок кода (определенная в web.config) компилируется в свою собственную сборку.
Обычно, когда у вас нет нескольких папок кода AppCode, ASP.NET может сериализовать и десериализовать объекты, скомпилированные в разное время или на разных серверах, поскольку имя сборки ("AppCode.randomstring") хранится вместе с именем класса. в сериализованном выводе. При десериализации инфраструктура вызывает System.Type.GetType()
для имени сборки + класса, и эта функция имеет специальный регистр для обработки имен сборок, начинающихся с App_Code
, где, если она не находит сборку, названную точно так же, но она делает найдите тот, который начинается с App_Code, он использует эту сборку для загрузки класса.
Если у вас есть языковые папки в App_Code
, сгенерированные сборки имеют имена, подобные: App_SubCode_FOLDERNAME.randomstring
, и среда, похоже, не справляется с этим случаем. Таким образом, если у вас есть 2 веб-сервера, совместно использующих сеанс с поддержкой Sql, класс Foo компилируется как "App_SubCode_FN.random1, Foo"
на сервере A и "App_SubCode_FN.random2, Foo"
на сервере B. Если пользователь получает Foo в своем сеансе от сервера A, а затем свой следующий запрос переходит на сервер B, сервер B не сможет десериализовать Foo, потому что не может найти сборку с именем "App_SubCode_FN.random1"
.
Эту проблему можно решить, избавившись от старого кода VB (позволяя скомпилировать код приложения в единую сборку, с которой лучше всего работает .NET), или написав пользовательский SerializationBinder + пользовательскую реализацию Sql Server. поддерживаемая сессия.