Showing posts with label back. Show all posts
Showing posts with label back. Show all posts

Monday, March 26, 2012

Integration with ViewState

Sometimes, I store information in the viewstate statebag. Since this information goes back to the server on a roundtrip, I have access to the information. If I want to send that same information back to the server, how should I handle the situation where the information is stored in the statebag? Should I go back and use hidden fields that javascript can get at? is there some type of way to reach into the statebag from the client-side javascript? I realize that the statebag is not considered to be secure so would it be possible to include some type of javascript decoder in atlas to get at values in the statebag?
WallyHi Wally,
I didn't see any viewstate support at the moment, and I think Microsoft is thinking of AJAX methods as I. If you try the Atlas web controls you will see that there is no Click event for the server.

I don't think we'll be creating solutions to change view state from the client. Often times this is not possible - view state may be encrypted. More often though, its simply not efficient to try and parse that content using script.

However, server controls that preserve the server-based programming model, while providing richer experience will use view state creatively, to provide the right behavior if an ajax-style page does need to postback for some reason.

Saturday, March 24, 2012

Invalid postback or callback argument on page back

Hello,

I ran into this by placing myselft as the final user of my web application.

I have several pages using AJAX controls (update panel, autocomplete extender, etc), and I noticed that when I have redirect to another page, and till there, using the IE back page button, the previous page is loaded and then a message error is prompt (Invalid postback or callback argument)

By now I'm disabling the - PageEventValidation - but, actually I'd like to solve it in a better way.

Thanks in advance guys,

Hi Manotas,

Do you have databound controls, like a DropDownList or a GridView? If so, did you make sure they are initialized in a block that checks for inital page load?

For example:

if (false == Page.IsPostBack)

{

// code for initial load goes here

}

else

{

// code for PostBack from same page goes here

}

Pete


Hi Peter,

Thanks for reply.
I do have bound control. After reading at your post, I checked the initialization of my databound controls.
I realized that there is a gridview which I am initializing at first loading but not during postbacks, however, when the page is reload by using the back button on the browser, there is a postback and maybe is there where is my error. The thing is that I'm not sure what kind of validation I could do there since I wouldn't like to change the data of the parameters used on the select's datasource ...

I tried to find a pattern on the error... I must correct what I said about the invalid postback after the page's loading. In fact, I realized that it was happening only sometimes, and only when I was clicking on certain linkbuttons, on the other side, if I click on others buttons I was not having any problem at all. Also, as you mentioned the fact of look at databoud controls, I began testing and I found that I was getting the error only when I was turning back to the page and my gridview was visible (I'm using a multiview control, and the gridview I mentioned above is contained in its view).

By now, I restored the PageEventValidation and added at the update panel a postback trigger for the controls which are making visible my gridview.

Since I'm not receving the error message anymore... let's see I'l heard about it later...

Cheers

Invoke JavaScript method after partial post back

  Hi,
 Im trying to invoke a javascript method after a partial update has occured from an update panel. I found some code for which i beleive works for an old version, but it doesn't work for the released version.
 Does anyone know how i can invoke a javascript method after post back?
 
 
1 function afterPostback()2 {10 }1112 function PageRequestManagerPropertyChanged(sender, args)13 {14if (args.get_propertyName() =="inPostBack")15 {16if (!$object("_PageRequestManager").get_inPostBack())17 afterPostback();18 }19 }2021 function pageLoad()22 {23 $object("_PageRequestManager").propertyChanged.add(PageRequestManagerPropertyChanged);24 }

You can handle _endRequest to do that. Try something like this:

var prm = Sys.WebForms.PageRequestManager.getInstance();prm.add_endRequest(afterPostback);function afterPostback(sender, args){}

Note: This code has to be placed below the ScriptManager control.


Brilliant, that works a treat.

Thanks

Invoking post back on page load (an easy question - but I couldnt find the answer!)

What I want to do is very easy, so I'm very frustated to have to ask this on the forum - but I've been searching the net for 2 days now and couldn't figure out the answer in a nice "Atlas" way of doing things.

The behaviour I want is exactly what pageflakes.com does when you go their home page: Display a "loading" message while the data is being loaded.

Icanput an UpdatePanel with my data controls in it.

Icanput an UpdateProgress control to show the "loading" message.

What Idon'tknow, is how to make it so that the client-side page will invoke a postback immidietly after loading, i.e. call the BindData() function on the server-side page.

I would prefer a declerative solution to this, or at least, a very short Javascript code (but I'm not too picky - first priority is to get the basic functionality :-) )

Little help?

Is the question unclear? or is it not as easy as I thought? Google does it, pageflakes does it, so I know it's possible...

This is what I have so far.

The javascript pageLoad() function runs properly after loading, and it does indeed call the server (and is capable of returning data to the page, I checked with js alerts)- but the label in the updatepanel doesn't change.

In addition, I received the wierdest error -must have <head runat="server"> You might notice I've added the runat=server to the header, though it still doesn't work.

Default2.aspx

<%

@.PageLanguage="VB"AutoEventWireup="false"CodeFile="Default2.aspx.vb"Inherits="Default2" %>

<

html>

<

headrunat="server"><title>ddd</title>

</

head>

<

body><formid="MainForm"runat="server"><atlas:ScriptManagerID="sm"runat="server"EnablePartialRendering="true"/><atlas:UpdatePanelID="UpdatePanel1"Mode="Always"runat="Server"><ContentTemplate><asp:LabelID="Label1"runat="server"Text="Label"></asp:Label></ContentTemplate></atlas:UpdatePanel></form><scriptlanguage="javascript">function pageLoad()

{

GetServerTime();

}

function GetServerTime()

{

var message ='';var context ='';

<%=sCallBackFunctionInvocation%>

}

function ShowServerTime(timeMessage, context) {

alert(

'The time on the server is:\n' + timeMessage);

}

function OnError(message, context) {

alert(

'An unhandled exception has occurred:\n' + message);

}

</script>

</

body>

</

html>

Default2.aspx.vb

Partial

Class Default2Inherits System.Web.UI.PageImplements ICallbackEventHandlerPublicFunction GetCallbackResult1()AsStringImplements System.Web.UI.ICallbackEventHandler.GetCallbackResultMe.Label1.Text ="Binded, at last"Return ("The server time is " &Date.Now.ToString)EndFunctionPublicSub RaiseCallbackEvent1(ByVal eventArgumentAsString)Implements System.Web.UI.ICallbackEventHandler.RaiseCallbackEventEndSubPublic sCallBackFunctionInvocationAsStringProtectedSub Page_Load(ByVal senderAsObject,ByVal eAs System.EventArgs)HandlesMe.Load

sCallBackFunctionInvocation = _

Me.ClientScript.GetCallbackEventReference(Me,"message","ShowServerTime","context","OnError",True)EndSub

End

Class
Sorry, I havent got an asnwer for you, but Im trying to do the same thing.

I have built a query screen that connects to one of my web services and nicely brings back a list of results using atlas, then when you click on one of the results it loads the details page which then shows you the full details of the selected item.

The thing is when the details page is being loaded I have to call 4 web services to get the required data back, and this can take anything upto 8seconds to do. During this time the first screen is just locked whilst the details page is being built in the background.

What i want is the details page to show straight away - but empty, and my UpdateProgress to show a nice ticking loading sign.

As you said, PageFlakes has a nice example of this working, but I cant seem to replicate it.

I have tried putting my server side code in the page load event, then setting the trigger for the updatepanels to page load, but it doesnt seem to like this.

if you find an answer let me know!

stuart

Eureka !Idea [Idea]

With the help ofMatt Gibbsfrom Microsoft (ScottGuthrie refered me to him) I managed to do it.

Matt's answer to my question was a little different from how I ended up doing it, so I'll show both.

First, my crude way... The trick was not to useICallbackEventHandlerbutIPostBackEventHandler (I didn't even know it existed before Matt told me).

ASPX page:

<%@. Page Language="VB" AutoEventWireup="false" CodeFile="Default4.aspx.vb" Inherits="Default4" %><html><head runat="server" > <title>ddd </title></head><body> <form id="MainForm" runat="server"> <atlas:ScriptManager ID="sm" runat="server" EnablePartialRendering ="true" /> <atlas:UpdatePanel ID="UpdatePanel1" Mode="Always" runat="Server"> <ContentTemplate> <asp:Label ID="Label1" runat="server" Text="Label"></asp:Label> </ContentTemplate> </atlas:UpdatePanel> <atlas:UpdateProgress ID ="UpdateProgress1" runat="server"> <ProgressTemplate> Loading... </ProgressTemplate> </atlas:UpdateProgress> </form> <script language="javascript"> function pageLoad() { GetServerTime(); } function GetServerTime() { var message = ''; var context = ''; <%=sCallBackFunctionInvocation%> } function ShowServerTime(timeMessage, context) { alert('The time on the server is:\n' + timeMessage); } function OnError(message, context) { alert('An unhandled exception has occurred:\n' + message); } </script> </body></html>


This is the code behind:
 PartialClass Default4Inherits System.Web.UI.Page'Inherits System.Web.UI.WebControls.WebControlImplements IPostBackEventHandlerPublic sCallBackFunctionInvocationAs String Protected Sub Page_Load(ByVal senderAs Object,ByVal eAs System.EventArgs)Handles Me.Load sCallBackFunctionInvocation = _Me.ClientScript.GetPostBackEventReference(Me,"message")' Me.ClientScript.GetCallbackEventReference(Me, "message", "ShowServerTime", "context", "OnError", True)End Sub Public Sub RaisePostBackEvent1(ByVal eventArgumentAs String)Implements IPostBackEventHandler.RaisePostBackEvent System.Threading.Thread.Sleep(2000)Me.Label1.Text ="Binded, at last"End SubEnd Class


Now, this is what Matt wrote, I see how it's better because it's easier to apply later to any application, but I couldn't create it:

1) create a custom control that inherits from WebControl, let's call it Loader

2) In the code for Loader, have it override the Render method and call GetPostBackEvent reference. It should render out clientside script for the pageLoad function that contains the result of the call to GetPostBackEventReference.

3) The Loader control should also implement the IPostbackEventHandler interface. In the RaisePostBackEvent method call DataBind on the page.

4) Now you can use the control on your page to have the UpdatePanel refreshed when the page loads.


Here is your sample packaged as a custom control.

The Page:

<%

@.PageLanguage="C#" %>
<%@.RegisterTagPrefix="my"Namespace="Samples" %>
<!DOCTYPEhtmlPUBLIC"-//W3C//DTD XHTML 1.0 Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<scriptrunat="server">
</script>
<htmlxmlns="http://www.w3.org/1999/xhtml">
<headrunat="server">
<title>Untitled Page</title>
</head>
<body>
<formid="form1"runat="server">
<div>
<atlas:ScriptManagerID="sm"runat="server"EnablePartialRendering="true"/>
<atlas:UpdatePanelID="UpdatePanel1"Mode="Always"runat="Server">
<ContentTemplate>
<asp:LabelID="Label1"runat="server"Text="Label"></asp:Label>
</ContentTemplate>
</atlas:UpdatePanel>
<atlas:UpdateProgressID="UpdateProgress1"runat="server">
<ProgressTemplate>
Loading...
</ProgressTemplate>
</atlas:UpdateProgress>
<my:Loaderrunat="server"/>
</div>
</form>
</body>
</html>

And the custom control:

using

System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

namespace

Samples {
publicclassLoader : System.Web.UI.WebControls.WebControl,IPostBackEventHandler {public Loader() {
}protectedoverridevoid Render(HtmlTextWriter writer) {
writer.Write("<script type=\"text/javascript\" >\r\n");
writer.Write("function pageLoad() {\r\n");
writer.Write("alert(\"waiting\");\r\n");
writer.Write(this.Page.GetPostBackEventReference(this));
writer.Write("}\r\n");
writer.Write("</script>\r\n");
}publicvoid RaisePostBackEvent(string eventArgument) {
Label label =this.Page.FindControl("Label1")asLabel;
if (label !=null) {
label.Text ="updated at last";
}
}
}
}
Well done - that has helped me a lot. I got it all working with the user control setup.

I just found out (late, huh?) that search engine spider bots will not be able to "see" the information on any page that uses this, because this uses post backs.

If there's no way to do this and still have the search engines find it, I'll have to give it up. Pitty - this was a very nice UI solution.


I just found this thread - how do I keep the page from posting back in a loop ? It does in fact do a postback after page_load has fired, but it keeps doing it...
It shouldn't be doing it. Go over the code again, see if you can debug it. If not, post it and we'll take a look.

@.BitShift:

The problem might be that you moved the Loader control within the UpdatePanel?? I did that for another reason and I got exactly what you described.

Here is the problem I'm facing:

Yes the sample code that Matt provided does work, however, I want to move my Loader control into the UpdatePanel, so that the first it renders it does the AsyncPostback, and then on the second render it display the real control that I want to load. This avoid the need for triggers and everything in centralized in my Loader control. I too thought this would be easy, but alas not. :(

here is what I have (simplified):

<asp:UpdatePanelID="UpdatePanel1"UpdateMode="Conditional"ChildrenAsTriggers="true"runat="Server">
<ContentTemplate>
<cc1:LoaderID="Loader1"ReportPath="/Analysis Reports Test/Report1"runat="server"/>
</ContentTemplate>
</asp:UpdatePanel>

CodeBehind of Loader.cs:

protectedoverridevoid Render(HtmlTextWriter writer)
{
if (!bPostback)
{
writer.WriteLine("Loading...");
writer.WriteLine("<script type=\"text/javascript\" >");
writer.WriteLine("Sys.Application.add_load(" +this.ClientID +"_Load);");
writer.WriteLine("function " +this.ClientID +"_Load() {");
writer.WriteLine(this.Page.ClientScript.GetPostBackEventReference(this,""));
writer.WriteLine("}");
writer.WriteLine("</script>");
}
else
{
this.Controls[0].RenderControl();
}
}bool bPostback =false;
publicvoid RaisePostBackEvent(string eventArgument)
{
System.Diagnostics.Debug.WriteLine("Postback from : " + eventArgument);
bPostback =true;
MyCustomControl c =new MyCustomControl();
this.Controls.Add(c);
}

When I do this, I lose the AsyncPostback of the UpdatePanel, it does a full page postback. I have to explicitly set the AsyncPostBackTrigger even though it is a child control and the ChildrenAsTriggers="true"?!?

Even at that I am still having another issue, that my page has mulitple of these loaders and all UpdatePanels should be triggered only once. Unfortunately this is not the case. I have the UpdateMode set to Conditional however with the AsyncTrigger it still appears to trigger multiple updates. With 2 UpdatePanels and Loader controls, I get 3 postbacks:
1) Loader2
2) Loader1
3) Loader2

Any helpwould be greatly appreciated.

Perry


I got this problem also, and it's been a long time this thread gone unanswered.

Could somebody gives me exact explanation about how the postback sequence in favor of MS AJAX? It seems to me it got mixed up and the order is different on web form without AJAX.

regards,

Eriawan