我有一个用户控件,大部分时间都能正常处理成千上万的请求,但通常每天大约一两次,有一个ArgumentOutOfRangeException指向Page_Load方法的第一行代码隐藏aspx.vb文件。我自己从来没有能够复制它,但是我记录了错误的详细信息/堆栈跟踪。问题是,我很肯定错误实际上并没有发生在Page_Load块中,尽管堆栈跟踪指示不是这样。事实上,我在那里的代码并不重要,为了证明这一点我在Page_Load中放了一些虚拟代码,发布并等待下一次出现如下......
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim abc As Integer = 123
abc = abc + 1
...
End Sub
果然,当错误最终再次发生时,它仍然指向Page_Load的第一行(第16行:Dim abc As Integer = 123)。显然,这不是会产生ArgumentOutOfRangeException的语句类型。
Type: System.ArgumentOutOfRangeException
Message: Index was out of range. Must be non-negative and less than the size of the collection.
Parameter name: index
Source: mscorlib
TargetSite: Void ThrowArgumentOutOfRangeException()
StackTrace: at System.ThrowHelper.ThrowArgumentOutOfRangeException()
at aut.ProductWithColorChoice.Page_Load(Object sender, EventArgs e) in F:\Visual Studio Projects\1003\templates\usercontrols\ProductWithColorChoice.ascx.vb:line 16
at System.EventHandler.Invoke(Object sender, EventArgs e)
at System.Web.UI.Control.OnLoad(EventArgs e)
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Control.LoadRecursive()
at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
在.ascx页面上使用的唯一内联代码实际上是在javascript块中找到,以获取控件的ClientId,以便在页面完全加载之前禁用控件。
<%@ Control Language="vb" AutoEventWireup="false" Inherits="aut.ProductWithColorChoice" %>
<script language="javascript" type="text/javascript">
(function () {
Sys.Application.add_load(setupButtonDisablers);
function setupButtonDisablers() {
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(onPageLoad);
Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(onSubmit);
Sys.Application.remove_load(setupButtonDisablers);
}
function onPageLoad() {
findAndEnable('<%= AddToCartImageButton.ClientID %>');
}
function onSubmit() {
findAndDisable('<%= YearDropDownList.ClientID %>');
findAndDisable('<%= MakeDropDownList.ClientID %>');
findAndDisable('<%= ModelDropDownList.ClientID %>');
findAndDisable('<%= ColorDropDownList.ClientID %>');
findAndDisable('<%= AddToCartImageButton.ClientID %>');
}
function findAndDisable(id) { findAndSetDisabledProperty(id, true); }
function findAndEnable(id) { findAndSetDisabledProperty(id, false); }
function findAndSetDisabledProperty(id, value) {
var control = $get(id);
if (control) control.disabled = value;
else alert('could not find ' + id);
}
})();
</script>
我通过记录收集到这个错误总是发生在可能通过数据绑定下拉列表的autopostback事件触发的回发中。
另外还要提一下,如果它是相关的,这个控件继承了另一个名为ProductControlBase的类,然后继承UserControl。但我会想,如果错误实际发生在那里,那么堆栈跟踪就会表明这一点。
我已经被这个问题困扰了很长时间,并且会对可能导致该异常的原因有所了解,或者对如何获得有关该问题的更多调试信息的一些建议(尽管我不能直接复制它)
12/7/12更新 我还没有解决它,但已取得进展。弄清楚堆栈跟踪没有指向代码中的正确行,可能是由于编译器优化,错误可能是这个块中的几行...考虑到if语句中的检查,你能否看到任何可能性sizeIndex不在0 - 6范围内?注意:PaintSizes,RegularPaintPrices和PaintWeights都是Specialized.StringCollections,每个都有7个字符串。
If My.Settings.PaintSizes.Contains(SizeOption) Then
sizeIndex = My.Settings.PaintSizes.IndexOf(SizeOption)
Price = Decimal.Parse(My.Settings.RegularPaintPrices(sizeIndex))
Weight = Double.Parse(My.Settings.PaintWeights(sizeIndex))
Else
Throw New ApplicationException(Me.ID & ": sizeoption must match exactly one of the values in PaintSizes located in the web.config file")
End If