ViewState virker ikke ved brug af AJAX
Hej Eksperter.Dette spørgsmål er en forlængelse af et tidligere indlæg, hvor jeg forsøgte at finde frem til, hvorfor jeg ikke kan arbejde med ViewStates sammen med AJAX. Jeg synes nu at jeg er blevet lidt klogere på hvad der sker, og kan derfor opstille et bedre eksempel, der forhåbentligt kan hjælpe jer til at hjælpe mig :)
Kort og godt kan jeg ikke få ViewStates til at virke i min WebPart - de data jeg indsætter når jeg foretager et AJAX kald, er ikke tilgængelige ved næste AJAX kald. I følge Microsoft (jf. http://msdn.microsoft.com/msdnmag/issues/07/09/CuttingEdge/), er der ikke stor forskel på applikationens LifeCycle ved et PostBack og et AJAX kald;
"Everything is the same in the AJAX and ASP.NET postbacks, except the implementation of the rendering stage"
Men hvis man afvikler mit fine eksempel nedenfor, vil man se, at et AJAX kald kun resulterer i, at følgende metoder bliver afviklet:
- LifeCycle()
- OnInit()
- TrackViewState()
- OnLoad()
- RaiseCallbackEvent()
- getCallbackResult()
Nåh, altså ikke helt som forventet. SaveViewState() bliver ikke kaldt. Nåh, men skidt, for det gør TrackViesState, og det betyder, at data indsat i vores ViewState herefter, vil blive gemt, når jeg kalder SaveViewState(). Så i min OnLoad() metode kan jeg nu prøve at gemme noget data i mit ViewState og gemme det manuelt ved at kalde SaveViewState(). Men IGEN bliver jeg skuffet, for det er nøjagtig lige så tomt som det var før.
Jeg er dybt forvirret. Jeg har brugt rigtig lang tid på at blive klog på, hvorfor det her ikke virker, og det har da givet mig et glimrende indblik i livscyklussen for en WebPart. Men det hjælper ikke helt så meget, når de opnåede resultater, ikke stemmer overens med Microsofts dokumentation.
Kan I hjælpe? På forhånd tak :o)
------------------------------------------
Source code til mit LifeCycle eksempel:
------------------------------------------
[DefaultProperty("Text"),
ToolboxData("<{0}:LifeCycle runat=server></{0}:LifeCycle>"),
XmlRoot(Namespace = "LifeCycle")]
public class LifeCycle : WebPart, ICallbackEventHandler, IPostBackDataHandler
{
private string log;
private Button cmdButton;
public LifeCycle()
{
this.log = "\n LifeCycle()";
this.cmdButton = new Button();
}
protected override void OnInit(EventArgs e)
{
this.log += "\n OnInit()";
base.OnInit(e);
}
protected override void TrackViewState()
{
this.log += "\n TrackViewState()";
base.TrackViewState();
}
protected override void CreateChildControls()
{
this.log += "\n CreateChildControls()";
this.cmdButton = new Button();
this.cmdButton.Text = "Do PostBack";
this.cmdButton.Width = Unit.Pixel(100);
this.cmdButton.Height = Unit.Pixel(20);
this.cmdButton.Click += new EventHandler(this.cmdButtonClick);
this.Controls.Add(cmdButton);
}
protected override void LoadViewState(object savedState)
{
this.log += "\n LoadViewState()";
base.LoadViewState(savedState);
}
// From IPostBackDataHandler
public bool LoadPostData(string postDataKey, System.Collections.Specialized.NameValueCollection postCollection)
{
this.log += "\n LoadPostData()";
return true;
}
protected override void OnLoad(EventArgs e)
{
this.log += "\n OnLoad()";
string caller = this.Page.ClientScript.GetCallbackEventReference(this, "'argVal'", "inform", "'ctxVal'", true);
string ajax = "";
ajax += "function invokeInformer() {" + caller + "}";
ajax += "function inform(result, context) { alert('Res: ' + result); }";
this.Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "MyCallBackScript", ajax, true);
base.OnLoad(e);
}
// From IPostBackDataHandler
public void RaisePostDataChangedEvent()
{
this.log += "\n RaisePostDataCHangedEvent()";
}
protected override void OnPreRender(EventArgs e)
{
this.log += "\n OnPreRender()";
base.OnPreRender(e);
}
protected override object SaveViewState()
{
this.log += "\n SaveViewState()";
return base.SaveViewState();
}
// Same as Render()
protected override void RenderWebPart(System.Web.UI.HtmlTextWriter writer)
{
this.log += "\n RenderWebPart()";
writer.WriteLine(this.log.Replace("\n", "<br>"));
writer.WriteLine("<br><br><input type='button' value='AJAX Call' onclick='invokeInformer()'>");
base.RenderWebPart(writer);
}
public override void Dispose()
{
this.log += "\n Dispose()";
base.Dispose();
}
protected override void OnUnload(EventArgs e)
{
this.log += "\n OnUnload()";
base.OnUnload(e);
}
#region ICallbackEventHandler Members
// AJAX call back result is being fetched using this method
public string GetCallbackResult()
{
return this.log + "\n GetCallbackResult()";
}
// This method is call when the AJAX (JS) function is invoked
public void RaiseCallbackEvent(string eventArgument)
{
this.log += "\n RaiseCallbackEvent()";
}
#endregion
private void cmdButtonClick(object sender, System.EventArgs e)
{
this.log += "\n cmdButtonClick()";
this.cmdButton.Text = "Clicked";
}
}