Wednesday, April 13, 2011

Asp.Net, DropDownList, AutoPostBack and Google Chrome

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....

From stackoverflow
  • 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.

    tanathos : I've tried your suggestion (and thank you for your answer), but it seems to not change nothing..I see that if I insert an asp:Button inside the updatepanel (that has ChildrenAsTrigger set to true),it works fine..but it doesn't work with SelectedIndexChanged of the DropDowns (only Chrome of course)..
    tanathos : I'll try as you say, thanks : )
  • 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 :)

    Ole Lynge : Thanks! This solved my problem with paging a GridView inside an UpdatePanel in Chrome.
    Bayard Randel : "If at all possible stop using WebForms and Ajax.NET and use MVC and jQuery." Sage advice, but in the meantime, this fix works beautifully. Thank you kind sir.
  • 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

0 comments:

Post a Comment