是什么导致此“ Base-64 char数组的长度无效”


91

我在这里很少。我无法在本地复制此消息,但是当用户收到错误消息时,我会收到自动的电子邮件异常通知:

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;

如果无法在本地重现错误,则很难猜测错误的来源。

如果有人对此错误有任何经验,我真的很想知道您发现了什么。

Answers:


36

我已经看到了这种错误,这是由于大小合适的视图状态和过分的内容过滤设备/防火墙(特别是与K-12教育机构打交道)相结合而引起的。

我们通过将Viewstate存储在SQL Server中来解决此问题。在走那条路线之前,我建议尝试通过不存储任何较大的视图状态并为不需要它的所有控件将其关闭来限制您对视图状态的使用。

在SQL Server中存储ViewState的参考:
MSDN-PageStatePersister
ASP Alliance 概述-在SQL Server 代码项目中存储ViewState的简单方法-ViewState
提供程序模型


我复制了页面的veiwstate并将其粘贴到Word中。它的长度超过86000个字符。似乎太过分了。
减肥2009年

kes,我现在遇到了问题。我已经为所有可能的控件关闭了ViewState。我正在使用具有多个页面和大量内容的向导控件。有什么建议吗?
Mike Cole

@Mike C.,这是一个非常令人沮丧的问题!您可以将向导每个页面的内容分解为用户控件,然后按需加载内容(通过ajax?)。当然,这仅是该页面的一种解决方案,如果您开始一致地遇到问题,则可能需要考虑在数据库中存储viewstate。我已经使用在SQL Server中存储viewstate的引用更新了我的答案。
Jimmie R. Houts,2009年

1
我遇到的另一个问题是长度超过86000个字符(假设单字节字符,我认为实际上可能接近85K)是您的.NET应用程序也可能开始在大型对象堆上放置视图状态字符串,这可能导致堆如果未回收应用程序池,则碎片会随着时间的流逝而碎片化(并最终导致OutOfMemoryException)。
没必要,2013年

我遇到了同样的问题,请问该如何解决。
2014年

84

urlDecode处理文本后,它将所有'+'字符替换为''...,因此出现错误。您应该简单地调用此语句以使其再次与base 64兼容:

        sEncryptedString = sEncryptedString.Replace(' ', '+');

好东西。谢谢。我当时从C ++ MFC应用程序调用ASP.NET Web服务,并且可能已经花了好几个小时在很多方面分支尝试解决此问题。您为我节省了很多时间。
nspire

3
刚刚遇到了这个问题,正如您所说的那样,请替换为+固定的空格。英雄!
mattytommo 2013年

任何人都可以在哪里包括此代码的指导?我经常处理此问题,但是从代码片段中,我无法确定在哪里实现此修复程序。
dst3p

@ dst3p在遇到错误的处理管道中的任何地方使用它。检查您的堆栈跟踪,并查看导致该错误的方法。
Jalal El-Shaer

21

我的猜测是某些东西编码或解码的频率太高-或者您输入的文本多行。

Base64字符串的长度必须是4个字符的倍数-每4个字符代表3个字节的输入数据。不知何故,ASP.NET传回的视图状态数据已损坏-长度不是4的倍数。

发生这种情况时,您是否登录用户代理?我想知道这是否是一个行为不佳的浏览器...另一种可能性是,有一个代理在做淘气的事情。同样,尝试记录请求的内容长度,这样就可以查看它是否仅适用于大型请求。


就我而言,浏览器始终是Safari(移动版或台式机版)
cockypup

12

试试这个:

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));
}

此方法有助于解决问题。虽然我没有使用UTF8编码
阿布舍克Shrivastava

10
int len = qs.Length % 4;
            if (len > 0) qs = qs.PadRight(qs.Length + (4 - len), '=');

qs任何base64编码的字符串在哪里


8

正如其他人提到的那样,这可能是由于某些防火墙和代理阻止访问包含大量ViewState数据的页面而引起的。

ASP.NET 2.0引入了ViewState Chunking机制,该将ViewState分为可管理的块,从而使ViewState可以毫无问题地通过代理/防火墙。

要启用此功能,只需将以下行添加到您的web.config文件中。

<pages maxPageStateFieldLength="4000">

不应其用作减小ViewState大小的替代方法,但它可以有效地避免由于攻击性代理等导致的“ Base-64 char数组的长度无效”错误。


这可能有副作用吗?
MonsterMMORPG '16

我从未见过任何观察者,有更多关于视角的信息
Red Taz

那么您的最佳长度是多少?我确实将其设置为1024
MonsterMMORPG,2016年

1

不幸的是,这不是答案。在遇到间歇性错误一段时间后,最终由于恼火而无法修复,我还没有找到解决方法。但是,我已经确定了重现我的问题的方法,这可能会对其他人有所帮助。

在我的情况下,这是我的开发机上唯一的本地主机问题,该机还具有应用程序的数据库。这是我正在用VS2005编辑的.NET 2.0应用程序。Win7 64位计算机还安装了VS2008和.NET 3.5。

这是通过多种形式产生错误的原因:

  1. 加载表格的新副本。
  2. 输入一些数据,和/或使用表单的任何控件回发。只要没有明显的延迟,请重复执行所有操作,并且不会发生任何错误。
  3. 请稍等片刻(可能需要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()

在这种情况下,不是视图状态的大小,而是与页面和/或视图状态缓存有关的事情似乎在困扰我。设置<pages>参数enableEventValidation="false",并且viewStateEncryption="Never"Web.config没有改变的行为。都没有将设置maxPageStateFieldLength为适度。


1

看看您的HttpHandlers。在实施压缩工具(Telerik的RadCompression)之后的几个月中,我一直注意到一些奇怪且完全随机的错误。我注意到以下错误:

  • System.Web.HttpException:无法验证数据。

  • System.Web.HttpException:客户端已断开连接。---> System.Web.UI.ViewStateException:无效的视图状态。

  • System.FormatException:Base-64 char数组的长度无效。

  • System.Web.HttpException:客户端已断开连接。---> System.Web.UI.ViewStateException:无效的视图状态。

我在博客上写了这个


您的博客已关闭。您是否还有其他链接,或者可以发布相关信息?thx
mga911


0

这是因为存在一个巨大的视图状态,对于我来说,我很幸运,因为我没有使用视图状态。我刚刚添加enableviewstate="false"了表单标签,视图状态从35k变为100个字符


0

在使用SqlMembershipProvider对Membership.ValidateUser进行初始测试的过程中,我将哈希(SHA1)算法与盐结合使用,并且,如果将盐长度更改为不能被四整除的长度,则会收到此错误。

我没有尝试任何上述修复,但是如果更改了盐,这可能会帮助某人将其确定为此特定错误的来源。


0

正如Jon Skeet所说,字符串必须是4个字节的倍数。但是我仍然遇到错误。

至少在调试模式下将其删除。在其上放置一个断点,Convert.FromBase64String()然后逐步执行代码。奇迹般地,这个错误对我而言消失了:)可能与View状态以及其他人报告的其他类似问题有关。


0

除了@jalchr的解决方案对我有所帮助之外,我发现ATL::Base64Encode从c ++应用程序进行调用以对传递给ASP.NET Web服务的内容进行编码时,还需要其他一些东西。此外

sEncryptedString = sEncryptedString.Replace(' ', '+'); 

@jalchr的解决方案中,需要确保不使用ATL_BASE64_FLAG_NOPAD on上标志ATL::Base64Encode

 BOOL bEncoded = Base64Encode(lpBuffer,
                    nBufferSizeInBytes,
                    strBase64Encoded.GetBufferSetLength(base64Length),
                    &base64Length,ATL_BASE64_FLAG_NOCRLF/*|ATL_BASE64_FLAG_NOPAD*/);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.