导致这个“Base-64 char数组的长度无效”的原因

时间:2009-05-13 15:52:35

标签: .net asp.net exception viewstate

我很少去这里。我无法在本地重现,但当用户收到错误时,我会收到一封自动电子邮件异常通知:

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;

如果不能在本地重现错误,很难猜出错误的来源。

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

12 个答案:

答案 0 :(得分:82)

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

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

答案 1 :(得分:36)

我看到这种错误是由大小合适的视图状态和过度激进的内容过滤设备/防火墙组合而造成的(特别是在与K-12教育机构打交道时)。

我们通过在SQL Server中存储Viewstate来解决它。在走这条路线之前,我建议尝试限制你对viewstate的使用,不要在其中存储任何大的东西,并为所有不需要它的控件关闭它。

在SQL Server中存储ViewState的引用:
MSDN - Overview of PageStatePersister
ASP Alliance - Simple method to store viewstate in SQL Server
Code Project - ViewState Provider Model

答案 2 :(得分:21)

我的猜测是有些东西要么经常编码或解码 - 要么就是你有多行文字。

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

发生这种情况时是否记录用户代理?我想知道它是否是一个表现糟糕的浏览器...另一种可能性是有一个代理做顽皮的事情。同样,尝试记录请求的内容长度,这样您就可以看到它是否只发生在大型请求中。

答案 3 :(得分: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));
}

答案 4 :(得分:10)

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

其中qs是任何base64编码的字符串

答案 5 :(得分:8)

正如其他人所说,当一些防火墙和代理阻止访问包含大量ViewState数据的页面时,可能会导致这种情况。

ASP.NET 2.0引入了ViewState Chunking mechanism,它将ViewState分解为可管理的块,允许ViewState无问题地通过代理/防火墙。

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

<pages maxPageStateFieldLength="4000">

这应该用作减少ViewState大小的替代方法,但它可以成为针对“基础-64字符数组的无效长度”错误的有效支持,该错误是由于激进的代理和等。

答案 6 :(得分:1)

看看你的HttpHandlers。在我实现压缩工具(来自Telerik的RadCompression)之后的几个月里,我注意到了一些奇怪且完全随机的错误。我注意到错误:

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

  • System.Web.HttpException:客户端断开连接.---&gt; System.Web.UI.ViewStateException:viewstate无效。

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

  • System.Web.HttpException:客户端已断开连接。 ---&GT; System.Web.UI.ViewStateException:viewstate无效。

wrote about this在我的博客上。

答案 7 :(得分:1)

遗憾的是,这不是一个答案。在经历了一段时间的间歇性错误并最终烦恼到试图修复它之后,我还没有找到解决办法。但是,我确定了一个复制我的问题的方法,这可能对其他人有所帮助。

在我的情况下,它完全是一个本地主机问题,在我的开发机器上也有应用程序的数据库。这是我用VS2005编辑的.NET 2.0应用程序。 Win7 64位机器也安装了VS2008和.NET 3.5。

以下是从各种形式产生错误的内容:

  1. 加载表单的新副本。
  2. 使用任何表单的控件输入一些数据和/或回发。只要没有明显的延迟,重复您喜欢的一切,并且不会发生任何错误。
  3. 稍等片刻(可能是1分钟或2分钟,不超过5分钟),然后尝试另一次回发。
  4. 一分钟或两分钟延迟“等待localhost”,然后浏览器“重置连接”,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()
    

    在这种情况下,它不是viewstate的SIZE,而是与页面和/或viewstate缓存有关,这似乎是在咬我。在<pages>中设置enableEventValidation="false"参数viewStateEncryption="Never"Web.config并未改变行为。也没有将maxPageStateFieldLength设置为适度的。

答案 8 :(得分:0)

这是因为一个巨大的视野状态,在我的情况下,我很幸运,因为我没有使用视图状态。我刚刚在表单标记上添加了enableviewstate="false",并且查看状态从35k变为100个字符

答案 9 :(得分:0)

在使用SqlMembershipProvider对Membership.ValidateUser进行初始测试期间,我使用哈希(SHA1)算法结合盐,如果我将盐长度更改为不能被4整除的长度,我收到此错误。

我没有尝试过上面的任何修复,但如果更改了盐,这可能有助于某人查明这是此特定错误的来源。

答案 10 :(得分:0)

除了帮助我的@jalchr's solution之外,我发现当从c ++应用程序调用{​​{1}}来编码传递给ASP.NET Web服务的内容时,您还需要其他东西。

除了

ATL::Base64Encode
来自@jalchr's solution,

需要确保您不使用sEncryptedString = sEncryptedString.Replace(' ', '+'); 上的ATL_BASE64_FLAG_NOPAD 标记:

ATL::Base64Encode

答案 11 :(得分:0)

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

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