Почему этот код не обновляет таблицу базы данных?

В устаревшем приложении ASP.NET Webforms мне нужно обновить таблицу базы данных, когда пользователь нажимает кнопку, в зависимости от того, какие флажки в форме установлены, используя значение из соответствующей метки для обновления.

Это не работает; однако почти идентичный код в "тестовом" приложении Winforms работает.

Код FormLoad (Winforms) и Page_Load (Webforms) работает нормально; нет необходимости показывать весь этот код; они оба заполняют форму / страницу парами элементов управления метка / флажок.

Однако, чтобы показать, как они отличаются друг от друга: Когда элементы управления создаются динамически, они присваивают строковое значение тега (Winforms) или ID (Webforms) (подробнее об этом ниже).

В рабочем (Winforms) коде это делается так:

Dim lblCompanyName = New Label()
lblCompanyName.Tag = i.ToString()
lblCompanyName.Text = reader.Item(0).ToString()
Me.Controls.Add(lblCompanyName)

Dim ckbx = New CheckBox()
ckbx.Tag = i.ToString()
ckbx.Checked = True
Me.Controls.Add(ckbx)

В нерабочем коде (Webforms) это делается следующим образом:

Dim coName = New Label()
' Must prepend with something, as controls cannot share the same ID
coName.ID = "lbl" + i.ToString()
coName.Text = categoryDT.Rows(i)(0).ToString()
formCustCatMaint.Controls.Add(coName)

Dim chk = New CheckBox()
chk.ID = "ckbx" + i.ToString()
chk.Checked = True
formCustCatMaint.Controls.Add(chk)

Помимо кода загрузки формы / страницы, есть только три других блока кода: обработчик события нажатия кнопки и два служебных метода, вызываемых этим обработчиком.

Работает код в приложении Winforms, который использует.NET Framework 4.5 (обновляет таблицу базы данных при нажатии кнопки); код в приложении Webforms, который использует.NET Framework 2, не обновляет таблицу базы данных так, как должно - но пока не показывает страницы ошибок, просто сладко ухмыляется и лениво почивает на лаврах.

Единственное реальное различие, которое я вижу в коде между ними, заключается в том, что в одном случае (приложение Winforms) свойству Tag динамически созданным элементам управления присваивается значение, тогда как в другом (сайт Webforms) динамически создаваемые элементы управления ' ID свойство это то, что назначено. Кстати, ни одна из технологий, похоже, не имеет другого доступного свойства (кажется, что Winforms не могут получить доступ к свойству ID для элемента управления, а Webforms не может получить доступ к свойству Tag для элемента управления).

Отличие заключается в том, что никакие два элемента управления не могут иметь одинаковый идентификатор (веб-формы); таким образом, я должен добавить "lbl" к идентификаторам элементов управления Label и "ckbx" к идентификаторам элементов управления Checkbox (каждая пара имеет одно и то же число, так что "lbl1" и "ckbx1" - это согласованная пара, "lbl42" и "ckbx42"- согласованная пара и т. д.).

Почему почти идентичный код в приложении Webforms не может обновить базу данных?

Вот рабочий код (Winforms/.NET 4.5) для этих трех блоков кода:

Private Sub Button1_Click( sender As Object,  e As EventArgs) Handles Button1.Click
        Dim connStr As String = "SERVER=PLATYPUS42;DATABASE=duckbilldata;UID=schnozz;PWD=pondscum"
        Dim upd8DML As String = "UPDATE CustomerCategoryLog SET Category = 'Exploding' WHERE Unit = @Unit And MemberNo = @MemberNo AND Custno = @CustNo"

        Dim coName As String
        Dim argVals(2) As String
        Dim _Unit As String
        Dim _MemberNo As String
        Dim _CustNo As String
        Dim curTagVal As String

        For Each cntrl As Control In Me.Controls
                If TypeOf cntrl Is CheckBox Then
                    If DirectCast(cntrl, CheckBox).Checked = True Then
                        curTagVal = CStr(DirectCast(cntrl, CheckBox).Tag)
                        coName = GetLabelTextForTag(curTagVal)
                        argVals = GetArgValsForCompanyName(coName)
                        _Unit = argVals(0)
                        _MemberNo = argVals(1)
                        _CustNo = argVals(2)
                        Using conn As New SqlConnection(connStr), _
                            cmd As New SqlCommand(upd8DML, conn)
                            cmd.Parameters.Add("@Unit", SqlDbType.VarChar, 50).Value = _Unit
                            cmd.Parameters.Add("@MemberNo", SqlDbType.VarChar, 50).Value = _MemberNo
                            cmd.Parameters.Add("@CustNo", SqlDbType.VarChar, 50).Value = _CustNo
                            conn.Open
                            cmd.ExecuteScalar()
                        End Using
                    End If
                End If
            Next
End Sub

    Protected Function GetLabelTextForTag(tagVal As String) As String
        Dim CoName As String = ""

        For Each cntrl As Control In Me.Controls
            If TypeOf cntrl Is Label Then
                If DirectCast(cntrl, Label).Tag.ToString() = tagVal Then
                    CoName = DirectCast(cntrl, Label).Text
                    Exit For
                End If
            End If
        Next
        Return CoName
    End Function

    Protected Function GetArgValsForCompanyName(coName As String) As String()
        Dim args(2) As String

        Using con As New SqlConnection("SERVER=PLATYPUS42;DATABASE=duckbilldata;UID=schnozz;PWD=pondscum"),
              cmd As New SqlCommand("select Unit, MemberNo, CustNo from Customers WHERE CompanyName = @CoName", con)

            con.Open()

            cmd.CommandType = CommandType.Text
            cmd.Parameters.Add("@CoName", SqlDbType.VarChar, 50).Value = coName

            Using reader As SqlDataReader = cmd.ExecuteReader

                While reader.Read
                    args(0) = reader.Item(0).ToString()
                    args(1) = reader.Item(1).ToString()
                    args(2) = reader.Item(2).ToString()
                End While

            End Using

        End Using

        Return args
    End Function

... и вот код нерабочего (Webforms/.NET 2.0) для соответствующих блоков кода:

Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim connStr As String = "SERVER=PLATYPUS42;DATABASE=duckbilldata;UID=schnozz;PWD=pondscum"
    Dim upd8DML As String = "UPDATE CustomerCategoryLog SET Category = 'Exploding' WHERE Unit = @Unit And MemberNo = @MemberNo AND Custno = @CustNo"

    Dim coName As String
    Dim argVals(2) As String
    Dim _Unit As String
    Dim _MemberNo As String
    Dim _CustNo As String
    Dim curCheckboxIDVal As String

    For Each cntrl As Control In Me.Controls
            If TypeOf cntrl Is CheckBox Then
                If DirectCast(cntrl, CheckBox).Checked = True Then
                    curCheckboxIDVal = CStr(DirectCast(cntrl, CheckBox).ID)
                    coName = GetLabelTextForID(curCheckboxIDVal)
                    argVals = GetArgValsForCompanyName(coName)
                    _Unit = argVals(0)
                    _MemberNo = argVals(1)
                    _CustNo = argVals(2)
                    Using conn As New SqlConnection(connStr), _
                        cmd As New SqlCommand(upd8DML, conn)
                        cmd.Parameters.Add("@Unit", SqlDbType.VarChar, 50).Value = _Unit
                        cmd.Parameters.Add("@MemberNo", SqlDbType.VarChar, 50).Value = _MemberNo
                        cmd.Parameters.Add("@CustNo", SqlDbType.VarChar, 50).Value = _CustNo
                        conn.Open
                        cmd.ExecuteScalar()
                    End Using
                End If
            End If
        Next
End Sub

Protected Function GetLabelTextForID(ckbxIDVal As String) As String
    Dim CoName As String = ""
    Dim _idVal As String = ckbxIDVal
    Dim numberLen As Integer = _idVal.Length - "ckbx".Length
    _idVal = _idVal.Substring("ckbx".Length, numberLen)
    LabelDebug.Text = _idVal

    For Each cntrl As Control In Me.Controls
        If TypeOf cntrl Is Label Then
            If DirectCast(cntrl, Label).ID = "lbl" + _idVal Then
                CoName = DirectCast(cntrl, Label).Text
                Exit For
            End If
        End If
    Next
    Return CoName
End Function

Protected Function GetArgValsForCompanyName(coName As String) As String()
    Dim args(2) As String

    Using con As New SqlConnection("SERVER=PLATYPUS42;DATABASE=duckbilldata;UID=schnozz;PWD=pondscum"), _
          cmd As New SqlCommand("select Unit, MemberNo, CustNo from Customers WHERE CompanyName = @CoName", con)

        con.Open()

        cmd.CommandType = CommandType.Text
        cmd.Parameters.Add("@CoName", SqlDbType.VarChar, 50).Value = coName

        Using reader As SqlDataReader = cmd.ExecuteReader

            While reader.Read
                args(0) = reader.Item(0).ToString()
                args(1) = reader.Item(1).ToString()
                args(2) = reader.Item(2).ToString()
            End While

        End Using
    End Using

    Return args
End Function

Как видите, код практически идентичен, но результаты (успех / неудача) диаметрально противоположны. Зачем?

ОБНОВИТЬ

Видимо эта строка не работает:

If TypeOf cntrl Is CheckBox Then

Хотя на странице есть флажки, этот тест не пройден. Зачем?

Я знаю это, потому что я добавил несколько "отладочных" тестов в обработчик Button1_Click, например, так (не могу пройти по коду):

For Each cntrl As Control In Me.Controls
    Label2.Text="label 2 text from foreach"
    If TypeOf cntrl Is CheckBox Then
        Label2.Text="label 2 text from is checkbox"
        If DirectCast(cntrl, CheckBox).Checked = True Then
            Label2.Text="label 2 text from checked"
            . . .

Последний текст, написанный в Label2, - это "текст метки 2 от foreach".

Таким образом, "Если TypeOf cntrl Is CheckBox Затем" не удается.

Чекбоксы не видны, потому что они были созданы динамически? Если так, как я могу обойти это?

ОБНОВЛЕНИЕ 2

Когда я добавляю это в соответствующий файл.aspx:

<%@ Page Language="VB" AutoEventWireup="true" IsPostback="true" CodeFile="custmaint_categoryadmin.aspx.vb" 
Inherits="pages_custmaint_categoryadmin" %>

(добавлена ​​часть "IsPostback="true"")

... "IsPostback" подчеркивается красными волнистыми попугайчиками, и когда я запускаю его, я получаю:

Parser Error 
Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately. 

Parser Error Message: Error parsing attribute 'ispostback': The 'ispostback' property is read-only and cannot be set.

Source Error: 

Line 1:  <%@ Page Language="VB" AutoEventWireup="true" IsPostback="true" CodeFile="custmaint_categoryadmin.aspx.vb" Inherits="pages_custmaint_categoryadmin" %>
Line 2:  
Line 3:  <!DOCTYPE html>

ОБНОВЛЕНИЕ 3

Теперь мне кажется, что здесь есть нечто сверхъестественное: я поставил флажок на веб-форме и снова запустил ее. Даже если в форме установлен флажок "видимый во время разработки", он все равно не пройдет тест "If TypeOf cntrl Is CheckBox Then"; последнее обновление Label2.Text по-прежнему "текст метки 2 от foreach"

Как может случиться, что флажок, особенно "конкретный", а не динамический, не приравнивается к флажку?!?

0 ответов

Другие вопросы по тегам