为什么.NET会突然尝试在我的ASP.NET应用程序中序列化我的对象?

时间:2011-06-27 12:21:10

标签: .net asp.net iis azure authorization

我在完整IIS模式下运行Azure Web角色。请求已获得custom basic authentication授权。

我有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程序集(我通过处理{修复{1}}事件)。

我不知道为什么序列化开始了?为什么在本地用户下运行应用程序池并调用那些简单的代码会突然触发序列化?

3 个答案:

答案 0 :(得分:4)

编辑重新阅读您的问题,我不太确定这是问题所在。我将它留在这里,因为我花了5分钟写它,这是有用的信息:)如果你正在编写网络应用程序,你需要了解会话状态和存储选项!

<小时/> 正如Daniel Powell所说,你很可能在会话状态中存储了一个对象实例。

ASP.NET应用程序有3种标准模式用于存储会话状态。 InProc(进程内)将其存储在内存中,因此不需要序列化。 StateServerSqlServer将尝试将会话状态分别序列化为ASP.NET状态服务器或SQL服务器。

要确认这是问题,您需要检查web.config文件中mode元素的sessionState属性。

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

如果您使用的是SQL Server或State Server,那么您的应用程序将在每个请求结束时序列化整个会话状态。你有几个选择:

  1. 将会话状态更改为InProc。这将阻止序列化,但您将无法使用负载平衡环境。此外,如果您的应用程序重新启动,则所有用户都将丢失其会话(因为它保存在内存中)。

  2. 停止将此对象放入会话中。如果你不需要将这个对象存储在Session中,那就不要了!问题解决了。

  3. 通过实现ISerializable,使对象及其任何子元素可序列化。如果对象使用“实时”元素(如数据库连接等)

  4. ,则无法执行此操作

答案 1 :(得分:1)

对这个答案要谨慎,因为我不能确定它是好的答案。

首先,我假设你没有设置类似sql会话管理的东西,你唯一改变的是运行IIS的用户。

你观察到两种现象:

  1. 不应序列化的对象的序列化
  2. 通过尚未加载程序集的AppDomain加载程序集。
  3. 由于您的appdomain已经加载了程序集,因此可以安全地假设该异常是由另一个AppDomain引发的。如果它被另一个Appdomain抛出,可能是因为此AppDomain正在尝试反序列化您的自定义对象。 (在另一个例外证明之前,它已被序列化。)

    行。现在即使IIS在本地用户下运行,角色环境也不是。此服务随Azure OS一起安装,您无法选择其运行的用户(事实上您可能会这样做,但我不会)

    我认为,为了从RoleEnvironnement获取信息,Azure运行时能够使用两个代码路径:

    1. 如果IIS服务和运行时在同一用户下运行,则不需要appdomain切换。
    2. 另一个,如果IIS服务和运行时不共享它们正在运行的用户。在这种情况下,运行时需要它,因为两个用户没有相同的权限。
    3. 总而言之,我当然不知道为什么Azure运行时希望在不同的AppDomain之间移动您的用户,但它可能正是这样做的。

答案 2 :(得分:0)