I've a simple asp.net page (framework 3.5) and an UpdatePanel with a series of dropdownlist I want to populate asyncronously. All works fine in all major browsers (Opera, Safari, IE6, IE7, FF3), but not in Chrome.
Chrome seems to ignore the SelectedIndexChanged event who had to make the asynch request.
Anyone knows a simple workaround to this?
Thanks!
EDIT: More Informations
As I say to Adam Lassek, the updatepanel refresh after the click to an asp:Button inside of it, but it doesn't work with the dropdown's SelectedIndexChanged event.
The updatepanel is set like:
<asp:UpdatePanel ID="updPanel" runat="server" UpdateMode="Always" ChildrenAsTriggers="true">
without Triggers specified, and the dropdows have sets AutoPostBack="true"
UPDATE: (and retagging)
After a few attempts I discover that it isn't a problem of the UpdatePanel, but it seems that the AutoPostback of dropdowns doesn't work properly, even in pages without ScriptManager and UpdatePanel...
I'm sure that it is a problem concerning only this project, because if I start a new WebSite from scratch and replicate the structure of this, works fine in Chrome...
I'm trying to remove step by step all the other things in the original project to find exactly what's the problem.
If anyone has some ideas in meantime....
There is a known incompatibility with Ajax.NET and Chrome & Safari 3.
Small, quick tests can be deceptive because it will appear to work fine with the existing Ajax.NET library as is. This is because it manages to perform the first Ajax request and fails when that ends, so only when you try to perform the second Ajax action will you notice it has failed. If you put an UpdateProgress control on your page, you'll notice that after the first request your UpdateProgress control won't disapppear.
Luckily, there is an answer!
Recently there was a great post put up detailing what to do which you can find here:
http://blog.turlov.com/2009/01/aspnet-ajax-compatibility-patch-for.html
The general gist of it is that both Chrome and Safari 3 report themselves as WebKit in their userAgent strings.
You need to add a little bit of javascript in to aid the Ajax.NET framework in recognising WebKit based browsers that looks like the following:
if (typeof(Sys.Browser.WebKit) == "undefined") {
Sys.Browser.WebKit = {};
}
if (navigator.userAgent.indexOf("WebKit/") > -1 ) {
Sys.Browser.agent = Sys.Browser.WebKit;
Sys.Browser.version =
parseFloat(navigator.userAgent.match(/WebKit\/(\d+(\.\d+)?)/)[1]);
Sys.Browser.name = "WebKit";
}
You need to add that to a javascript file and reference it in your ScriptManager:
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Scripts>
<asp:ScriptReference Path="~/assets/javascript/WebKit.js" />
</Scripts>
</asp:ScriptManager>
Note that you can keep the WebKit.js in an assembly and reference that by using a ScriptReference tag similar to this:
<asp:ScriptReference Assembly="Scripts" Name="Scripts.webkit.js" />
Once you've done all that, if at all possible stop using WebForms and Ajax.NET and use MVC and jQuery :)
This happens because MicrosoftAjax.js does browser detection, and it's incorrectly detecting Chrome as Safari. In order to fix this, you need to make the following changes:
Add a new browser type
Sys.Browser = {};
Sys.Browser.InternetExplorer = {};
Sys.Browser.Firefox = {};
Sys.Browser.Safari = {};
Sys.Browser.Opera = {};
Sys.Browser.Chrome = {};
Update the if-then logic to search for Chrome
else if (navigator.userAgent.indexOf(' Firefox/') > -1) {
Sys.Browser.agent = Sys.Browser.Firefox;
Sys.Browser.version = parseFloat(navigator.userAgent.match(/ Firefox\/(\d+\.\d+)/)[1]);
Sys.Browser.name = 'Firefox';
Sys.Browser.hasDebuggerStatement = true;
}
else if (navigator.userAgent.indexOf(' Chrome/') > -1) {
Sys.Browser.agent = Sys.Browser.Chrome;
Sys.Browser.version = parseFloat(navigator.userAgent.match(/ Chrome\/(\d+\.\d+)/)[1]);
Sys.Browser.name = 'Chrome';
Sys.Browser.hasDebuggerStatement = true;
}
else if (navigator.userAgent.indexOf(' AppleWebKit/') > -1) {
Sys.Browser.agent = Sys.Browser.Safari;
Sys.Browser.version = parseFloat(navigator.userAgent.match(/ AppleWebKit\/(\d+(\.\d+)?)/)[1]);
Sys.Browser.name = 'Safari';
Be sure to put the Chrome check before Safari. If you need help replacing the Framework script with your custom version, read this.
UPDATE:
I created a test page and put the following controls on it:
<asp:ScriptManager ID="scriptManager1" runat="server" />
<asp:UpdatePanel ID="panel1" runat="server" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:DropDownList ID="ddlTest" runat="server" AutoPostBack="true">
<asp:ListItem Value="0" Text="Item 1" />
<asp:ListItem Value="1" Text="Item 2" />
</asp:DropDownList>
<asp:Literal ID="litTest" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
And wrote the following codebehind:
protected override void OnInit(EventArgs e)
{
ddlTest.SelectedIndexChanged += new EventHandler(ddlTest_SelectedIndexChanged);
base.OnInit(e);
}
void ddlTest_SelectedIndexChanged(object sender, EventArgs e)
{
litTest.Text = "Selected: " + ddlTest.SelectedItem.Text;
}
The Updatepanel works fine in Chrome, with no modification of the Ajax library. So, I think something else is causing this problem. You're going to need to isolate the cause of the problem through a process of elimination. Start with something simple like this example, and work up to what you have a piece at a time.
It is not an appropriate suggestion to use MVC and jQuery instead of WebForms and ASP.NET AJAX. One should understand all the pros and cons of the technologies and approaches to choose from.
First, MVC is a design pattern and has nothing to do with the particular frameworks mentioned. You can easily implement an MVC pattern with WebFroms. There are many different implementations of MVC for ASP.NET and WebForms.
Second, jQuery, being a great JavaScript library, does not allow any integration with and does not leverage server side ASP.NET functionality, as opposed to ASP.NET AJAX framework that comes standard with the ASP.NET 3.5+ and fully utilizes ASP.NET features, such as server side mark-up, ScriptManager control, server-side script combining, localization and globalization, etc.
Third, jQuery can be easily used in conjunction with ASP.NET and ASP.NET AJAX frameworks thus enhancing client-side programming. Microsoft has announced that jQuery will be shipped with the next ASP.NET 4.0 and for now you can just add it to your project manually.
I just ran into a similar problem today (although I wasn't using Ajax), and found a fix. See the third comment down on this blog post.
I have the same problem. I've got a dropdown inside a ajax postback and need to do an update when the selected index changes. It works with a basic page in a new project too.
After adding the Webkit script mentioned in the other answers I still get the same problem and when running the javascript debugger in Chrome I get this error:
uncaught exception ReferenceError: evt is not defined
UPDATE: SOLUTION
I found that in my case it was a CustomValidator that was interfering with the event handler. Setting EnableClientScript to false fixed the issue.
You can check out solution
http://dotnetguts.blogspot.com/2009/05/dropdownlist-autopostback-problem-with.html
Related
I have an asp button that looks like this:
Default.aspx
<asp:button id="button1" runat="server" Text="clickme" onclick="function" />
Default.aspx.cs
protected void function(object sender EventArgs e)
{
// Do some calculation
}
However, whenever I press the button, the entire page gets refreshed. I have looked on this site and found many solutions, but none of them really works for my project. Here are some of the suggested solutions:
set onclick="return false;" // but then how do I run the function in the code-behind?
use !IsPostBack in Page_Load // but the page still refreshes completely. I don't want Page_Load to be called at all.
Disable AutoEventWireup. // making this true or false doesn't make a difference.
Does anyone have a solution to this, or is it really impossible?
I would place the control inside of an Update panel.
To do so, you would also need a script manager above it, so something like this:
<asp:ScriptManager runat="server" ID="sm">
</asp:ScriptManager>
<asp:updatepanel runat="server">
<ContentTemplate>
<asp:button id="button1" runat="server" Text="clickme" onclick="function" />
</ContentTemplate>
</asp:updatepanel>
if a control inside the update panel does a postback, it will only reload the part of the page inside of the upate panel.Here is a link you may find useful from the MSDN site.
I think there is a fundamental misunderstanding here of how ASP.Net works.
When a user first requests your page, an instance of your Page class is created. The ASP.Net framework runs through the page lifecycle with this page instance in order to generate html. The html response is then sent to the user's browser. When the browser receives the response it renders the page for the user. Here's the key: by the time rendering is complete, your page class instance was probably already collected by the .Net garbage collector. It's gone, never to be seen again.
From here on out, everything your page does that needs to run on the server, including your method, is the result of an entirely new http request from the browser. The user clicks the button, a new http request is posted to the web server, the entire page lifecycle runs again, from beginning to end, with a brand new instance of the page class, and an entirely new response is sent to the browser to be re-rendered from scratch. That's how ASP.Net (and pretty much any other web-based technology) works at its core.
Fortunately, there are some things you can do to get around this. One option is to put most of your current Page_Load code into an if (!IsPostBack) { } block. Another option is to set up your method with the [WebMethod] attribute and make an ajax request to the method from the button. Other options include calling web services from custom javascript and ASP.Net UpdatePanel controls.
What works best will depend on what other things are on the page that user might have changed.
That is normal behavior for asp.net, you are actually causing a postback of the the page in order for the associated event to be called on the server.
I would suggest working with update panels but if you just need something to happen on the backend without it causing any major change on the web page, I would use jquery and a web service. The main reason for me is that update panels create huge viewstate objects.
Have a look here for asp.net ajax : http://www.asp.net/ajax
And here for an example of jquery and wcf : http://www.codeproject.com/Articles/132809/Calling-WCF-Services-using-jQuery
I have a similar problem. this answer helps me a lot. in your asp button.<asp:button id="button1" runat="server" Text="clickme" OnClientClick="return SomeMethod();" /> and in the SomeMethod which is a js method do your logic like manipulating your page then return false as the mentioned answer suggest.
I have a small web project, the sole purpose of this project is to house and produce reports for a larger application.
I have a page "ReportManager.aspx" that simply has a ReportViewer (10.0) control on it.
<div style="width:auto;">
<form id="Form1" runat="server" style="width:100%; height: 100%;">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<rsweb:reportviewer id="ReportViewer1" runat="server" Width="100%" Height="100%" AsyncRendering="false" SizeToReportContent="true"></rsweb:reportviewer>
</form>
</div>
<script runat="server">
private void Page_Load(object sender, System.EventArgs e)
{
if (IsPostBack)
return;
ReportViewer1.ProcessingMode = ProcessingMode.Remote;
ReportViewer1.ServerReport.ReportServerUrl = new Uri("http://localhost/ReportServer");
ReportViewer1.ServerReport.ReportPath = "/SSRSReport";
ReportParameter param = new ReportParameter("effective_date", "4/22/2013");
ReportViewer1.ServerReport.SetParameters(param);
ReportViewer1.PageCountMode = PageCountMode.Actual;
}
</script>
Changing pages on the reportviewer control at runtime is producing an error.
The error is in:
Reserved.ReportViewerWebControl.axd?OpType=Resource&Version=10.0.30319.1&Name=ViewerScript
at Line 3559, and looks like this:
// Remove the current STYLE element, if it already exists.
if (oldStyleElement != null)
headElement.removeChild(oldStyleElement);
headElement.removeChild(oldStyleElement); is the line where the error is showing htmlfile: Invalid argument. Break | Continue | Ignore.
Clicking "Continue" causes the report to render without any styling. Clicking "ignore" allows the report to render correctly.
I am running Windows 2012 Server, Visual Studio 2012 Premium and IE8. The same error occurs on Win 7 machines.
Any suggestions or known fixes?
My report is in an MVC app also. I actually fix this problem awhile ago. I think I fixed it by removing the following lines:
ReportViewer1.ProcessingMode = ProcessingMode.Remote;
ReportViewer1.ServerReport.ReportServerUrl = new Uri("http://localhost/ReportServer");
ReportViewer1.ServerReport.ReportPath = "/SSRSReport";
ReportViewer1.PageCountMode = PageCountMode.Actual;
I changed the code to store all that data in the tag.
Another thing I did was add
ReportViewer1.ServerReport.Refresh() below ReportViewer1.ServerReport.SetParameters(param).
After I made those changes, everything started working.
Though suspicious it would help, I tried removing as much code-behind as possible like you suggested, but this did not fix it for me.
However, this was the solution in our app:
The .aspx page hosting the ReportViewer control was missing its <body> tag.
THAT'S ALL!!
Anti-climactic, I know, but apparently this causes IE8 (at least) to barf on
headElement.removeChild(oldStyleElement);
I'm curious if doing the same in your app brings the error back.
There are only a handful of resources I found via Google dealing with this problem, I can't believe this wasn't mentioned in any of them :-x
I have a really specific question for which I don't think I will have an answer but... let's try!
I have an aspx web page that works perfectly with Firefox and Chrome but not on IE9 (don't feed the troll ^^).
My objective is to allow an asynchronous image upload using ASP AjaxControlToolkit (see http://www.asp.net/ajaxlibrary/AjaxControlToolkitSampleSite/asyncfileupload/asyncfileupload.aspx for a demo). When the image asynchronous upload is finished, the UploadedComplete function is called and I put the image in a session variable :
if (fileSizeOk && fileTypeOk)
Session["image"] = this.AsyncFileUploadLogo.FileBytes;
In parallel I have a handler responsible for returning an image from the session variable :
byte[] buffer = (byte[])context.Session["image"];
context.Response.OutputStream.Write(buffer, 0, buffer.Length);
context.Response.OutputStream.Flush();
Then, in my aspx page, I have an asp:Image field in a UpdatePanel that asks to the handler to get the image every five second :
<asp:UpdatePanel ID="UpdatePanelLogo" runat="server">
<ContentTemplate>
<asp:Image ID="ImageFileUploaded" runat="server" ImageUrl="AsyncImageHandler.ashx" />
<asp:Timer ID="TimerFileUploaded" Interval="5000" runat="server" />
</ContentTemplate>
</asp:UpdatePanel>
When the user validates the form, I just have to get the variable from the session and I save the image in database with the other values.
Here is my problem: with Firefox and Chrome, the timer provokes the reloading of the image but with IE (even IE9) the image is only displayed after hitting F5. When I put a breakpoint in the handler I can see that it's never called with IE (maybe a caching mechanism?).
Do you have an idea of how to solve this problem?
Thanks for your answers!
Found the solution using a classic Web dirty trick:
this.ImageFileUploaded.ImageUrl = "AsyncImageHandler.ashx?p=" + Environment.TickCount.ToString();
I added that line in the PageLoad(), this last is called on each post back triggered by the timer :)
I have a pretty simple ASP.NET Web Form that looks a bit like the following:
<%# Page Language="C#" AutoEventWireup="true" CodeFile="example.aspx.cs" Inherits="example" %>
<form runat="server">
<asp:GridView runat="server" id="grid" AutoGenerateColumns="false" OnRowCommand="DoStuff">
<Columns>
<asp:ButtonField Text="Do stuff" />
</Columns>
</asp:GridView>
</form>
(In PageLoad I call grid.DataBind(), and the event handler DoStuff is unremarkable.)
When I view this in Internet Explorer and click the ButtonField (which renders as a link), the event handler fires as expected. When I click it in Firefox, nothing happens.
If I turn on Firebug's Javascript debugging console then click the link, it shows an error in the Javascript onclick handler that's auto-generated by ASP.NET:
theForm is undefined
__doPostBack("grid", "$0")
javascript:__doPostBack('grid', '$0')()
if (!theForm.onsubmit || (theForm.onsubmit() != false)) {\r\n
Why does this happen and how can I make the ButtonField work in Firefox?
(N.B. I'm asking this question in order to answer it myself: I've already discovered why I was seeing the above error, and wanted to record it for the benefit of myself and others. Feel free to add other answers if you know other gotchas with ASP.NET and Firefox.)
This is due to a difference in how the browsers handle Javascript in the presence of invalid HTML: specifically, when the form is not surrounded with <html> and <body> tags. Without these tags, Firefox seems to try to initialise the variable theForm before the form actually exists.
Adding the proper <html> and <body> tags around the form (as is required for valid HTML in any case) makes the click handler work in both IE and Firefox.
Notes:
obviously invalid HTML is a worst practice for many other reasons. The page I was developing was intended to be used with a Master page which rendered the rest of the surrounding HTML, but (for various reasons) I was testing it in isolation from the Master page.
I tried reproducing the same problem with a simple <asp:Button runat="server">, but that triggers a full page-refreshing PostBack, so it doesn't hit the same error. Being a Web Forms n00b I don't know what's special about a GridView (or this use case) that makes it behave differently (i.e. sets up an onclick handler to handle the click without a page load).
I've marked this as wiki in case anyone else can explain this better than I.
I am having an ASP.NET page with one Asp.net button control and a normal html link (anchor tage) I want to invoke the postbackl event of asp.net button control when someone clicks on the link.
I used the below code
<a href="javascript:myFunction();" class="checkout" ></a>
<asp:Button ID="btnCheckout" runat="server" Visible="false"
onclick="btnCheckout_Click" />
and in my javascript i have
function myFunction()
{
var strname;
strname = "Test";
__doPostBack('btnCheckout','OnClick');
}
But when runnin gthis , i am getting an error like __doPostBack is undefined
Can any one tell me why it is ?
Thanks in advance
This anyway wouldn't have worked. When you make your .NET control invisible by using 'Visible="false"' it isn't rendered, that means not available at the client.
Back to your question.
1- Where is myFunction defined? Between the tag?
2- Are there more .NET controls on the page? If there aren't any other .NET controls, .NET doesn't add all the scripts that are required for postbacks and stuff.
Why not do the following (based on TheVillageIdiot answer):
<asp:LinkButton ID="lbtnCheckout" runat="server" CausesValidation="false" OnClick="lbtnCheckout_Click" CssClass="checkout" />
With the above example you don't need the fake button and make it invisble. You still can do your postback. Way more cleaner approach I would say.
First of all I tried your code and also not get anything like __doPostBack, then I added another button on the page which was visible but it was all the same. Then I added a LinkButton and got __doPostBack method. You can do post back from javascript but then EventValidation is problem, as it does not allow this kind of thing. I had to use the following to overcome it and it worked:
protected override void Render(HtmlTextWriter writer)
{
ClientScript.RegisterForEventValidation(
new PostBackOptions(btnCheckout, "OnClick"));
base.Render(writer);
}
I think I'm bit incoherent in answering so I'll mark it as wiki :)