targetting an update panels post back - c#

I was wondering if there was a way to determine when a post-back occured in an update panel. Looking for something similar to (IsPostBack).
I'm using ASP.NET, with C#.

Use ScriptManager.IsInAsyncPostBack:
if (ScriptManager.GetCurrent(this).IsInAsyncPostBack)
{
// In a request from an update panel
}
else {
// Not in a request from an update panel
}

Try IsCallBack - should do the trick.

Are you looking for a way to determine this on the server side or client side? There is a server-side UpdatePanel load event that you can override I think. Client side can be done by following these instructions - http://forums.asp.net/t/1254188.aspx

If any update occured in a page , you can find which updatepanel(s) is caused postback.
It is possible by javascript
Sys.WebForms.PageRequestManager.getInstance().add_pageLoaded(PageLoadedHandler);
function PageLoadedHandler(sender, args)
{
//this event is raised after all content on the page is refreshed.
//Whether it was refreshed bacause of a synchronous or asynchronous
if (TargetPanelWasUpdated(args.get_panelsUpdated(), "UpdatePanel1") )
{
//do stuff
}
}
function TargetPanelWasUpdated(panelsUpdated, targetPanelID)
{
// NOTE: Multiple UpdatePanels will be included in the list unless
// you set each panel's UpdateMode property to Conditional.
var matched = false;
for (i = 0 ; i < panelsUpdated.length; i++) {
if (panelsUpdated[i].id == targetPanelID) {
matched = true;
break;
}
}
return matched;
}

Related

Is there a way to check if page was reloaded with WebDriver (C#)?

In some of my projects to correctly save forms user needs to perform click on "Save" or "Save changes" button. That click cause whole page to reload (changes done will be visible on page after that reload), but if something is wrong validation will stops page from reloading.
I want to create a simple assertion to check if that page was reloaded, if not my test will fail. I tried to use this code:
public bool WasPageRefreshed(float seconds)
{
DriverLocal.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.MinValue);
string getReadyState = "return document.readyState;";
for (int i = 0; i < 10; i++)
{
string readyState = GetJsExecutor().ExecuteScript(getReadyState) as string;
if (readyState != "complete")
return true;
Thread.Sleep(TimeSpan.FromMilliseconds(seconds / 10));
}
DriverLocal.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(60));
return false;
}
I use it in Assert.True() to check if page was reloaded but it doesn't work always (I can use it 5 times on same form - 3 times its ok, 2 times test will fail).
Is there a way to upgrade it to work correctly in 100% of usage?
Or maybe there is another way to check if page was reloaded?
For Webpage load, there is unfortunately no one size fits all solution. Every situation varies. How you wait in your automation suite is very critical. Explicit waits are recommended way of waiting, instead of using Javascript options, you can just wait for a new element after the page load or wait for invisibility of certain element that tells you that the page is loaded
new WebDriverWait(driver, TimeSpan.FromSeconds(timeOut))
.Until(ExpectedConditions
.ElementExists((By.Id("new Element Id"))));
or
new WebDriverWait(driver, TimeSpan.FromSeconds(timeOut))
.Until(ExpectedConditions
.InvisibilityOfElementLocated((By.Id("old Element Id"))));
You can check ExpectedElements docs here
There may be some Ajax call works asynchronously. You can wait until ajax call finished, then do your case, see this:
public void WaitForAjax()
{
while (true) // break if ajax return false
{
var ajaxIsComplete = (bool)(driver as IJavaScriptExecutor).ExecuteScript("return jQuery.active == 0");
if (ajaxIsComplete)
break;
Thread.Sleep(100);
}
}
As my opinion, you better use SeleniumWait instead of Sleep. Try this
public bool WasPageRefreshed(double seconds)
{
WebDriverWait wait = new WebDriverWait(DriverLocal, TimeSpan.FromSeconds(seconds));
wait.PollingInterval = TimeSpan.FromSeconds(1);
string getReadyState = "return document.readyState;";
try
{
wait.Until(d =>
{
string readyState = GetJsExecutor().ExecuteScript(getReadyState) as string;
if (readyState == "complete")
return true;
});
}
catch (Exception)
{
}
return false;
}
I suggest you Wait for a specific element that marked the status of a refreshed page.

Detect if an UpdatePanel is affected by an Update() method call

I use several UpdatePanel in the same page, with UpdateMode = Conditional, and i'm trying to find a clean way to only execute code behind related to the UpdatePanel which will be updated.
So, when i'm calling a __doPostBack from JS, i am able, on the code behind side, to detect the name of the UpdatePanel which is asked to refresh by using Request["__EVENTTARGET"] (which gives me the ClientID of the UpdatePanel).
But when i'm calling the UpdatePanel1.Update() method (from server side), is there a built-in way to know if an Update panel is about to be updated ?
I am posting here to myself my temporary (?) answer.
Because there is apparently no way to detect if a UpdatePanel is being updated (when UpdatePanel is updated by code behind), i've created a class which handle the update, and put some data in session, so, this same class will be able to tell if the UpdatePanel is updating.
So, I doesn't call anymore directly UpdatePanel.Update(), but UpdatePanelManager.RegisterToUpdate().
The method bool isUpdating() is able to tell if an UpdatePanel is updating, and can tell automatically if an updatePanel is Updating though Javascript using HttpContext.Current.Request["__EVENTTARGET"].
Note: isUpdating() need to be used within the OnPreRender Page event.
public static class UpdatePanelManager
{
private const string SessionName = "UpdatePanelRefresh";
public static void RegisterToUpdate(System.Web.UI.UpdatePanel updatePanel)
{
updatePanel.Update();
if (HttpContext.Current.Session[SessionName] == null)
{
HttpContext.Current.Session[SessionName] = new List<string>();
}
((List<string>)HttpContext.Current.Session[SessionName]).Add(updatePanel.ClientID);
}
public static bool IsUpdating(System.Web.UI.UpdatePanel updatePanel)
{
bool output = false;
// check if there is a JavaScript update request
if (HttpContext.Current.Request["__EVENTTARGET"] == updatePanel.ClientID)
output = true;
// check if there is a code behind update request
if (HttpContext.Current.Session[SessionName] != null
&& ((List<string>)HttpContext.Current.Session[SessionName]).Contains(updatePanel.ClientID))
{
output = true;
((List<string>)HttpContext.Current.Session[SessionName]).Remove(updatePanel.ClientID);
}
return output;
}
public static bool IsUpdatingOrPageLoading(System.Web.UI.UpdatePanel updatePanel, System.Web.UI.Page page)
{
bool output = false;
if (!page.IsPostBack || IsUpdating(updatePanel))
output = true;
return output;
}
}

Identify during Page.Load if Button click event is going to be handled

I have ASPX web page which has a Button on it. Once user click this button, request is submitted to server and button click event handler is executed.
I have some logic that must reside on Page.Load, but this logic depends if request has been submitted by button click. Based on page life cycle event handlers executes after Page Load.
Question: How in Page load I can find out what event handlers are going to be executed after Page Load?
#akton's answer is probably what you SHOULD do, but in case you want to go off the reservation and determine what is causing a postback early on in the lifecycle, you can interrogate the postback data to determine what was clicked. This will NOT give you what actual functions/handlers will be executed during event handling, however.
First, if something other than a Button/ImageButton caused the postback, the ID of the control will be in __EVENTTARGET. If a Button caused the postback, there is something "cute" ASP.NET does: it ignores all other buttons so that only the clicked button shows up on the form. An ImageButton is a little different, because it will send coordinates. A utility function you can include:
public static Control GetPostBackControl(Page page)
{
Control postbackControlInstance = null;
string postbackControlName = page.Request.Params.Get("__EVENTTARGET");
if (postbackControlName != null && postbackControlName != string.Empty)
{
postbackControlInstance = page.FindControl(postbackControlName);
}
else
{
// handle the Button control postbacks
for (int i = 0; i < page.Request.Form.Keys.Count; i++)
{
postbackControlInstance = page.FindControl(page.Request.Form.Keys[i]);
if (postbackControlInstance is System.Web.UI.WebControls.Button)
{
return postbackControlInstance;
}
}
}
// handle the ImageButton postbacks
if (postbackControlInstance == null)
{
for (int i = 0; i < page.Request.Form.Count; i++)
{
if ( (page.Request.Form.Keys[i].EndsWith(".x")) || (page.Request.Form.Keys[i].EndsWith(".y")))
{
postbackControlInstance = page.FindControl(page.Request.Form.Keys[i].Substring(0, page.Request.Form.Keys[i].Length-2) );
return postbackControlInstance;
}
}
}
return postbackControlInstance;
}
All that being said, if you can refactor your control/page to delay execution, your code will be much cleaner/more robust if you use the paradigm suggested by #akton.
There may be a better solution to the problem. Do you want the code to only run when the page is first loaded and you are using postbacks? If so check the Page.IsPostBack property. If the code does not need to run before other event handlers, move it to OnPreRender because it fires after event handlers.
These helped me a lot: I wanted to save values from my gridview, and it was reloading my gridview /overriding my new values, as i have IsPostBack inside my PageLoad.
if (HttpContext.Current.Request["MYCLICKEDBUTTONID"] == null)
{ //Do not reload the gridview.
}
else { reload my gridview. }
SOURCE: http://bytes.com/topic/asp-net/answers/312809-please-help-how-identify-button-clicked

How set null a variable from session when the user leaves a page

I want to set one variable from session to null
Session["my_variable"] = null;
I tried with OnUnload like this
protected override void OnUnload(EventArgs e)
{
base.OnUnload(e);
Session["my_variable"] = null;
}
but it doesn't work right, it sets the variable while the user is on page but I want to set it null whet is leaves page
Your function/event will be fired as soon as page is served to client, because it is a server side event. You might use Viewstate but still it cannot be implemented as navigation does not send any event to server while clientside scripting can help.
This functionality can be implemented by java script on-unload event. You have to send a request to server to remove or put null in particular session value ( as session is key-value object ). Your question is best explained at Asp Forum
But be careful. This event might fire only on navigation by some browser. you might have to do some code-work to implement what you want.
Why dont you are making use of ViewState inplace of Session Variable.
viewstate variable automatically get removed once you leave page
here is example how to use it
protected DataSet MyDataSet
{
get
{
if(ViewState["MyDataSet"] == null)
{
return null;
}
else
{
return (DataSet)ViewState["MyDataSet"];
}
}
set
{
ViewState["MyDataSet"] = value;
}
}

Browser Helper Object and AJAX

I am wondering if BeforeNavigate2 or DocumentComplete events should fire on pages with AJAX. For example google maps. When I put something in addressbar everything is ok, but when I move the map and resizing it nothing happens (DocumentComplete and BeforeNavigate2 does not fire), but data is sent to and from Internet.
The a in ajax stands for asynchronous. These events fire in response to synchronous methods completing. Since an asynchronous request can be made at any time the browser has no way of knowing when they are all completed.
I think you need to handle ajax request and you can Handle with DownloadBegin and DownloadComplete Event.
In Code:
public int SetSite(object site)
{
if (site != null)
{
webBrowser = (WebBrowser)site;
webBrowser.DownloadComplete += new DWebBrowserEvents2_DownloadCompleteEventHandler(DownloadComplete);
webBrowser.DownloadBegin += new DWebBrowserEvents2_DownloadBeginEventHandler(DownloadBegin);
}
else
{
webBrowser.DownloadComplete += new DWebBrowserEvents2_DownloadCompleteEventHandler(DownloadComplete);
webBrowser.DownloadBegin += new DWebBrowserEvents2_DownloadBeginEventHandler(DownloadBegin);
webBrowser = null;
}
return 0;
}
Events:
private void DownloadBegin()
{
MessageBox.Show("Download Begin");
}
private void DownloadComplete()
{
MessageBox.Show("Download Complete");
}
it's work for me.
I monitor download begin and download complete events to process pages which include ajax codes.
Also need program logic to control the flow, e.g.. set/check flags.

Categories

Resources