为什么 .NET 会突然尝试序列化 ASP.NET 应用程序中的对象?
我在完整 IIS 模式下运行 Azure Web 角色。请求通过自定义基本身份验证进行授权。
我有继承自 System.Security.Principal.GenericIdentity 的 MyAssembly.CustomIdentity 类。当调用 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
类(我通过添加 Serialized
属性来修复它),然后它说它无法加载 MyAssembly
> 程序集(我通过处理 AppDomain.AssemblyResolve 事件来修复)。
我不明白的是为什么序列化会启动?为什么在本地用户下运行应用程序池并调用那个简单的代码会突然触发序列化?
I run an Azure web role in Full IIS mode. Requests are authorized with custom basic authentication.
I have MyAssembly.CustomIdentity
class that inherits from System.Security.Principal.GenericIdentity
. When HttpApplication.AuthenticateRequest
handler (OnEnter()
code from the link above) is invoked it performs checks, then creates an instance of MyIdentity.CustomIdentity
and assigns it to HttpContext.Current.User
. Then an actual ASP.NET request handler obtains that object and can use it to find what user it is for.
Now everything more or less works fine in default configuration when IIS is running under NETWORK SERVICE
account. During role startup I restart IIS application pool under a local user (to grant it extra privileges). Now even the following code
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
bool isAvailable = Microsoft.WindowsAzure.ServiceRuntime.RoleEnvironment.IsAvailable;
}
}
will throw various exceptions. First it says it can't serialize my CustomIdentity
class (which I fix by adding Serializable
attribute), then it says it can't load MyAssembly
assembly (which I fix by handling AppDomain.AssemblyResolve
event).
What I don't get is why serialization kicks in? Why running the application pool under s local user and invoking that trivial code suddenly trigger serialization?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
编辑重新阅读您的问题,我不太确定这是问题所在。我把它留在这里是因为我花了 5 分钟写它,它是有用的信息:) 如果您正在编写 Web 应用程序,您需要了解会话状态和存储选项!
As Daniel Powell says, it's very likely that you are storing an instance of your object in the session state.
ASP.NET 应用程序有 3 种标准模式来存储会话状态。
InProc
(进程内)将其存储在内存中,因此不需要序列化。StateServer
或SqlServer
将尝试分别将会话状态序列化到 ASP.NET 状态服务器或 SQL 服务器。要确认这就是问题所在,您需要检查 web.config 文件中
sessionState
元素的mode
属性。如果您使用 SQL Server 或 State Server,那么您的应用程序将在每个请求结束时序列化整个会话状态。这里有几个选项:
将会话状态更改为 InProc。这将阻止序列化,但您将无法使用负载平衡的环境。此外,如果您的应用程序重新启动,所有用户都将丢失其会话(因为它保存在内存中)。
停止将此对象放入会话中。如果您不需要将此对象存储在会话中,那么就不要这样做!问题已解决。
通过实现 ISerialized,使对象及其任何子元素可序列化。如果对象使用“活动”元素(例如数据库连接等),则这是不可能的。
EDIT Re-reading your question, I'm not so sure this is the issue. I'm leaving it here because I spent 5 minutes writing it, and it's useful info :) If you're writing web-apps, you need to know about session state and your storage options!
As Daniel Powell says, it's very likely that you are storing an instance of your object in the session state.
ASP.NET applications have 3 standard modes for storing session state.
InProc
(in-process) stores it in memory, so no serialization is required.StateServer
orSqlServer
will attempt to serialize the session state to either an ASP.NET State Server or a SQL server respectively.To confirm that this is the issue you will need to check what the
mode
attribute of thesessionState
element is in the web.config file.If you are using SQL Server or State Server, then your application will be serializing the entire session state at the end of every request. You have a few options here:
Change your session state to InProc. This will prevent the serialization, but you will not be able to use a load-balanced environment. Also, if your application restarts, all users will lose their session (as it is held in memory).
Stop putting this object in the Session. If you don't need to store this object in the Session, then don't! Problem solved.
Make the object, and any child elements of it, serializable, by implementing ISerializable. This will not be possible if the object uses "live" elements such as database connections, etc.
请谨慎对待这个答案,因为我不确定这是一个好的答案。
首先,我假设您还没有设置诸如 sql 会话管理之类的东西,并且您唯一更改的是运行 IIS 的用户。
您观察到两个现象:
由于您的应用程序域已经加载了程序集,因此可以安全地假设该异常是由另一个应用程序域引发的。如果它是由另一个 Appdomain 抛出的,则可能是因为此 AppDomain 正在尝试反序列化您的自定义对象。 (在其他异常表明这一点之前它已被序列化。)
好的。现在,即使 IIS 在本地用户下运行,角色环境也不会运行。该服务与Azure操作系统一起安装,您无法选择它运行的用户(事实上您可能可以,但我不会)
我认为,为了从RoleEnvironnement获取信息,Azure运行时能够使用两个代码路径:
总而言之,我当然不知道为什么 Azure 运行时想要在不同的 AppDomain 之间移动用户,但它可能正是这样做的。
Be cautious with this answer, as I am not absolutely sure it is the good one.
First, I assume you haven't set up something like sql session management, and the only thing you changed is the user under which IIS is running.
You observe two phenomenon:
As your appdomain has already loaded the assembly, it seems safe to assume that the exception is thrown by another AppDomain. If it is thrown by another Appdomain, it's probably because this AppDomain is attempting to deserialize your custom object. (It has been serialized before the other exception demonstrates that.)
OK. Now even if IIS is running under a local user, Role environnement isn't. This service is installed with the Azure OS, you can't choose the user it runs under (you could probably in fact, but I wouldn't)
What I think is that in order to get informations from RoleEnvironnement, the Azure runtime is able to use two code paths:
To conclude, I certainly don't know why the Azure runtime would like to move your user between different AppDomain, but it is probably doing exactly that.
这是否与以下连接错误相关:
https://connect.microsoft.com/VisualStudio/feedback/details/712500/cant-use-appdomains-inside-wcf- Called-methods
Is this related to the following connect bug:
https://connect.microsoft.com/VisualStudio/feedback/details/712500/cant-use-appdomains-inside-wcf-called-methods