是什么导致这个“Base-64字符数组长度无效”
我很less去这里。 我不能在本地重现这一点,但当用户得到错误,我得到一个自动的电子邮件exception通知:
Invalid length for a Base-64 char array. at System.Convert.FromBase64String(String s) at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString) at System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter.Deserialize(String serializedState) at System.Web.UI.Util.DeserializeWithAssert(IStateFormatter formatter, String serializedState) at System.Web.UI.HiddenFieldPageStatePersister.Load()
我倾向于认为分配给viewstate的数据存在问题。 例如:
List<int> SelectedActionIDList = GetSelectedActionIDList(); ViewState["_SelectedActionIDList"] = SelectedActionIDList;
如果不能在本地重现错误,就很难猜出错误的来源。
如果有人有这个错误的经验,我真的想知道你发现了什么。
我已经看到了这个错误造成的大尺寸视图状态和积极的内容过滤设备/防火墙(特别是在与K-12教育机构打交道时)的组合。
我们通过在SQL Server中存储Viewstate来解决这个问题。 在走这条路线之前,我会build议试图通过不存储任何大的内容来限制viewstate的使用,并closures所有不需要它的控件。
在SQL Server中存储ViewState的参考:
MSDN – PageStatePersister的概述
ASP联盟 – 在SQL Server中存储viewstate的简单方法
代码项目 – ViewState提供者模型
在urlDecode处理文本之后,它将用''replace所有'+'字符。 你应该简单地调用这个语句来使它和base 64兼容:
sEncryptedString = sEncryptedString.Replace(' ', '+');
我的猜测是,某些东西是编码或解码太频繁 – 或者你有多行的文本。
Base64string的长度必须是4个字符的倍数 – 每4个字符代表3个字节的input数据。 不知何故,被ASP.NET传回的视图状态数据被破坏 – 长度不是4的倍数。
发生这种情况时,您是否logging用户代理? 我不知道它是否是一个糟糕的浏览器…另一种可能性是有一个代理做淘气的事情。 同样,尝试logging请求的内容长度,以便您可以查看是否只发生大的请求。
int len = qs.Length % 4; if (len > 0) qs = qs.PadRight(qs.Length + (4 - len), '=');
qs
是任何base64编码的string
尝试这个:
public string EncodeBase64(string data) { string s = data.Trim().Replace(" ", "+"); if (s.Length % 4 > 0) s = s.PadRight(s.Length + 4 - s.Length % 4, '='); return Encoding.UTF8.GetString(Convert.FromBase64String(s)); }
正如其他人所提到的,当一些防火墙和代理阻止访问包含大量ViewState数据的页面时,可能会导致这种情况。
ASP.NET 2.0引入了ViewState分块机制 ,将ViewState分解为可pipe理的块,允许ViewState通过代理/防火墙而不会出现问题。
要启用此function,只需将以下行添加到您的web.config文件。
<pages maxPageStateFieldLength="4000">
这不应该作为减lessViewState大小的替代方法,但它可以成为针对激进代理等产生的“Base-64字符数组长度无效”错误的有效后盾。
看看你的HttpHandlers。 在我实现了一个压缩工具(Telerik的RadCompression)之后,我在过去的几个月里一直注意到一些奇怪的,完全随机的错误。 我注意到错误如:
-
System.Web.HttpException:无法validation数据。
-
System.Web.HttpException:客户端断开连接.–> System.Web.UI.ViewStateException:无效的视图状态。
和
-
System.FormatException:Base-64字符数组的无效长度。
-
System.Web.HttpException:客户端断开。 —> System.Web.UI.ViewStateException:无效的视图状态。
我在我的博客上写了这个 。
这是因为一个巨大的视图状态,在我的情况下,我很幸运,因为我没有使用视图状态。 我只是在窗体标签上添加了enableviewstate="false"
,视图状态从35k增加到了100个字符
在使用SqlMembershipProvider对Membership.ValidateUser进行初始testing期间,我使用了一个与盐结合的散列(SHA1)algorithm,如果将salt长度更改为不能被4整除的长度,我收到了这个错误。
我没有尝试过上面的任何修正,但如果盐被改变,这可能会帮助别人指出,作为这个特定的错误的来源。
正如Jon Skeet所说,string必须是4个字节的倍数。 但是我仍然得到错误。
至less它在debugging模式下被删除。 在Convert.FromBase64String()
上放一个断点,然后遍历代码。 奇迹般地,错误消失了:)这可能与视图状态和其他类似的问题有关。
可悲的是,这不是一个答案。 在经历了一段时间的间歇性错误后,终于恼火到足以尝试修复它,我还没有find解决办法。 但是,我已经确定了一个复制我的问题的方法,这可能会帮助别人。
在我的情况下,它是唯一的本地主机问题,在我的开发机器,也有应用程序的数据库。 这是一个我用VS2005编辑的.NET 2.0应用程序。 Win7 64位机器也安装了VS2008和.NET 3.5。
以下是从多种forms中产生错误的原因:
- 加载一份新的表格。
- input一些数据,和/或任何forms的控件回发。 只要没有显着的延迟,重复所有你喜欢的,没有错误发生。
- 稍等片刻(1或2分钟,不超过5),并尝试另一个回传。
一两分钟的延迟“等待本地主机”,然后由浏览器“连接重置”,以及global.asax
的应用程序错误陷阱日志:
Application_Error event: Invalid length for a Base-64 char array. Stack Trace: at System.Convert.FromBase64String(String s) at System.Web.UI.ObjectStateFormatter.Deserialize(String inputString) at System.Web.UI.Util.DeserializeWithAssert(IStateFormatter formatter, String serializedState) at System.Web.UI.HiddenFieldPageStatePersister.Load()
在这种情况下,这不是视图状态的大小,而是与页面和/或视图状态caching有关的事情,这似乎是在咬我。 在Web.config
设置<pages>
参数enableEventValidation="false"
和viewStateEncryption="Never"
不会改变行为。 也没有设置maxPageStateFieldLength
适度的东西。
除了帮助我的@ jalchr解决scheme之外 ,我发现当从c ++应用程序调用ATL::Base64Encode
来编码传递给ASP.NET webservice的内容时,您还需要其他的东西。 此外
sEncryptedString = sEncryptedString.Replace(' ', '+');
从@ jalchr的解决scheme,您还需要确保您不要在ATL::Base64Encode
上使用ATL_BASE64_FLAG_NOPAD
标志:
BOOL bEncoded = Base64Encode(lpBuffer, nBufferSizeInBytes, strBase64Encoded.GetBufferSetLength(base64Length), &base64Length,ATL_BASE64_FLAG_NOCRLF/*|ATL_BASE64_FLAG_NOPAD*/);