不能在DropDownList中选择多个项目,但调试器可以完美地执行代码



刷新页面时会出现主题错误(数据绑定在页面加载时完成)。遍历页面的代码不会显示任何错误,堆栈跟踪中也不会引用任何页面:

Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 
Exception Details: System.Web.HttpException: Cannot have multiple items selected in a DropDownList.
Source Error: 
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.
Stack Trace:
[HttpException (0x80004005): Cannot have multiple items selected in a DropDownList.]
   System.Web.UI.WebControls.DropDownList.VerifyMultiSelect() +106
   System.Web.UI.WebControls.ListControl.RenderContents(HtmlTextWriter writer) +161
   System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) +32
   System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +208
   System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
   System.Web.UI.WebControls.WebControl.RenderContents(HtmlTextWriter writer) +10
   System.Web.UI.WebControls.WebControl.Render(HtmlTextWriter writer) +32
   System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +208
   System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
   System.Web.UI.Control.Render(HtmlTextWriter writer) +10
   System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +208
   System.Web.UI.UpdatePanel.RenderChildren(HtmlTextWriter writer) +256
   System.Web.UI.UpdatePanel.Render(HtmlTextWriter writer) +37
   System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +208
   System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
   System.Web.UI.Control.Render(HtmlTextWriter writer) +10
   System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +208
   System.Web.UI.HtmlControls.HtmlForm.RenderChildren(HtmlTextWriter writer) +173
   System.Web.UI.HtmlControls.HtmlContainerControl.Render(HtmlTextWriter writer) +31
   System.Web.UI.HtmlControls.HtmlForm.Render(HtmlTextWriter output) +53
   System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
   System.Web.UI.HtmlControls.HtmlForm.RenderControl(HtmlTextWriter writer) +40
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +208
   System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
   System.Web.UI.Control.Render(HtmlTextWriter writer) +10
   System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
   System.Web.UI.Control.RenderChildrenInternal(HtmlTextWriter writer, ICollection children) +208
   System.Web.UI.Control.RenderChildren(HtmlTextWriter writer) +8
   System.Web.UI.Page.Render(HtmlTextWriter writer) +29
   System.Web.UI.Control.RenderControlInternal(HtmlTextWriter writer, ControlAdapter adapter) +27
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer, ControlAdapter adapter) +100
   System.Web.UI.Control.RenderControl(HtmlTextWriter writer) +25
   System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3060

上次发生这种情况时,我在主页上有一个图像标签:

<img src="<%=Page.ResoveUrl("~/Images/footerLogo.png") %>" />

修改它以删除<% %><img src="/Images/footerLogo.png" />)块修复了错误,但我这次在主页面(或链接到有问题页面的任何页面)上没有任何这样的标记。这是我的代码:

Imports MySql.Data
Imports MySql.Data.MySqlClient
Partial Class maintreservation
    Inherits System.Web.UI.Page
    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            getClients()
            getDrivers()
            getVehicles()
            pnlDriven.Visible = False
            pnlSelfDriven.Visible = False
            If Not String.IsNullOrEmpty(Session("resid")) AndAlso Session("resid") IsNot Nothing Then
                getReservation()
            End If
        End If
    End Sub
    Protected Sub getDrivers()
        ddlDriver.ClearSelection()
        Dim db As New Database
        Dim sql As String = "select driverid, drivername from drivers order by drivername"
        Dim dr As MySqlDataReader = db.GetReader(sql)
        If dr.Read Then
            ddlDriver.DataSource = dr
            ddlDriver.DataTextField = "drivername"
            ddlDriver.DataValueField = "driverid"
            ddlDriver.DataBind()
        End If
        dr.Close()
        ddlDriver.Items.Insert(0, New ListItem("Select a Driver", 0))
    End Sub
    Protected Sub getVehicles()
        ddlVehicle.ClearSelection()
        Dim db As New Database
        Dim sql As String = "select veh.vehicleid, veh.licence_plate, veh.model, vm.make from vehicles veh " & _
            "inner join vehicle_manufacturers vm on veh.make = vm.makeid order by veh.make"
        Dim dr As MySqlDataReader = db.GetReader(sql)
        While dr.Read
            ddlVehicle.Items.Add(New ListItem(dr("make") & " " & dr("model") & " " & " (" & dr("licence_plate") & ")", dr("vehicleid")))
        End While
        dr.Close()
        ddlVehicle.Items.Insert(0, New ListItem("Select a Vehicle", 0))
    End Sub
    Protected Sub getClients()
        ddlClient.ClearSelection()
        Dim db As New Database
        Dim sql As String = "select clientid, clientname, contact from clients order by clientname"
        Dim dr As MySqlDataReader = db.GetReader(sql)
        If dr.Read Then
            ddlClient.DataSource = dr
            ddlClient.DataTextField = "clientname"
            ddlClient.DataValueField = "clientid"
            ddlClient.DataBind()
        End If
        dr.Close()
        ddlClient.Items.Insert(0, New ListItem("Select an Agent", 0))
        getClientContact()
    End Sub
    Protected Sub getClientContact()
        Dim db As New Database
        Dim sql As String = "select contact, vat_no from clients where clientid = " & ddlClient.SelectedItem.Value
        Dim dr As MySqlDataReader = db.GetReader(sql)
        If dr.Read Then
            If Not IsDBNull(dr("contact")) Then
                lblClientContact.Text = dr("contact")
            Else
                lblClientContact.Text = ""
            End If
            If Not IsDBNull(dr("vat_no")) Then
                txtVatNo.Text = dr("vat_no")
            Else
                txtVatNo.Text = ""
            End If
        End If
        dr.Close()
    End Sub
    Protected Sub ddlClient_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles ddlClient.SelectedIndexChanged
        getClientContact()
    End Sub
    Protected Sub getReservation()
        Dim db As New Database
        Dim sql As String = _
            "select * from reservations res " & _
            "inner join reservationbody trip on res.reservationid = trip.reservationid " & _
            "inner join vehicles vehicle on trip.vehicleid = vehicle.vehicleid " & _
            "left outer join drivers driver on trip.driverid = driver.driverid " & _
            "where res.reservationid = " & Session("resid")
        Dim dr As MySqlDataReader = db.GetReader(sql)
        If dr.Read Then
            ' GET CLIENT
            ' -------------------------------------------------------------
            ddlClient.ClearSelection()
            ddlClient.Items.FindByValue(dr("clientid")).Selected = True
            getClientContact()
            ' GET VOUCHER
            ' -------------------------------------------------------------
            If IsDBNull("vouchernumber") Then
                txtVoucher.Text = ""
            Else
                txtVoucher.Text = dr("vouchernumber")
            End If
            ' GET DRIVER
            ' -------------------------------------------------------------
            If dr("driverid") = "0" Then
                ' Self Drive
                rblTrips.Items(1).Selected = True
                pnlDriven.Visible = False
                pnlSelfDriven.Visible = True
            Else
                ' Driven
                rblTrips.Items(0).Selected = True
                pnlSelfDriven.Visible = False
                pnlDriven.Visible = True
                ddlDriver.ClearSelection()
                ddlDriver.Items.FindByValue(dr("driverid")).Selected = True
            End If
            ' GET PASSENGER/S
            ' -------------------------------------------------------------
            If IsDBNull(dr("passengers")) Then
                txtPassengers.Text = ""
            Else
                txtPassengers.Text = dr("passengers")
            End If
            If IsDBNull(dr("passengercontact")) Then
                txtPassengerContact.Text = ""
            Else
                txtPassengerContact.Text = dr("passengercontact")
            End If
            ' GET COMMENTS
            ' -------------------------------------------------------------
            If IsDBNull(dr("comments")) Then
                txtComments.Text = ""
            Else
                txtComments.Text = dr("comments")
            End If
            ' GET VEHICLES
            ' -------------------------------------------------------------
            ddlVehicle.ClearSelection()
            ddlDriver.Items.FindByValue(dr("vehicleid")).Selected = True
            ' GET DATES AND TIMES
            ' -------------------------------------------------------------
            txtPickupDate.Text = Left(dr("res_date"), 10) ' USE DATE(trip.res_date) as res_date in the sql statement
            ucTimeIn.Time = dr("time_in")
            ucTimeOut.Time = dr("time_out")
        End If
        dr.Close()
    End Sub
    Protected Sub rblTrips_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles rblTrips.SelectedIndexChanged
        If rblTrips.SelectedItem.Value = "driven" Then
            pnlDriven.Visible = True
            pnlSelfDriven.Visible = False
        Else
            pnlSelfDriven.Visible = True
            pnlDriven.Visible = False
        End If
    End Sub
End Class

如上所述,这段代码执行得很完美,所以我真的不知道这里的问题是什么。

我尝试过清洁和重建解决方案,但它仍然没有解决任何问题,所以欢迎任何见解!

Cory的输入让我决定返回并检查每个DropDownList是否只指定了1个选项,这时我发现了问题。

在上面的getReservation()中:

        ' GET DRIVER
        ' -------------------------------------------------------------
        If dr("driverid") = "0" Then
            ' Self Drive
            rblTrips.Items(1).Selected = True
            pnlDriven.Visible = False
            pnlSelfDriven.Visible = True
        Else
            ' Driven
            rblTrips.Items(0).Selected = True
            pnlSelfDriven.Visible = False
            pnlDriven.Visible = True
            ddlDriver.ClearSelection()
            ddlDriver.Items.FindByValue(dr("driverid")).Selected = True
        End If

然后:

        ' GET VEHICLES
        ' -------------------------------------------------------------
        ddlVehicle.ClearSelection()
        ddlDriver.Items.FindByValue(dr("vehicleid")).Selected = True

这只是糟糕的复制/粘贴,所以对于查看此答案的人,请确保100%确保您只选择了一次

顺便说一句,我被告知以下是更好的做法:

' Do this:
ddlVehicles.SelectedValue = dr("vehicleid")
' Instead of this:
ddlVehicles.Items.FindByValue(dr("vehicleid").Selected = True

在渲染任何ListControl时,如果遇到多个选定项目,则会设置一个标志。如果该标志为true,则调用抽象方法VerifyMultiSelect。如果DropDownListVerifyMultiSelect的实现遇到多个选定项,则会引发异常,因此您看到此异常的唯一可能原因是,您的一个DropDownList s中有多个ListItem s,其中Selected设置为true

我会仔细检查SQL的结果,以确定是否存在同一DropDownList中的多个项的Selected属性设置为true的情况。在上面的示例中,getReservation()函数中有三行代码改变了此属性。

也许这就是你处理IsPostBack的方式。ViewState中为该控件存储了一个以前选择的项,您正试图在返回后选择另一个值。

编辑:OP找到了解决方案。

我在重写别人的旧代码时遇到了类似的问题。对我来说,这是一个视图状态问题,只需调用即可解决

myDropDown.ClearSelection(); 

他们从一个没有键的枚举中提取下拉列表的数据源,从而使用FindText进行选择。如果下拉选择的项目发生了更改,但他们在PostBack上用FindText重新运行语句,而无需首先调用

myDropDown.ClearSelection();

根据Corys的回复,这意味着两个项目——刚刚选择的项目加上已经在视图状态中选择的项目——现在被选中,因此引发了异常。

不确定它是如何工作的,但直到对代码进行了一些小的更改,它才被公开。因此,如果有人正在努力根据OP的答案找到重复的代码行,那么您可能还想考虑在返回后查看状态机制。

最新更新