Home All Groups Group Topic Archive Search About

ASP.NET 2.0 Databind during Client Callback

Author
27 Jan 2006 3:17 PM
jslaybaugh
I am trying to bind to a GridView or DetailsView after a callback using
the ClientCallback Manager in the new .NET 2.0 framework.  See below
for the HTML followed by the VB code:

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
    <script type="text/javascript">

        function GetEmployeeInfo(empID)
        {
            var Command = "employeeID:" + empID;
            var context = new Object();
            context.CommandName = "GetEmployeeInfo";
            <%=CallbackFunctionString %>
        }

        function CallBackHandler(result, context)
        {
          if (context.CommandName == "GetEmployeeInfo")
          {
            document.getElementById('status').innerHTML = result;
          }
        }

        function onError(message, context) {
          alert("Exception :\n" + message);
        }

    </script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <a href="#" onclick="GetEmployeeInfo(501);">Employee 501</a><br
/>
        <a href="#" onclick="GetEmployeeInfo(502);">Employee 502</a><br
/>
        <a href="#" onclick="GetEmployeeInfo(503);">Employee 503</a><br
/>
        <div style="width:500px;height:500px;border:solid black
1px;background-color:gainsboro;padding:20px;">
            <asp:DetailsView ID="DetailsView1" runat="server"
BackColor="White" BorderColor="#E7E7FF" BorderStyle="None"
BorderWidth="1px" CellPadding="3">
            </asp:DetailsView>
        </div>
        <asp:LinkButton ID="LinkButton1"
runat="server">LinkButton</asp:LinkButton>
    <div id="status"></div>
    </form>
</body>
</html>


-----------

Imports System.Data.SqlClient

Partial Class FancyTest
    Inherits System.Web.UI.Page
    Implements ICallbackEventHandler

    Public CallbackFunctionString As String
    Private CallbackResult As String

    Public Function GetCallbackresult() As String _
   Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult
        If CallbackResult = "error" Then
            Throw (New Exception("ERROR"))
        Else
            Return CallbackResult
        End If
    End Function


    Public Sub RaiseCallbackEvent(ByVal eventArgument As String)
Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent

        If eventArgument.StartsWith("employeeID:") Then
            eventArgument = eventArgument.Split(":"c).GetValue(1)

            CallbackResult = DisplayEmployeeInfo(CInt(eventArgument))
        Else
            CallbackResult = "Command not recognized"
        End If
    End Sub


    Protected Sub Page_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
        CallbackFunctionString =
Page.ClientScript.GetCallbackEventReference(Me, "Command",
"CallBackHandler", "context", "onError", False)
    End Sub


    Private Function GetEmployeeInfo(ByVal EmployeeID As Integer) As
Data.DataTable
        Dim cn As New SqlConnection(Global.ConnString)
        Dim cmd As New SqlCommand("select * from employees where
employeeid=@employeeID", cn)
        cmd.Parameters.Add("@EmployeeID", Data.SqlDbType.Int).Value =
EmployeeID

        Dim da As New SqlDataAdapter(cmd)
        Dim dt As New Data.DataTable()

        Try
            If cn.State <> Data.ConnectionState.Open Then cn.Open()
            da.Fill(dt)

            Return dt
        Catch ex As Exception
            Throw ex
        Finally
            If cn.State <> Data.ConnectionState.Closed Then cn.Close()
        End Try
    End Function

    Private Function DisplayEmployeeInfo(ByVal EmployeeID As Integer)
As String

        Dim dt As New Data.DataTable
        dt = GetEmployeeInfo(EmployeeID)

        DetailsView1.DataSource = dt
        DetailsView1.DataBind()
        DetailsView1.Visible = True

        Return employeeid.tostring
    End Function

    Protected Sub LinkButton1_Click(ByVal sender As Object, ByVal e As
System.EventArgs) Handles LinkButton1.Click
        DisplayEmployeeInfo(502)
    End Sub
End Class

----------

My problem is that the DetailsView1.Databind() call does nothing when
called via ClientCallback.  The page doesnt display the DetailsView
data.  I added an ASP.NET LinkButton just to make sure the code works
and if the page POSTS BACK, it works, but if it does a CALLBACK,
nothing happens.  Also, since the function that does the databind
returns the EmployeeID as a string, I know the code is executing,
because the page displays the EmployeeID.  Its strictly the Databind
that doesnt work.

I thought I had a pretty good understanding of the page lifecycle, but
this one confuses me.  I noticed by looking at the page source that
before the postback, the detailsview doesnt even exist on the client,
so i'm not surprised that we cant quickly modify it on the client, but
I thought the whole point of this AJAX stuff was that I could execute
server code asynchronously.

Sure, I can return strings and pre-formatted HTML to create a table or
something, but I want to use the power of the ASP.NET controls such as
DetailsView and GridView.  This really isnt much of a feature to
ASP.NET if you cant use all the powerful controls.  If i have to
generate raw HTML, I am just left with a (quicker) version of classic
ASP content generation.

Please help!!!

Jorin

Author
27 Jan 2006 4:03 PM
Peter Bromberg [C# MVP]
You have to understand that a client callback simply refreshes information on
the page using XMLHTTP "Under the hood" - it does not reload or postback the
page.

Because of this, you cannot expect server-side code to rebind your controls
to be executed.

You might want to take a look at the Anthem.Net offering on SourceForge.net.
It offers a complete "AJAX" (Remote Scripting) infrastructure along with grid
and other controls that WILL refresh their data with client callbacks. It
compiles for both ASP.NET 1.1 and 2.0
Peter

--
Co-founder, Eggheadcafe.com developer portal:
http://www.eggheadcafe.com
UnBlog:
http://petesbloggerama.blogspot.com




Show quoteHide quote
"jslayba***@gmail.com" wrote:

> I am trying to bind to a GridView or DetailsView after a callback using
> the ClientCallback Manager in the new .NET 2.0 framework.  See below
> for the HTML followed by the VB code:
>
> <html xmlns="http://www.w3.org/1999/xhtml" >
> <head runat="server">
>     <title>Untitled Page</title>
>     <script type="text/javascript">
>
>         function GetEmployeeInfo(empID)
>         {
>             var Command = "employeeID:" + empID;
>             var context = new Object();
>             context.CommandName = "GetEmployeeInfo";
>             <%=CallbackFunctionString %>
>         }
>
>         function CallBackHandler(result, context)
>         {
>           if (context.CommandName == "GetEmployeeInfo")
>           {
>             document.getElementById('status').innerHTML = result;
>           }
>         }
>
>         function onError(message, context) {
>           alert("Exception :\n" + message);
>         }
>
>     </script>
> </head>
> <body>
>     <form id="form1" runat="server">
>     <div>
>         <a href="#" onclick="GetEmployeeInfo(501);">Employee 501</a><br
> />
>         <a href="#" onclick="GetEmployeeInfo(502);">Employee 502</a><br
> />
>         <a href="#" onclick="GetEmployeeInfo(503);">Employee 503</a><br
> />
>         <div style="width:500px;height:500px;border:solid black
> 1px;background-color:gainsboro;padding:20px;">
>             <asp:DetailsView ID="DetailsView1" runat="server"
> BackColor="White" BorderColor="#E7E7FF" BorderStyle="None"
> BorderWidth="1px" CellPadding="3">
>             </asp:DetailsView>
>         </div>
>         <asp:LinkButton ID="LinkButton1"
> runat="server">LinkButton</asp:LinkButton>
>     <div id="status"></div>
>     </form>
> </body>
> </html>
>
>
> -----------
>
> Imports System.Data.SqlClient
>
> Partial Class FancyTest
>     Inherits System.Web.UI.Page
>     Implements ICallbackEventHandler
>
>     Public CallbackFunctionString As String
>     Private CallbackResult As String
>
>     Public Function GetCallbackresult() As String _
>    Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult
>         If CallbackResult = "error" Then
>             Throw (New Exception("ERROR"))
>         Else
>             Return CallbackResult
>         End If
>     End Function
>
>
>     Public Sub RaiseCallbackEvent(ByVal eventArgument As String)
> Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEvent
>
>         If eventArgument.StartsWith("employeeID:") Then
>             eventArgument = eventArgument.Split(":"c).GetValue(1)
>
>             CallbackResult = DisplayEmployeeInfo(CInt(eventArgument))
>         Else
>             CallbackResult = "Command not recognized"
>         End If
>     End Sub
>
>
>     Protected Sub Page_Load(ByVal sender As Object, ByVal e As
> System.EventArgs) Handles Me.Load
>         CallbackFunctionString =
> Page.ClientScript.GetCallbackEventReference(Me, "Command",
> "CallBackHandler", "context", "onError", False)
>     End Sub
>
>
>     Private Function GetEmployeeInfo(ByVal EmployeeID As Integer) As
> Data.DataTable
>         Dim cn As New SqlConnection(Global.ConnString)
>         Dim cmd As New SqlCommand("select * from employees where
> employeeid=@employeeID", cn)
>         cmd.Parameters.Add("@EmployeeID", Data.SqlDbType.Int).Value =
> EmployeeID
>
>         Dim da As New SqlDataAdapter(cmd)
>         Dim dt As New Data.DataTable()
>
>         Try
>             If cn.State <> Data.ConnectionState.Open Then cn.Open()
>             da.Fill(dt)
>
>             Return dt
>         Catch ex As Exception
>             Throw ex
>         Finally
>             If cn.State <> Data.ConnectionState.Closed Then cn.Close()
>         End Try
>     End Function
>
>     Private Function DisplayEmployeeInfo(ByVal EmployeeID As Integer)
> As String
>
>         Dim dt As New Data.DataTable
>         dt = GetEmployeeInfo(EmployeeID)
>
>         DetailsView1.DataSource = dt
>         DetailsView1.DataBind()
>         DetailsView1.Visible = True
>
>         Return employeeid.tostring
>     End Function
>
>     Protected Sub LinkButton1_Click(ByVal sender As Object, ByVal e As
> System.EventArgs) Handles LinkButton1.Click
>         DisplayEmployeeInfo(502)
>     End Sub
> End Class
>
> ----------
>
> My problem is that the DetailsView1.Databind() call does nothing when
> called via ClientCallback.  The page doesnt display the DetailsView
> data.  I added an ASP.NET LinkButton just to make sure the code works
> and if the page POSTS BACK, it works, but if it does a CALLBACK,
> nothing happens.  Also, since the function that does the databind
> returns the EmployeeID as a string, I know the code is executing,
> because the page displays the EmployeeID.  Its strictly the Databind
> that doesnt work.
>
> I thought I had a pretty good understanding of the page lifecycle, but
> this one confuses me.  I noticed by looking at the page source that
> before the postback, the detailsview doesnt even exist on the client,
> so i'm not surprised that we cant quickly modify it on the client, but
> I thought the whole point of this AJAX stuff was that I could execute
> server code asynchronously.
>
> Sure, I can return strings and pre-formatted HTML to create a table or
> something, but I want to use the power of the ASP.NET controls such as
> DetailsView and GridView.  This really isnt much of a feature to
> ASP.NET if you cant use all the powerful controls.  If i have to
> generate raw HTML, I am just left with a (quicker) version of classic
> ASP content generation.
>
> Please help!!!
>
> Jorin
>
>
Author
27 Jan 2006 7:29 PM
jslaybaugh
Thanks, Peter.

I was afraid that was the answer I was going to get...and like I said,
it makes sense--it just wasnt the answer I wanted :(.  I was hopeful
there would be some way of working around it and binding my data
controls.

I'll check out the Anthem.NET controls.

Thanks!

Jorin