Table of Contents
- π¨ Problem
- Expected vs Actual Behavior
-
π Solution (Part 1): Updating
AjaxControlToolkit
-
π Solution (Part 2): Adding
<asp:AsyncPostBackTrigger>
- Summary
π¨ Problem
TL;DR: see Summary and the working code snippet if you want to try it right away.
In my company there is an old Web Form Website running .NET Framework 3.5. I migrated it to an ASP.NET Web Form Application running .NET Framework 4.7.2 few months ago. The website is running just like the old one but recently a user reported that:
a
<select>
list which should triggers an AJAX call and refresh part of the page does not work. Instead, the page is reloaded everytime when the item in the<select>
list is changed.
I used almost a day to figure out whatβs (probably) happened and I hope that this article will be helpful to someone in the future who (still) encounter this problem.
Expected vs Actual Behavior
There is a <form>
containing a <select>
list (generated by <asp:DropDownList>
). When the selected option is changed, an AJAX call will be fired and new items will be fetched. Besides, there is a text area for user to input remarks. A submit button will submit the form.
Expected
The page will not be reloaded when the selected option is changed. The content in the text area retains.
Actual
Once the selected option is changed, a form POST is fired (instead of an AJAX call). The content in the text area is therefore being cleaned.
This is related to AJAX calls so the first thing I checked was how the AJAX call was initiated.
π Solution (Part 1): Updating AjaxControlToolkit
In the .aspx
file I saw a <asp:UpdatePanel>
and a <asp:DropDownList>
. This is the simplified structure of that part:
<asp:UpdatePanel runat="server" ID="UpdatePanel2" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:DropDownList runat="server" ID="ddItemTypes" AutoPostBack="true" OnSelectedIndexChanged="ddItemTypes_OnSelectedIndexChanged" />
</ContentTemplate>
</asp:UpdatePanel>
AutoPostBack
is there so the app should use AjaxControlToolkit
to make AJAX calls (I guess thatβs the standard right?).
Nuget Package Update
I checked the package.config
:
<package id="AjaxControlToolkit" version="4.1.50508" targetFramework="net35" />
Looks like the targetFramework
is not right. Maybe itβs time to update the package too.
<package id="AjaxControlToolkit" version="20.1.0" targetFramework="net472" />
Some Breaking Changes
AjaxControlToolkit has some breaking changes since version 15+. In short, you need to:
Uninstall the old version and install the new version of
AjaxControlToolkit
.Change
<asp:ToolkitScriptManager>
to<asp:ScriptManager>
Remove some unused configs in
web.config
(see this)[Optional] Install
AjaxControlToolkit.HtmlEditor.Sanitizer
Change the namespace
AjaxControlToolkit.HTMLEditor
toAjaxControlToolkit.HtmlEditor
Change the namespace
AjaxControlToolkit.HTMLEditor.ToolbarButton
toAjaxControlToolkit.HtmlEditor.ToolbarButtons
You may also readthe official complete migration guide.
After I upgrade the Nuget package, the AJAX calls was working partially: It only works on Chromium-base browsers like Chrome and Edge. However, it does not work on Firefox (85.0) and Safari (14.0.1).
π π π
Different __doPostBack()
in Firefox?
This is what I got from Firefoxβs dev tool:
The initiator is from __doPostBack()
in the .aspx
page. In Chrome, itβs from ScriptResource.axd
. Below is the expected call stack: the call is an XHR request fired from ScriptResource.axd
.
Looks like the stack items from bottom to _doPostBack()
are the same. I therefore dug into _doPostBack()
and eventually found this piece of code in ScriptResource.axd
:
if (!this._postBackSettings.async) {
form.onsubmit = this._onsubmit;
this._originalDoPostBack(eventTarget, eventArgument);
form.onsubmit = null;
return;
}
if this._postBackSettings.async
is false
, _originaldoPostBack()
will be called and that is the __doPostBack()
function defined in the .aspx
page. This will trigger a page reload instead of an AJAX call.
Furthermore, I found that the asyncTarget
in _postBackSettings
is null
but in Chrome that target is the <select>
list.
In Firefox (v85.0) the javascript event initiated is somehow keep propagating to a higher level than the
<select>
list (probably to the formβs level) and therefore being treated as a form POST instead of an AJAX call.
π Solution (Part 2): Adding <asp:AsyncPostBackTrigger>
I did some research related to the Firefox-specific page reload and seems none of them were talking about the issue I met. I tried to study the fundamentals of this PostBack behaviour.
Finally I got this article Avoid (Prevent) Page refresh (PostBack) after SelectedIndexChanged is fired in ASP.Net DropDownList. It suggested what I might missing is an asp:AsyncPostBackTrigger
.
Also, this StackOverflow answer menitoned the asp:AsyncPostBackTrigger
thing.
So my understanding is:
When using the
ScriptManager
(i.e. the one we introduced when updating theAjaxControlToolkit
), we need to define anasp:AsyncPostBackTrigger
Trigger
in order to make the call AJAX.
Therefore, I added a Trigger
section to the .aspx
file:
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddItemTypes" EventName="SelectedIndexChanged" />
</Triggers>
This Trigger
section should be placed under the same <asp:UpdatePanel>
with the <asp:DropDownList>
. Here is the complete snippet:
The Working Code Snippet
<asp:UpdatePanel runat="server" ID="UpdatePanel2" UpdateMode="Conditional" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:DropDownList runat="server" ID="ddItemTypes" AutoPostBack="true" OnSelectedIndexChanged="ddItemTypes_OnSelectedIndexChanged" />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="ddItemTypes" EventName="SelectedIndexChanged" />
</Triggers>
</asp:UpdatePanel>
Note:
EventName
is optional here but since I just want this trigger to listen theSelectedIndexChanged
event, I add them all.The
ControlID
has to be an exact match with theID
of<asp:DropDownList>
.
After I added the <asp:AsyncPostBackTrigger>
, all the browsers including Chrome, Edge, Firefox (85.0) and Safari (14.0.1) are working.
Summary
When your .NET 4.5+ ASP.NET Web Form Application using AjaxControlToolkit
does not work as expected and cause the controls like <asp:DropDownList>
cannot fire an AJAX call (but triggers a form POST), make sure that:
The
AjaxControlToolkit
Nuget package is up to date (and did the proper migration steps here).The
<asp:UpdatePanel>
section should contain a<Triggers>
section. In that section there is an<asp:AsyncPostBackTrigger>
withControlID
same as theID
of your control (which is also placed under the same UpdatePanel section).
Top comments (0)