Почему .NET внезапно пытается сериализовать мой объект в моем приложении ASP.NET? - PullRequest
3 голосов
/ 27 июня 2011

Я запускаю веб-роль Azure в режиме Full IIS.Запросы авторизуются с помощью пользовательской базовой аутентификации .

. У меня есть MyAssembly.CustomIdentity класс, который наследуется от System.Security.Principal.GenericIdentity.Когда вызывается обработчик HttpApplication.AuthenticateRequest (код OnEnter() по ссылке выше), он выполняет проверки, затем создает экземпляр MyIdentity.CustomIdentity и присваивает его HttpContext.Current.User.Затем фактический обработчик запросов ASP.NET получает этот объект и может использовать его, чтобы найти, для какого пользователя он предназначен.

Теперь все более или менее работает нормально в конфигурации по умолчанию, когда IIS работает под учетной записью NETWORK SERVICE.Во время запуска роли я перезапускаю пул приложений IIS под локальным пользователем (чтобы предоставить ему дополнительные привилегии).Теперь даже следующий код

public partial class Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        bool isAvailable = Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.IsAvailable;
    }
}

будет выдавать различные исключения.Сначала он говорит, что не может сериализовать мой класс CustomIdentity (который я исправляю, добавив атрибут Serializable), затем он говорит, что не может загрузить сборку MyAssembly (которую я исправляю, обрабатывая событие AppDomain.AssemblyResolve).

Чего я не понимаю, так это о том, почему начинается сериализация?Зачем запускать пул приложений под локальным пользователем и вызывать этот тривиальный код, внезапно запускающий сериализацию?

Ответы [ 3 ]

4 голосов
/ 27 июня 2011

РЕДАКТИРОВАТЬ Перечитывая ваш вопрос, я не уверен, что это проблема.Я оставляю это здесь, потому что я потратил 5 минут на его написание, и это полезная информация :) Если вы пишете веб-приложения, вам нужно знать о состоянии сеанса и опциях хранения!


Как говорит Дэниел Пауэлл, весьма вероятно, что вы храните экземпляр вашего объекта в состоянии сеанса.

Приложения ASP.NET имеют 3 стандартных режима для хранения состояния сеанса.InProc (в процессе) сохраняет его в памяти, поэтому сериализация не требуется.StateServer или SqlServer попытается сериализовать состояние сеанса либо на сервер состояний ASP.NET, либо на сервер SQL соответственно.

Чтобы подтвердить, что это проблема, вам нужно проверить, что mode атрибут элемента sessionState находится в файле web.config.

<sessionState mode="InProc|SqlServer|StateServer" />

Если вы используете SQL Server или State Server, то ваше приложение будет сериализовать все состояние сеанса в конце каждогозапрос.У вас есть несколько вариантов здесь:

  1. Измените состояние сеанса на InProc.Это предотвратит сериализацию, но вы не сможете использовать среду с балансировкой нагрузки.Кроме того, если ваше приложение перезапустится, все пользователи потеряют свой сеанс (так как он хранится в памяти).

  2. Прекратите помещать этот объект в сеанс.Если вам не нужно для хранения этого объекта в сеансе, тогда не делайте этого!Проблема решена.

  3. Сделать объект и любые его дочерние элементы сериализуемыми, реализуя ISerializable.Это будет невозможно, если объект использует «живые» элементы, такие как соединения с базой данных и т. Д.

1 голос
/ 27 июня 2011

Будьте осторожны с этим ответом, так как я не совсем уверен, что он хороший.

Во-первых, я предполагаю, что вы не настроили что-то вроде управления сеансом sql, и единственное, что вы изменили, - это пользователь, под которым работает IIS.

Вы наблюдаете два явления:

  1. Сериализация объекта, который не должен быть сериализован
  2. Загрузка вашей сборки доменом приложения, который еще не загрузил ее.

Поскольку ваш домен приложения уже загрузил сборку, кажется безопасным предположить, что исключение выдается другим доменом приложения. Если он генерируется другим доменом приложения, возможно, это связано с тем, что этот домен приложения пытается десериализовать ваш пользовательский объект. (Он был сериализован до того, как это продемонстрирует другое исключение.)

OK. Теперь, даже если IIS работает под локальным пользователем, среда Role - нет. Эта служба устанавливается вместе с ОС Azure, вы не можете выбрать пользователя, под которым она работает (возможно, вы могли бы это сделать, но я бы не стал)

Мне кажется, что для получения информации из RoleEnvironnement среда выполнения Azure может использовать два пути кода:

  1. Один, если служба IIS и среда выполнения работают под одним и тем же пользователем, что не требует переключения домена приложения.
  2. другое, если служба IIS и среда выполнения не разделяют пользователя, под которым они работают. В этом случае среда выполнения требует этого, так как два пользователя не имеют одинаковых прав.

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

0 голосов
/ 08 декабря 2011

Связано ли это со следующей ошибкой подключения:

https://connect.microsoft.com/VisualStudio/feedback/details/712500/cant-use-appdomains-inside-wcf-called-methods

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...