【问题标题】:Unable to save values into SQL Server from dynamically generated ASP.NET Controls无法从动态生成的 ASP.NET 控件将值保存到 SQL Server
【发布时间】:2011-07-13 14:18:55
【问题描述】:

我有一个 asp.net 网络表单应用程序。在此应用程序中,学生上传作业并连同它一起提交调查。对于调查,我从 DB 读取值并在 gridview 的 RowDataBound 事件期间在表单上动态生成 ASP.NET 控件,如单选按钮列表、复选框列表、文本框。我无法在 Page_Init 方法中执行此操作,因为我仅在用户单击需要提交调查的特定作业时创建。

当我提交调查表时,调查值没有保存到数据库中。在调试期间,我发现代码隐藏页面中没有这些值。 radiobuttonlist.selectedvalue 返回“”,我收到以下错误:

从“”到整数的字符串转换无效。

回发后,表单值仍然存在,我不知道为什么它们无法在代码隐藏中访问。我很困惑,因为在所有控件上都启用了视图状态。

Dim lstContextArtifacts As New List(Of ContextAttributesArtifacts) 

                            Dim lstContextAttributesOpen As New List(Of ContextAttributesArtifactsOpenEnded)     
    For Each gvrow As GridViewRow In gridview_ContextAttributes.Rows
     If gvrow.RowType = DataControlRowType.DataRow Then

       Dim contextAttribute As New ContextAttributesArtifacts
       Dim contextAttributeOpen As New ContextAttributesArtifactsOpenEnded

    Select Case gvrow.Cells(1).Controls(1).ID.ToString()
    Case "rdblist"
        Dim _radiobtnlist As RadioButtonList = DirectCast(gvrow.Cells(1).FindControl("rdblist"), RadioButtonList)
        contextAttribute.ContextAttributeOptionID = _radiobtnlist.SelectedValue
        contextAttribute.ContextAttributeID = CType(gridview_ContextAttributes.DataKeys(gvrow.DataItemIndex).Value, Integer)
        contextAttribute.ArtifactID = varArtifactID
        lstContextArtifacts.Add(contextAttribute)
      End Select
    End If
    Next

我在以下行收到错误:

contextAttribute.ContextAttributeOptionID = _radiobtnlist.SelectedValue

我可以从 gridview 中投射单选按钮列表,但值无法访问,即使它们在回发后仍然存在。

提前感谢您的帮助。

更新1: 我参考了这些与我的问题有关的文章 http://www.4guysfromrolla.com/articles/092904-1.aspx

http://msdn.microsoft.com/en-us/library/Aa479007

http://www.codeproject.com/KB/aspnet/dynamiccontrolsByLeon.aspx 正如@coding gorilla 在下面的答案中所建议的那样。

但是,当用户单击作业时,我会生成这些控件,然后它会检查它是否需要调查。如果是这样,那么我会在网格视图 rowdatabound 事件中生成控件,这使我可以检查需要加载哪些控件。我没有在上述文章引用的页面加载事件中加载它们。或者正如文章提到的,我如何在每个页面请求上加载它们,因为它取决于用户行为。对不起,如果我误解了什么,请纠正我。

我认为用户选择的值没有保存在视图状态中。

UPDATE2:我给出了在 gridviewdatabound 事件上生成的代码。我什至在回发时对我的 gridview 进行数据绑定以重新生成动态控件。而且它们似乎保留了控件选择,但在代码隐藏中无法访问。

If e.Row.DataItemIndex > -1 Then
            Dim label1 As Label = DirectCast(e.Row.Cells(0).FindControl("lbl_ca"), Label)
            '  'MsgBox(label1.Text)
            Dim FormElement As Label = DirectCast(e.Row.Cells(0).FindControl("lbl_FormElement"), Label)

            Select Case FormElement.Text

                Case "radio"
                    ''Add Custom Logic Here
                    Dim rdblist As New RadioButtonList
                    rdblist.ID = "rdblist"
                    rdblist.EnableViewState = True
                    rdblist = myRadioButtonList(gridview_ca.DataKeys(e.Row.DataItemIndex).Value)
                    Dim v1 As New RequiredFieldValidator
                    v1.ControlToValidate = "rdblist"
                    v1.ValidationGroup = "valSurvey"
                    v1.Text = "*"
                    v1.ForeColor = Drawing.Color.Red
                    v1.SetFocusOnError = True
                    v1.Display = ValidatorDisplay.Dynamic
                    Dim t1 As String = Now.ToLongTimeString.ToString.Replace(":", "")
                    t1 = t1.Replace("/", "")
                    t1 = t1.Remove(t1.Length - 3, 3)
                    t1 = t1.Replace(" ", "")
                    v1.ID = "val" + t1
                    e.Row.Cells(1).Controls.Add(v1)
                    e.Row.Cells(1).Controls.Add(rdblist)

            End Select
        End If

更新 3:我最终使用了另一种方法从控件中获取值。当我尝试在 onserver 验证事件上检查它们的值时,控件值仍然存在。所以插入了一个子程序来获取值并临时存储它们并稍后检索它们。

虽然我觉得这个系列文章对于理解动态添加的控件非常有用。

http://weblogs.asp.net/infinitiesloop/archive/2006/08/30/TRULY-Understanding-Dynamic-Controls-_2800_Part-3_2900_.aspx

【问题讨论】:

    标签: asp.net sql-server vb.net webforms


    【解决方案1】:

    这可能是一个非常复杂的问题,但问题的基础是这样的:

    您动态生成的 asp.net 控件,在回发之后,您必须在尝试使用这些控件之前重新生成这些控件。问题是您的代码隐藏仅包含通过解析 .aspx 文件直接创建的控件。

    请记住,每次生成页面请求(包括回发)时,都会重新创建由 .aspx.cs 文件表示的类(即newed向上)。因此,如果在初始渲染中创建复选框列表控件,并将其存储在实例字段中。页面呈现后,该特定类被销毁,当回发进入时,它被重新创建。

    因此,对于回发,您必须以与最初创建控件时完全相同的方式重新创建这些控件,并且这必须在加载回发数据之前进行。如果不是,则数据可作为 HTTP 请求中的表单字段使用,但 ASP.NET 不知道如何处理它。

    如果你只搜索“动态创建的 asp.net 控件”,有很多关于如何做这种事情的帖子。快速搜索将我带到了这个:http://www.codeproject.com/KB/aspnet/dynamiccontrolsByLeon.aspx

    【讨论】:

    • 请参考我的更新,感谢您的帮助。非常感谢。
    • 正如我在回答开头所说的,这可能是一个非常复杂的问题。 viewstate 真的与它无关,viewstate 仅用于在页面请求之间保持服务器端值。在您的情况下,需要将发布的数据从 HTTP 请求加载到控件中,然后才能到达视图状态。我仍然建议使用 CreateChildControls 事件,并且您可以使用 viewstate 属性来确定您的 CreateChildControls 方法需要做什么(如果有的话)。
    • 请参阅我的更新 2,其中包含更多生成控件的代码。谢谢。
    • 你还是有同样的问题,你的动态控件需要在回发数据处理之前重新创建,如果你在回发数据加载后创建你的控件,你的控件将永远看不到他们之前的数据回帖。试试这篇文章,看看它是否对你有帮助:msdn.microsoft.com/en-us/library/ms972976.aspx
    • 好吧,我想我错过了“回发之前”这两个词。让我试试看。再次感谢。我很抱歉打扰你。
    猜你喜欢
    • 2013-09-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-19
    • 1970-01-01
    • 2011-06-09
    相关资源
    最近更新 更多