为什么此代码不更新数据库表?

时间:2017-03-22 16:53:31

标签: sql-server winforms webforms .net-4.5 .net-2.0

在旧的ASP.NET Webforms应用程序中,我需要在用户单击按钮时更新数据库表,具体取决于检查表单上的复选框,使用相应标签中的值进行更新。

它不起作用;但是,Winforms“test”应用程序中几乎完全相同的代码确实有效。

FormLoad(Winforms)和Page_Load(Webforms)代码运行正常;没有必要显示所有代码;他们都使用成对的标签/复选框控件填充表单/页面。

要显示它们彼此之间的区别,但是:当动态创建控件时,它们会分配Tag值(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的代码可以正常工作(单击按钮时更新数据库表);使用.NET Framework 2的Webforms应用程序中的代码不会像应该的那样更新数据库表 - 但是没有显示错误的页面,只是甜蜜的笑容和懒洋洋地依赖于它的桂冠。

我在两者之间的代码中看到的唯一真正区别是,在一种情况下(Winforms应用程序),动态创建的控件的Tag属性被赋值,而在另一种情况下(Webforms站点),动态创建的控件的ID属性是指定的。顺便说一句,这两种技术似乎都没有其他属性可用(Winforms似乎无法访问控件的ID属性,而Webforms似乎无法访问控件的Tag属性)。

相关的区别是没有两个控件可以具有相同的ID(Webforms);因此,我必须将“lbl”添加到Label控件ID,将“ckbx”添加到Checkbox控件ID(每对共享相同的编号,以便“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的最后一个文本是“来自foreach的标签2文本”。

所以,“如果TypeOf cntrl是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

现在这里有一些超级怪异的东西,在我看来:我在Webform上放了一个复选框,然后再次运行它。即使表单上有可见的设计时复选框,它仍然没有超过“If TypeOf cntrl Is CheckBox Then”测试; Label2.Text的最后一次更新仍然是“来自foreach的标签2文本”

Checkbox,特别是“具体”而不是动态的复选框怎么能不等同于复选框?!

0 个答案:

没有答案