【发布时间】:2021-02-21 18:51:37
【问题描述】:
我们有一个在 ASP.NET 4.5.2 上运行的网站,它在新会话的第一次表单提交时引发以下视图状态错误,特别是并且仅当该表单提交是网站上的第一次回发时。任何后续表单提交似乎都很好,直到您关闭浏览器并开始新会话。如果您先在网站上的其他地方导航然后转到表单,也不会发生这种情况;仅当您从一开始就直接进入表单(即直接导航到登录页面)。
Event code: 4009
Event message: Viewstate verification failed. Reason: The viewstate supplied failed integrity check.
Is authenticated: False
Authentication Type: Forms
Thread account name: IIS APPPOOL\.NET v4.5
Exception message: Invalid viewstate.
这已在 Edge 和 Chrome 中报告/演示,但在 Firefox 或 Internet Explorer 中没有。
编辑:原来我们能够识别 Edge 和 Chrome 在初始浏览网站时没有 ASP.NET_SessionID 会话 cookie。回发后,会话 ID 出现在 cookie 中,表单再次工作。这在 Firefox 中不会发生,Firefox 具有来自第一个页面加载的 .NET 会话 ID。此会话 ID 被用作 ViewStateUserKey,这可能解释了错误的原因,但不能解释原因。为什么 Chrome 在回发之前没有会话 ID?
我已经阅读了互联网上关于此错误的所有内容,所以让我根据我看到的其他建议记录几点:
- 将机器密钥添加到 Web 配置文件没有帮助。我们已经试过了。此外,此站点不在服务器场上,而是在单个 Web 服务器上运行。
- 我已经看到可能涉及应用程序池回收或服务器上的内存限制的建议,但有问题的服务器运行时远未接近其资源限制,并且可以一致地复制错误;如果它与应用程序池事件或内存问题有关,我预计它会更加零星。
其他相关信息:
- 服务器在 Windows Server 2012 R2 上运行 IIS 8
- Web 配置中的身份验证设置为
<authentication mode="Forms"><forms name="XXXXXXXXXX" loginUrl="SignIn.aspx" timeout="525600" /></authentication> - 网络配置中的会话状态为
<sessionState mode="InProc" cookieless="false" timeout="20" />
任何想法将不胜感激!
编辑:有人询问表单是如何提交的。这是来自我可以在其上重现错误的表单页面之一的表单代码示例,giftcard.aspx。
<form name="aspnetForm" method="post" action="./giftcard.aspx" onsubmit="javascript:return WebForm_OnSubmit();" id="aspnetForm">
<div>
<input type="hidden" name="__EVENTTARGET" id="__EVENTTARGET" value="" />
<input type="hidden" name="__EVENTARGUMENT" id="__EVENTARGUMENT" value="" />
<input type="hidden" name="__VIEWSTATE" id="__VIEWSTATE" value="/[gibberish]" />
</div>
<script type="text/javascript">
//<![CDATA[
var theForm = document.forms['aspnetForm'];
if (!theForm) {
theForm = document.aspnetForm;
}
function __doPostBack(eventTarget, eventArgument) {
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {
theForm.__EVENTTARGET.value = eventTarget;
theForm.__EVENTARGUMENT.value = eventArgument;
theForm.submit();
}
}
//]]>
</script>
<script src="/WebResource.axd?[gibberish]" type="text/javascript"></script>
<script src="jscripts/formvalidate.js" type="text/javascript"></script>
<script src="jscripts/core.js" type="text/javascript"></script>
<script src="/ScriptResource.axd?[gibberish]" type="text/javascript"></script>
<script src="/ScriptResource.axd?[gibberish]" type="text/javascript"></script>
<script src="/ScriptResource.axd?[gibberish]" type="text/javascript"></script>
<script src="/WebResource.axd?[gibberish]" type="text/javascript"></script>
<script type="text/javascript">
//<![CDATA[
function WebForm_OnSubmit() {
if (typeof(ValidatorOnSubmit) == "function" && ValidatorOnSubmit() == false) return false;
return true;
}
//]]>
</script>
我们使用 asp:Button 控件进行提交,如下所示:
<asp:Button ID="btnContinue" CssClass="btn-primary btn-GCcontinue" runat="server" Text="Continue" OnClick="btnContinue_Click" />
这个例子是网站上的典型表格。
【问题讨论】:
-
如何在页面中发布表单?第一次访问表单时是否可以自动提交?两者在服务器端验证时不一致。您能描述一下您是如何发布表单并显示页面代码的吗?
-
已更新以包含来自表单页面之一的代码示例。
-
你在这个表单页面中使用site.master吗?或者你重写了一个新的 site.master 页面,这使得 viewstate 的值有问题。需要查看site.master中viewstate的验证过程,好像修改了input的值。
-
我们确实使用母版页,并且表单在母版页中。我没有编写表单代码,这个网站最初是一个开箱即用的解决方案,据我所知,这方面没有改变。如果您查看我提供的示例代码,看起来 __doPostBack 正在更改为在任何回发时提交表单。你认为这是问题的一部分吗?
-
如果你使用site.master并且不改变它,我认为问题可能是由“"。请删除它并重新测试。
标签: asp.net forms session iis viewstate