我是一个MVC3网络应用程序。我已经使用了 PRG (重定向后获取)模式。那是在回发期间如果任何模型验证失败我persist the ViewData in TempData然后重定向到原来的GET操作。
在后期行动中 -
if (!ModelState.IsValid)
TempData["ViewData"] = ViewData;
后来的GET行动 -
if (TempData["ViewData"] != null)
ViewData = (ViewDataDictionary)TempData["ViewData"];
这几乎是通常的做法。到目前为止,一切都很好。 现在,我们需要改善我们需要的会话持久性"更长时间"会话。我已经结束使用ASP.Net State Server。
将会话迁移到State Server后 -
web.config -
<system.web> ...
<sessionState timeout="180" mode="StateServer" cookieless="UseCookies" />
...
我开始得到&#34;无法序列化&#34;存储自定义对象的某些会话的错误。我已经制作了这样的对象 [Serializable] ,它解决了这个问题。但是现在我坚持使用上面的PRG模式了!
错误 - 键入&#39; System.Web.Mvc.ViewDataDictionary&#39;在大会 &#39; System.Web.Mvc,Version = 3.0.0.0,Culture = neutral, 公钥= 31bf3856ad364e35&#39;未标记为可序列化。
奇怪的是我无法找到共享我的场景的单个线程。任何人?
答案 0 :(得分:2)
TempData is stored in session和我的会话反过来存储在外部进程中的事实要求存储的任何内容必须是“可序列化的”。
像ViewDataDictionary或甚至ModelStateDictionary这样的对象不是[Serializable]。对于MVC PRG,我只需要传递模型状态错误和无效对象。
我已经将对象标记为[Serializable](我正在使用xml 序列化器“字符串化”我的obj然后存储它 - 因为它是一个L2S 实体因此也需要避免循环引用)。参考SO Post
TempDate["modelToPass"] = Serialization.Serialize<MyModel>(modelToPass);
同样我可以将我的ModelState对象(仅用于错误)转换为“更简单”的对象并将其转换为类似
的对象KeyValuePair<string,List<string>>[]
简而言之,我正在尝试使我的modelstate和modelObject“可序列化”,以便我可以将它们放在TempData中并保持PRG模式。
还有一些其他方法可以部署我们自己的TempData并在Cookie等中存储TempData。但我不想让事情复杂化。如果有人有更好的解决方案,请告诉我。
一些参考资料