【问题标题】:ArrayTypeMismatch Exception in Session会话中的 ArrayTypeMismatch 异常
【发布时间】:2013-12-24 17:54:28
【问题描述】:

我有一个用 ASP.NET MVC 编写的网站。有一些自定义的授权逻辑,并添加了以下属性。

public sealed class CustomAuthorizeAttribute : AuthorizeAttribute

在 AuthorizeCore 方法的覆盖中,我尝试访问 Session 并且:

  1. HttpContext.Current.Session != null
  2. HttpContext.Current.Session.IsNewSession == false
  3. 但是 HttpContext.Current.Session.Keys 会引发 ArrayTypeMismatch 异常。 HttpContext.Current.Session["SomeKey"] 也会抛出相同的异常。因此,我无法从会话中获取值。

更多信息: 模式:SQL服务器

<sessionState allowCustomSqlDatabase="true" cookieless="UseCookies" mode="SQLServer" sqlConnectionString="Server=.;Database=ASPState;integrated security=true;" timeout="120" sqlCommandTimeout="240" />

堆栈跟踪:

在 System.Runtime.Serialization.Formatters.Binary.ObjectReader.ParseArrayMember(ParseRecord pr) 在 System.Runtime.Serialization.Formatters.Binary.ObjectReader.ParseMember (ParseRecord pr) 在 System.Runtime.Serialization.Formatters.Binary.ObjectReader.Parse(ParseRecord pr) 在 System.Runtime.Serialization.Formatters.Binary._BinaryParser.ReadMemberReference() 在 System.Runtime.Serialization.Formatters.Binary。_BinaryParser.Run() 在 System.Runtime.Serialization.Formatters.Binary.ObjectReader.Deserialize(HeaderHandler 处理程序,__BinaryParser serParser,布尔 fCheck,布尔 isCrossAppDomain,IMethodCallMessage methodCallMessage) 在 System.Runtime.Serialization.Formatters.Binary.BinaryFormatter.Deserialize(流序列化流,HeaderHandler 处理程序,布尔 fCheck,布尔 isCrossAppDomain,IMethodCallMessage methodCallMessage) 在 System.Web.Util.AltSerialization.ReadValueFromStream(BinaryReader 阅读器) 在 System.Web.SessionState.SessionStateItemCollection.ReadValueFromStreamWithAssert() 在 System.Web.SessionState.SessionStateItemCollection.DeserializeItem(字符串名称,布尔检查) 在 System.Web.SessionState.SessionStateItemCollection.get_Item(字符串名称) 在 System.Web.SessionState.HttpSessionStateContainer.get_Item(字符串名称) 在 System.Web.SessionState.HttpSessionState.get_Item(字符串名称) 在 d:{mypath}\SessionHelper.cs:line 41 中的 {mynamespace}.SessionHelper.get_UserSessionContext() 在 d:{mypath}\CustomAuthorizeAttribute.cs:line 50 中的 {mynamespace}.CustomAuthorizeAttribute.AuthorizeCore(HttpContextBase httpContext) 在 System.Web.Mvc.AuthorizeAttribute.OnAuthorization(AuthorizationContext filterContext) 在 System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext 控制器上下文,IList`1 过滤器,ActionDescriptor actionDescriptor) 在 System.Web.Mvc.Async.AsyncControllerActionInvoker.c_DisplayClass25.b_1e(AsyncCallback asyncCallback, Object asyncState)

谁能解释一下为什么会出现这个错误,我该如何解决它以及可能的解决方法?

【问题讨论】:

  • 您是否在会话中存储了任何重要的内容?您使用的是哪个会话提供程序?在记忆中? sql服务器?等等,如果像 sql server: 这样持久的东西最近有建吗?所有服务器机器都使用相同版本的软件吗? (即是否有可能持久化的数据与当前构建不匹配)
  • 还有:堆栈跟踪是什么?
  • 查看更新后的帖子,我们使用 SqlServer 模式,我在本地环境中遇到此错误。在该 AuthorizeCore 方法中重新启动应用程序后,我收到此错误。它曾经在仅从控制器调用会话时正常工作,现在在将会话逻辑添加到 AuthorizeCore 后出现这个奇怪的错误
  • @lhor 是否可以在其他浏览器中使用? (即一个干净的会话)我认为你已经破坏了那个特定的会话......
  • 没错,当我第一次在FireFox中尝试时,它运行顺利,没有任何错误。然后在 Visual Studio 中,我单击了重新启动 (Ctrl+Shift+F5) - 站点重新启动,然后发生了同样的错误。是否有可能以某种方式检测导致会话损坏的确切原因?

标签: .net asp.net-mvc session exception authorization


【解决方案1】:

这听起来像是基于类型的序列化程序(BinaryFormatterNetDataContractSerializer 等)在构建之间与不兼容的类型一起使用的常见问题。在一般情况下,这种方式足够工作,它通常允许您在构建之间使用相同的数据(因为您通常不会更改所涉及的类型),但是:有一个很大的动态类型生成时的问题 - 在 Entity Framework 和 NHibernate 等工具中广泛使用。从本质上讲,因为它们在运行时子类化,几乎可以保证您永远无法在重建之间进行反序列化,甚至可能在应用程序重新启动之间以及在集群中的不同节点之间进行反序列化。

这里有两条指导:

  • 永远不要将您的标准域实体存储在会话(或缓存)中:拥有一个专用的 DTO(即代表您要存储的数据的简单类型)并存储它。如果可能,使这种类型不可变(特别是为了避免相同对象与克隆的问题,这会在提供者之间发生变化)
  • 如果可能,请控制序列化,使其不依赖于类型定义:“基于契约”的序列化器,如 XmlSerializer、Json.NET 或 protobuf-net,都允许您在会话中处理 CLOB 或 BLOB 数据(或缓存)层,即使您在程序集之间移动类型并重命名它们,也可以轻松进行序列化/反序列化

【讨论】:

    猜你喜欢
    • 2017-01-13
    • 2013-03-06
    • 2013-04-09
    • 2012-10-16
    • 2020-09-27
    • 1970-01-01
    • 2022-07-23
    • 1970-01-01
    • 2018-08-17
    相关资源
    最近更新 更多