Dot Net KB

ViewState & posting with callbacks

ASP.NET Ajax makes it easy since UpdatePanel is capable to keep ViewState in sync, but if you insist using callbacks, you might have something to think.

Basically first issue is that with callbacks the data to post to the server is gathered at WebForm_InitCallback() method when the Page loads. So first issue you see is that it seems callback doesn't send updated information to the server, that is for the other fields on the form (you usually specify the callback param yourself so that of course changes). That is yet easy to overcome, just before doing the callback call to the server, add these few liners

  __theFormPostCollection.length = 0;
        __theFormPostData ="";
        WebForm_InitCallback();
        //Now...do the callback with your method
        CallServer("", "");

Then second issue is that updated ViewState (serialized __VIEWSTATE string) is not sent along with the callback response. This means that you can get out of the sync after you've done the previous hack to send changes in form post data to the server. You do a few callbacks and then for any reason, a standard postback, your viewstate at the client does not match what it should be as __VIEWSTATE contains the original viewstate when page was rendered from the server last time. Basically by default, what is sent with the callback response is defined in GetCallBackResult. There is also a nice hack you could do, to force to get the serialized ViewState down

    Public Function GetCallbackResult() As String Implements System.Web.UI.ICallbackEventHandler.GetCallbackResult

        'Save state with PageStatePersister and place it to Page.ClientState
        Dim mi As System.Reflection.MethodInfo = GetType(Page).GetMethod("SaveAllState", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic)
        mi.Invoke(Me, Nothing)

        'Get serialized viewstate from Page's ClientState
        Dim stateProp As System.Reflection.PropertyInfo = GetType(Page).GetProperty("ClientState", Reflection.BindingFlags.Instance Or Reflection.BindingFlags.NonPublic)
        Dim state As String = stateProp.GetValue(Me, Nothing)

        Return returnValue & ";" & state

    End Function

Then in the callback handler at js

function ReceiveServerData(rValue)
    {  
        var data;
        data=rValue.split(";");
        document.getElementById("ResultsSpan").innerHTML = data[0];   
           
        document.getElementById('__VIEWSTATE').value=data[1];
    }

This works fine except that I've had to disable event validation by adding EnableEventValidation="False" on the @Page directive.

5/28/2008 2:29:13 AM Published by FengLiN Category ASP.NET Comments 0 Views (217)
Name

Web site

Are you human? Enter the verify code below.

Comment