2009-02-23 127 views
54
时不时地(每天一次或左右)

我们看到以下类型在我们的记录错误的一个ASP.NET 3.5应用程序我应该忽略偶尔的无效viewstate错误吗?

  • 无效的视图状态
  • 无效的回发或回调参数

这些东西在ASP.NET应用程序中不时发生?有人建议我们花费大量时间来尝试诊断导致问题的原因吗?

回答

46

嗯,这取决于。无效的视图状态可能由于各种原因而发生。

  1. Viewstate太大,并且在用户在页面上导致回发之前未完成呈现。该修复通常是禁用触发回发的所有控​​件,并在页面加载完成后启用客户端 - 请参阅http://blogs.msdn.com/tom/archive/2008/03/14/validation-of-viewstate-mac-failed-error.aspx
  2. 您正在使用viewstate MAC(出于安全原因,您应该是),但您尚未设置机器键和应用程序池已经回收并生成一个新的。不要忘记设置一个ViewStateUserKey。
  3. 有人在Mac上使用旧版本的IE来截断隐藏的表单字段。在这种情况下,您需要将viewstate移出页面session state
  4. Viewstate MAC问题通常表明您在Web场中,并且忘记在web.config中设置机器密钥。但是如果你这样做了,那么它可能是有人试图做坏事(机器人张贴评论,有人试图触发禁用控件的事件等)。只有排除潜在的安全问题,才能追踪这些原因。

不管你做什么关闭视图状态或事件验证。

+1

你能提供有关项目2更详细? – 2009-08-27 04:56:43

+5

以及viewstate包含一个签名,以防止某人在客户端编辑它。该签名是从服务器的机器密钥生成的。除非您特别设置计算机密钥,否则应用程序池重新启动时会重新生成计算机密钥,导致以前的所有视图状态变为无效。如果你有用户认证,你也应该设置一个ViewStateUserKey来防止CSRF。 – blowdart 2009-08-27 06:06:01

1

对于前者我们可以做的事情不多 - 我会捕获这些异常,并将用户跳转到错误页面,并沿着“您所在的页面已过期的消息”,这通常发生在您尝试重新访问一个你已经输入数据的页面。“

我在使用UpdatePanels的相当大的页面上看到后者最多。我认为这是用户在页面加载完成之前发回(或可能回调)的时间,因此并非所有在页面末尾标记的javascript都已运行。

同样,除了在您的错误页面上显示适当友好的消息外,您无法对其进行任何操作。

7

一个问题可能是用户路由器截断表单域。解决这个问题的方法是在web.config中将MaxPageStateFieldLength设置为一个小数(如100),并将ViewState分解为小块。这很简单,this article完全解释它。

+0

这个改变是否帮助我避免“Base64”错误? – 2017-07-01 11:11:12

3

例外情况不会随时发生。他们总是出于正当理由,其中一些已经在其他答案中列出。

但是,为了缓解ViewState的问题,请考虑彻底禁用它。作为ASP.NET开发人员,我们经常倾向于在各种不需要的地方使用ViewState,因为它是默认的。在考虑使用控件之前,我通常会考虑使用静态html。如果您决定使用控件,请考虑是否确实需要启用ViewState。禁用它通常会导致更好的页面加载时间,所以如果可以的话,请执行此操作。

我希望它被默认禁用,所以人们被迫这样想,但事实并非如此。

更新回答评论:

我的头,我拿出3分的机会来关闭ViewState中的顶部。

  1. 如果数据在每次回发中加载,则禁用ViewState。如果你正在构建支持AJAX的站点(这是real AJAX不是UpdatePanel类型;)),这通常会是这种情况,您通常在第一次加载时加载数据,然后使用AJAX请求重新加载/更新数据。在某些情况下,您甚至可能在每次访问时加载数据,仅用于禁用ViewState,然后将数据缓存在服务器上。

  2. 你也可以考虑禁用ViewState,如果你绑定到真正静态的内容。有时我会发现一个数据绑定到数据库中的一个小静态基础表的列表或类似的东西。现在,这可能是危险的,但是如果我确信数据不会改变,我可能会将数据作为静态内容移动到页面中(可以将其包装在单独的控件中,以便不会有数据的多个静态副本)。但是如果数据改变了,你将不得不手动改变它。

  3. 简单的控件(如标签)通常是禁用ViewState的好选择。

最后,你可以切换到ASP.NET MVC框架,并挥手告别这些问题永远,这就是我打算做的,即使我会面临一些问题。 ;)

0

忽略此错误可能不是一个好主意。除了上述所有答案之外,您还可以考虑查看视图状态的大小。代理服务器可以截断大视图状态。

如果您的视图状态很大,那么使用ASP.net跟踪来查看哪些控件正在使用viewstate以及可以关闭它的位置可能是一个好主意。

0

据韦恩沃尔特·贝瑞在this博客张贴另一个罪魁祸首可以使用IE8的XHTML文档类型而对具有符合XHTML标记页。这可能会导致IE8将scrambled参数发送到scriptresource.axd并抛出无效的viewstate异常。

他建议确保所有的javascript块都包含// <![CDATA[]]>或者只是更改doctype(这可能会导致页面上的其他CSS /样式问题)。

0

我有过这样的异常被抛出在我的日志,不得不从这里列出的其他一个非常不同的原因。我确实有一个非常大的ViewState,这是问题的一部分。但是,这与另一个问题相结合导致了这些异常(并且可能偶尔会从IIS中收到不良响应)。

我正在处理的代码库中有一些奇特的代码,以避免双击,并作为其中的一部分,它添加了一些东西到每个按钮的单击事件的JavaScript,第一次点击后禁用按钮,然后通常的回传。但是像这样调用回发是一个问题,因为我的一些按钮已经有一个由.NET自动生成的回发调用。所以我最后得到了两个回传,其中一个有一个无效的ViewState。删除额外的回发为我停止了例外。

我知道我应该真的大大减少ViewState的大小,但这是一个很大的遗留代码库,并且这样的改变会非常有创意。

0

无效的视图状态对您的记录器或用户或您的网站没有任何价值,最终用户从不会看到这些错误。 避免这种错误,请尝试添加以下在Global.ascx

void Application_Error(object sender, EventArgs e) 
    {   
       if (ex is HttpException && ex.InnerException is ViewStateException) 
       { 
        Response.Redirect(Request.Url.AbsoluteUri); 
        return; 
       } 
    } 

更多的信息查看以下链接:

https://www.karpach.com/viewstateexception-invalid-viewstate.htm

相关问题