UpdateControls 1.1: Bug Fixes and UpdateAction

The first revision to the UpdateControls ASP.NET AJAX server controls package including bug fixes for reported bugs on UpdateHistory and AnimatedUpdatePanel, as well as the addition of another control, UpdateAction.

I posted an initial version of my UpdateControls package - a set of ASP.NET AJAX server controls that build on the partial rendering model to extend the model beyond basic page updates. The package consisted of the UpdateHistory and the AnimatedUpdatePanel controls. Theres been quite a few downloads of it, and quite a few comments as well, including bug reports.

If this is the first time you're reading about this, check out my previous blog post on this first and then come back here to see whats changed. Various bugs that have been reported have been fixed including:

  • Support for installing to the GAC: The assembly is now signed, and you can add to the GAC if you like, or leave it in the bin directory of your Web application if you can't or don't want to.
  • Support for master page and user control scenarios: The UpdateHistory control now works in either of those scenarios. Remember you can still only have one UpdateHistory control on your page.
  • Support for bookmarking: Bookmarking was broken ... doh! The ability to bookmark and return to specific views of a page is a key scenario for the UpdateHistory control, and is now fixed.
  • Support for debug ASP.NET AJAX scripts: The UpdateHistory control is non-visual, however the framework expects there to be a matching element as it causes post-backs upon back/forward navigation, so I've made minor changes, so as to avoid the debug assert raised by the framework.

In addition to fixing the bugs, I've added a new control to the pack in v1.1 - UpdateAction. As the name might suggest, it enables you to perform a small selection of actions as part of a partial rendering or async postback. Specifically it currently allows you to show a message, set focus on a particular control, or scroll the page to a particular control. The usage is straightforward, and the download contains a sample. Here are the basics:

Step 1 is to add an instance of this control to your page.

<nStuff:UpdateAction runat="server" id="updateAction" />

Step 2 is to call APIs on this control from appropriate event handlers on the page. In the samples I have a DropDownList control, and demonstrate conditionally performing certain actions when a certain item is selected. To that end, you might have something like this:

private void DropDownList1_SelectedIndexChanged(object sender, EventArgs e) {
    if (DropDownList1.SelectedIndex == 2) {
        updateAction.ShowMessage("You selected the magic item");
        updateAction.SetFocus(someControl);
        updateAction.ScrollTo(someControl, ScrollOffset.Bottom);
    }
}

Thats basically it. Do you think these are useful actions? Any others that are interesting?

You can download the control package, sources and associated samples here for free. I have a couple more ideas in mind for a future iteration of this package, and suggestions are always welcome, in addition to continued feedback on the existing controls.

Posted on Friday, 4/13/2007 @ 4:14 PM | #ASP.NET


Comments

33 comments have been posted.

daniel

Posted on 4/13/2007 @ 7:40 PM
good job! Here's a question, does updateaction invoke postback?

Steve

Posted on 4/13/2007 @ 7:40 PM
Error 1 Cryptographic failure while signing assembly 'D:\UpdateControls\UpdateControls\obj\Debug\nStuff.UpdateControls.dll' -- 'Error reading key file 'd:\UpdateControls\UpdateControls.snk' -- The system cannot find the file specified. ' UpdateControls

Nikhil Kothari

Posted on 4/13/2007 @ 9:48 PM
Daniel - UpdateAction doesn't cause a postback... thats not the use model. The idea is that you have some other control that causes a postback, eg. a button... and during that postback parts of the page get updated (by virtue of UpdatePanel controls). If in addition to updating parts of the page, your want to show a message, or perform some other action, then you can use UpdateAction to perform those actions when the page does get updated back on the client.

Steve - The snk file I used to sign the assembly is intentionally not part of the package. Generally most people will just use the built dll that is in the bin directory of the site. If you do want to rebuild the sources, you'll need your own key file, so its doesn't get mixed up with the assembly I build and hand out from my site.

Aditya

Posted on 4/14/2007 @ 2:00 PM
Fabulous job nikhil. I have a question though, can I use it for commercial purpose? Thanks.

Chad

Posted on 4/14/2007 @ 2:21 PM
Great work. The UpdateAction panel is a great addition. When you have a chance, can you address Aditya's question about its use on commercial sites as I'd like to use it on a site I am working on now. Thanks again.

Chad
www.wtfShouldIDo.com

Steven

Posted on 4/15/2007 @ 8:35 PM
Header of files reads:

// You are free to:
// - copy, distribute, display, and perform the work
// - make derivative works
// - make commercial use of the work
// Under the following conditions:
// Attribution. You must attribute the original work in your
// product or release.
// Share Alike. If you alter, transform, or build upon this work,
// you may distribute the resulting work only under
// a license identical to this one.

Lance

Posted on 4/17/2007 @ 8:10 AM
When I pass an anchor in the URL, firefox and IE6 work perfectly, but IE7 appears to start moving to the anchored page and then stops on the main page, displays the "#" but drops the anchor name... am I missing a step?

Ty

Posted on 4/17/2007 @ 2:29 PM
hi nikhil,
i'm using DotNetNuke 4.41 and 4.5. i've creating a demo DNN module using your SlideMaster example. i took out the UpdateHistory stuff and put the script code in the serverside. in this example, all that happens is the contentPanel literal gets renders twice. asp.ajax works fine but i can't get any of your controls to work. what could be the problem?

Jerome

Posted on 4/18/2007 @ 2:14 AM
Hi all,
What is the best way to deploy those examples locally?

In VS2005, I created a new project : ASP.NET AJAX-Enabled Web Application.
I added Sample.master, Default.aspx, CrossFadeAnimation.aspx then the nStuff.UpdateControls dll in the References folder.
When I launch "Start debugging" (F5), the cross fade animation works fine.
But if I exit VS2005 and create a virtual directory to that project in IIS, I get the following error when accessing CrossFadeAnimation.aspx (in FF2 - Firebug) :

Sys.WebForms has no properties
nStuff_AnimatedUpdatePanel$initialize()ScriptResource.ax... (line 105)
Sys$Component$endUpdate()ScriptResource.ax... (line 2702)
Sys$Component$create(nStuff_AnimatedUpdatePanel(element), Object animation=Object, null, null, div#_ctl0_mainContent_mainUP_Container)ScriptResource.ax... (line 2856)
(no name)()CrossFadeAnimatio... (line 122)
_handler(Object _disposableObjects=[2] _components=Object, Object)ScriptResource.ax... (line 2503)
Sys$_Application$_doInitialize()ScriptResource.ax... (line 3792)
(no name)()ScriptResource.ax... (line 50)
[Break on this error] var prm = Sys.WebForms.PageRequestManager.getInstance();

Why do I have a different behavior ?
Something to do with UpdateControls.js apparently ?...
Thanks for your tips.

johnzered

Posted on 4/18/2007 @ 3:22 AM
Absolutely wonderful control! Thank you!
Though i have one question: is it possible to somehow remove any of the entries in the historycontrol? As it is now theres only a "AddEntry" method what I'm thinking of is a "RemoveEntry" mehtod

Cris

Posted on 4/18/2007 @ 10:03 AM
Nice...one question is how do you save 2 or more dropdownlist to history?

Gila

Posted on 4/18/2007 @ 11:25 AM
Hello Nikhil,
I’ve tried to use this control and everything works great on one page, however I have a gridview with hyperlink column that takes me to a detail page (master/detail on separate pages) and I was simulating back button to come back to master page. It also worked, but after coming back everything falling apart. It looks like it’s writing a correct history entry (I am checking the entry name), but it is not reflected in the address bar after the page is rendered. It looks like it keeps retrieving the same page (the last page before detail screen) when back button is pressed. Do you have any ideas on what I am doing wrong?

Erik

Posted on 4/19/2007 @ 4:38 AM
I have found a bug. I have included your UpdateHistory control in my project. The project is based on a Content Management System which uses Friendly Urls. Namely virtual urls such as httx://site.com/en/Development/UpdateHistory/. The file History.htm is placed in the root of the site httx://site.com/. When implementing history control on the page that has the path as above I get som problems. The UpdateHistory control tries to access history.htm from httx://site.com/en/Development/History.htm and that causes an error.

I have changed the line 174 in UpdateHistory.cs to EmptyPageUrl = "/History.htm";
Now it works great.

Thanks for this wonderful work.

Orlando Agostinho

Posted on 4/20/2007 @ 3:58 AM
Hi,

Great Work congratulations. I've just read a bit of 'Using Forms Authentication with ASP.NET AJAX', and i would like to know if it's any possibilty to add CAPTCHA functionality in that control.

Thanks a lot!

Dan

Posted on 4/22/2007 @ 1:02 PM
I use one or more radiobutton lists/dropdownlists and/or text fields to define the section criteria for a gridview with links to detail page in lots of places. I appreciate your efforts on making UpdatePanels viable.

Your latest code solves most of this problem, but one remains. Your example depends on the first entry in your dropdown being a label for the dropdown, not an actual selection so that your code doesn't update the history with the 0'th section index.

If my user changes the radiobutton/dropdown from the 1st entry to the 2nd and then back to the first, the gridview is return the the original version but a selection of a link in that grid followed by a back arrow, will show the 2nd version of the gridview not the first.

You can reproduce this on your samples, by selecting a technogy - seeing the result fill in - selecting the 'Select a technogy' - seeing the result clear - clicking the "created with Script#" - clicking the back button, then you will see the technology that you previously set and then cleared!

So I guess that when the user links from the gridview to a detail page, that detail page must now communicate back that all dropdown/radiobutton onselectionchanges until the after the next page render should be ignored.
Or can the page load capture the history state for when the OnNavigate is driven.

Am I confused or what? Thanks

swirek

Posted on 4/23/2007 @ 9:04 AM
Hi,
great stuff, your UpdateHistory works great, but I'm running into problems when running my application in IE7.
1. When displaying navigation history my views created with AddEntry method are named "Resource cannot be found.". I guess this is because of some validation IE7 makes to history entries. Is there any workaround for this?
2. If I go to another page in my app, all entries in history made with your control for previous page are erased, so that there is only one entry for initial full postback left.

Thanks in advance for help

Nikhil Kothari

Posted on 4/23/2007 @ 1:05 PM
Dan: I will look into your issue (and see if there is a bug that needs fixing for the next release ... after MIX07).

Swirek: For #1 - did you add History.htm to your site? Is that loading correctly? For #2, it sounds like this might be the same as Dan's issue, though as far as I tested, navigating to another page/site and then coming back doesn't loose the history entries for the original page. Will look into it...

Daiwen

Posted on 4/24/2007 @ 11:42 AM
Great work! Can I konw how to use a UpdateHistory control in a user control? Is there any demo?Thanks!

Joshua

Posted on 4/25/2007 @ 9:41 AM
I have placed the history control in my master page and call addEntry when an event is caught that is NOT an AJAX trigger. the event actually bubbles up fron a usercontrol in my update panel. Can I still add an entry with a non ajax triggered event? Cause the add entry code executes in my event and at the end of it I call updatePanel.update() but nothing happens??

Joshua

Posted on 4/25/2007 @ 11:25 AM
Also can an exmaple of a masterpage be posted? also another side issue that maybe you might have an opinion n:: is it better to have an update panel inside a content place holder? or is it better to have a content place holder inside an update panel for an ajajx master page scenario?

Dan

Posted on 4/25/2007 @ 10:30 PM
I tried a few more combinations and now it all works (except those gridviews with paging). What works for me is to have no extra code in the radiobox/textbox/dropdown onwhateverchanged.
I have
using nStuff.UpdateControls;
using System.Text.RegularExpressions;
and a
updateHistory.AddEntry(
pName.Text
+ ":" + pTables.SelectedIndex.ToString()
+ ":" + pDonor.SelectedIndex.ToString()
+ ":" + pActive.SelectedIndex.ToString());
as the first statement of my OnPreRender and define
protected void OnUpdateHistoryNavigate(object sender, HistoryEventArgs e)
{
// Raised when the user navigates back/forward or
// loads a bookmark to a specific view.

// Use the history entry name to determine the
// selected index and update the page.
int selected1Index = 0;
int selected2Index = 0;
int selected3Index = 0;
if (String.IsNullOrEmpty(e.EntryName) == false)
{
Regex rColon = new Regex(":");
string[] sArgs = rColon.Split(e.EntryName);
selected1Index = Int32.Parse(sArgs[1]);
selected2Index = Int32.Parse(sArgs[2]);
selected3Index = Int32.Parse(sArgs[3]);
pName.Text = sArgs[0];
}
pTables.SelectedIndex = selected1Index;
pDonor.SelectedIndex = selected2Index;
pActive.SelectedIndex = selected3Index;

PersonsView.DataBind();
DisplayUpdatePanel.Update();
SelectorUpdatePanel.Update();
}

and in the aspx
<%@ Register Assembly="nStuff.UpdateControls" Namespace="nStuff.UpdateControls"
TagPrefix="nStuff" %>
<%@ MasterType VirtualPath="~/Master1.master" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit"
TagPrefix="ajaxToolkit" %>
<asp:Content ID="Content1" ContentPlaceHolderID="ContentPlaceHolder1"
runat="Server">
<asp:ScriptManager runat="server">
</asp:ScriptManager>
<nStuff:UpdateHistory runat="server" ID="updateHistory"
OnNavigate="OnUpdateHistoryNavigate" />
<nStuff:UpdateAction runat="server" ID="updateAction" />
etc

works like a charm!

swirek

Posted on 4/26/2007 @ 3:36 AM
Hi,
My first issue was solved with your History.htm adding hint, thanks
Second issue occurs in IE6 and 7 only (Firefox works fine in this situation). If I change my logical views on one page several times, history entries are added appropriately, but if I open another page then, history about logical views from previous page dissapears. You can easily reproduce this on your example page by choosing entries from dropdown list and seeing your history filled. But try click link on bottom of page (Script# for example) and your history is empty (one entry left from initial page load only).

thanks for help

SRINATH NANDURI

Posted on 5/11/2007 @ 7:26 AM
Has a bug when using sort!!! I had developed a webpage (which inherits from a Master Page) which has a gridview ! I had implemented sorting on it (as I was using an ObjectDataSource) in the Row Command. After sorting a couple of times, it stops sorting! Also , I had a button that uses the Select command to display another GridView!! This does not work either... Nikhil, if you need the source code, please email me and you can test it out.. Also, I can provide you with a test URL if you want to check it out!!

Thanks
-Srinath

Ioor

Posted on 5/14/2007 @ 6:56 AM
Hi Nikhil!
Have you been able to reproduce the problem swirek wrote about?
Because i have the same problem. Fireforx works but not IE7 (havn't tested IE6 yet).
I my case i am using a postbackURL to load the page when the history events disappears.

Thanks for the help!

Sean

Posted on 5/24/2007 @ 2:54 PM
If a user hits the browser's refresh button, I have figured out how to make my control retain the information they contained by storing the viewstate in a Session variable, but all previous history entries made by your control are deleted - which means the user cannot navigate back anymore. The other problem is that I could reset the user back to the initial page, but that intial page is now marked with the anchor (UpdateHistory entry) of whatever page was refreshed and that just makes the initial page unreachable from any future pressing of the back button. Fun stuff.

For me, the ideal solution is not losing the back button history on a refresh. Second best solution is making your UpdateHistory control remove the anchor from the back button URL entry if the control knows this is not a PostBack.

Am I missing anything some other solution here?

Huw Millington

Posted on 5/29/2007 @ 5:42 AM
I'm using the UpdateIndicatorPanel and it's working well apart from one thing: When it is invoked the page scrolls so that the control being updated is at the top of the window prior to the indication occuring. Is that intentional? Is there a way to stop it (short of recompiling the dll)?

Lubos Edelstein

Posted on 6/17/2007 @ 10:19 AM
I uset the UpdateHistory, It works fine. But if i have sound on i get a 'Click Click', i expect only one 'Click' but i get two. Itried to figure it out myself but failed. Any idea what could be the reason for the 'Click Click'?

Celes

Posted on 7/4/2007 @ 12:20 AM
I'm also receiving the PageRequestManager script error. But it went off after turning off the Script Debugging option in IE

Raul

Posted on 7/23/2007 @ 5:58 AM
Hello All.

The control is very good!!! but we are having problems with servers that are balanced.

Do you know a solution for this problem?

Thanks in advance Raul

Valentin

Posted on 8/7/2007 @ 6:10 AM
Please help me (sorry for my bad English)
i need use this super control in other situation
i have on top page anchor's like <a href ..></a>
when user click on this anchor page full refreshed, but if href="#..." control works
how implement full reference on other page? that is for my internal cms system, where pages is virtual, loaded content from DB

thank you

Dan

Posted on 8/10/2007 @ 11:38 AM
My development machine died so I bought new and am running on VISTA.

I noticed that this control is under the control of the IE7's Protected Mode. When OFF, running from V2005 Express, it works because Protected Mode is OFF, but the DLL is not loaded and the history OnNavigate doesn't get control. Firefox also doesn't work - unless I learn what Firefox control to set.

I think my options are (1) to get my users all to turn Protected Mode OFF for the Local Intranet + figure out Firefox and (2) get on top of a full license of VS so that I can build a signed DLL.

Dan

Posted on 8/10/2007 @ 1:14 PM
Spoke to soon. Turning off protected mode made no difference.

RobM

Posted on 11/9/2007 @ 3:38 PM
Great set of web controls Nikhil!

I wonder if you could help with the following scenario? I've done some research but honestly my lack of understanding ASP.NET I feel is keeping me from finding an answer. I've been coding in windows too long apparently!

Assume you have a page like you History.aspx page. You can select items from the drop-down all day long, watch the back button become enabled and the history being written in the url. You can then select back / forward browser buttons and OnNavigate event fires and all works as expected.

But, if you had a button on your history.aspx page which redirected to another page, (call it page X) and then you use the back button from page X to return to History.aspx the asp.net page lifecycle model fires twice. Once for the normal page load and then a second time when the async operation occurs, firing the OnNavigate event. (as expected).

This scenario is causing me problems because I have a page of summary rows. The user can select a button on a summary row to view the details page. The user can then use the back button to return to the summary page. The summary page then loads twice. The first time it fires it loads all the data and resets to the first summary page (users can filter the data on the summary page, which is why i'm using the UpdateHistory control to track the filter set). The second time the page life cycle repeats itself is for the OnNavigate event. This forces a load of the summary page albeit to the right set of filtered data. This makes my page look funky as it loads a set of data with no filters, then it reloads the data with the filters set. (The filters are comb-boxes btw, not that the filter types matter).

This was really my first ASP.NET application and I decided AJAX was the way to implement the summary data view so the user could filter and navigate the dataset without full page updates. Maybe I should just use a query string and not worry about page refreshes. This would take care of my scenario.

Thanks again for the controls.
The discussion on this post has been closed. Please use my contact form to provide comments.