状态服务器上的多个序列化损坏了属性值
我的 ASP.NET MVC 应用程序中有异常的序列化/反序列化行为。
设置和架构如下:
.Net 3.5、MVC 2、Unity 2.0(用于依赖注入)、IIS 7。状态存储在 ASPNET 状态进程中。除了模型、视图和控制器之外,应用程序还包含许多应用程序特定的服务和模型映射器(用于与现有代码连接)。其中两个服务具有基于每个会话的生命周期,为此我实现了自定义 PerSessionLifetimeManager
(因为 Unity 没有开箱即用的生命周期)。此生命周期管理器使用 HttpContext.Current.Session 来存储对象。控制器、映射器、服务之间以及服务之间也存在相当多的依赖关系。
问题:
会话生命周期服务之一包含一个私有布尔字段,该字段在某些内部逻辑条件下更改值,但是该值在我的代码外部发生更改。经过一番调查,我发现问题与该对象每次序列化/反序列化两次有关,并且序列化期间字段的值不同。
到目前为止已完成的调查:
我在对象构造函数上有一个断点/日志记录,并将字段包装到一个属性中,并将断点/日志记录放在设置器上。对象肯定只构造一次,并且除了应该调用的那些之外,没有调用来更改属性值。我已经创建了对象来实现 ISerialized 并记录 System.Threading.Thread.CurrentThread.ManagedThreadId 和对象哈希(从对象的所有字段构造)。从我可以看到,如果属性/字段的值发生变化,对象会被序列化两次,一次使用新值,然后立即使用原始值。下次使用对象时,它会按 LIFO 顺序反序列化,因此首先拉出原始(未更改的)值对象,然后拉出更改的值对象。我尝试记录这些序列化调用的完整堆栈跟踪,但似乎都是 .Net 内部调用。
问题:
为什么会有多个具有不同值的序列化?如何避免这种情况?
当前的解决方法:
我使用 Session 而不是私有字段/属性,它工作得很好,但是在负载过重的网站上使用 session 并不是最好的事情,我希望能找到其他解决方案。
谢谢。
I have an abnormal serialization/de-serialization behavior in my ASP.NET MVC application.
Setup and architecture are as follows:
.Net 3.5, MVC 2, Unity 2.0 for dependency injection, IIS 7. State is stored in ASPNET state process. Application apart from models, views and controllers also contains a number of application specific services and model mappers (for interfacing with existing code). Two of the services have per Session based lifetime, for which I implemented custom PerSessionLifetimeManager
(as Unity does not have one out of the box). This lifetime manager uses HttpContext.Current.Session
to store objects. There are fair bit of dependencies between controllers, mappers, services and between services as well.
Problem:
One of session lifetime services contains a private boolean field which changes value under some internal logic conditions, however this value changes by outside of my code. After some investigation I found that problem relates to this object being serialized/de-serialized twice every time and values of the field are different during serializations.
Investigation done so far:
I have a break points/logging on object constructor and I wrapped field into a property and put breakpoint/logging on setter. Object is definitely constructed only once and there are no calls to change property value except those which should be called. I have made object to implement ISerializable
and put logging of System.Threading.Thread.CurrentThread.ManagedThreadId
and object hash (constructed from all fields of the object). From what I can see if value of the property/field changes object gets serialized twice once with new value and immediately after with original value. Next time object is used it de-serializes in LIFO order, so the original (unchanged) value object is pulled out first and then the changed one. I tried to log a full stack trace for these serialization calls, but it seem to be all .Net internal calls.
Questions:
Why is there multiple serializations with different values? How to avoid this?
Current work around:
I used Session instead of private field/property and it works fine, however use of session on heavily loaded websites is not the best thing and I am hoping to for some other solution.
Thank you.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您确定该值已损坏,还是您只是由于会话被清除而丢失了该值。会话中是否还有其他值同时消失?我对你的“状态存储在 ASPNET 状态进程中”的说法有点困惑。您的会话管理是否设置为 InProc 还是使用 StateServer?如果是 InProc,您肯定会遇到会话值丢失的情况(尤其是在共享托管环境中),并且应该切换到 ASP State Server Service 或 MSSQL State Server 解决方案。
Are you sure the value is becoming corrupted or are you simply loosing the value due to the session being purged. Do you have any other values in the session that disappear at the same time? I was a bit confused by your "State is stored in ASPNET state process. " statement. Is your session management set to InProc or are you using a StateServer? If it is InProc, you definitely will experience loss of session values (especially in shared hosting environments), and should switch to an ASP State Server Service or MSSQL State Server solution.