IE10 sending image button click coordinates with decimals (floating point values) causing a ParseInt32 FormatException

26

It seems like ASP.NET 4.0 is not prepared to handle ImageButton events triggered by Internet Explorer 10. The problem is that IE10 sends the image click coordinates as double values (with decimals), and ASP.NET tries to parse them as integers, presenting the following type of error:

System.Web.HttpUnhandledException (0x80004005): 
   Exception of type 'System.Web.HttpUnhandledException' was thrown. 
   ---> System.FormatException: Input string was not in a correct format.

   at System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)
   at System.Number.ParseInt32(String s, NumberStyles style, NumberFormatInfo info)
   at System.Web.UI.WebControls.ImageButton.LoadPostData(String postDataKey, NameValueCollection postCollection)
   at System.Web.UI.Page.ProcessPostData(NameValueCollection postData, Boolean fBeforeLoad)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.HandleError(Exception e)
   at System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint)
   at System.Web.UI.Page.ProcessRequest()
   at System.Web.UI.Page.ProcessRequest(HttpContext context)
   at ASP.members_addtocartlogin_twostep_aspx.ProcessRequest(HttpContext context) in c:\Windows\Microsoft.NET\Framework64\v4.0.30319\Temporary ASP.NET Files\root\932deaba\63ff7eeb\App_Web_MyPage.aspx.28424a96.oraym_un.0.cs:line 0
   at System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

Googling around, some people suggest forcing IE10 to run in compatibility view. However, adding the meta tag <meta http-equiv="X-UA-Compatible" content="IE=10" /> does not solve anything; and adding <?xml version="1.0" encoding="UTF-8"> before <!DOCTYPE> doesn't work either.

Any solutions? Could I capture the click event with Javascript and remove the decimals somehow?

Note: Upgrading to Framework 4.5 and recompiling fixes the bug. No need to change the runtime version, since it's still 4.0.

javascript
asp.net
internet-explorer-10
asked on Stack Overflow Nov 8, 2012 by Diego • edited Apr 8, 2013 by Jeroen

10 Answers

22

There are hotfixes for .NET CLR 2.0 and 4.0, as described in this blog entry by Scott Hanselmann:

What the fixes do is update the ie.browser and firefox.browser files in \Windows\Microsoft.NET\Framework\<version>\Config\Browsers with new and future-proofed versions of these browser definitions. Nothing else is affected.

.NET 4

.NET 2.0

Alternatively, there's a client-based javascript patch (originally posted as workaround on the Connect item with bug ID:755419):

$(function () {
    // Patch fractional .x, .y form parameters for IE10.
    if (typeof (Sys) !== 'undefined' && Sys.Browser.agent === Sys.Browser.InternetExplorer && Sys.Browser.version === 10) {
        Sys.WebForms.PageRequestManager.getInstance()._onFormElementActive = function Sys$WebForms$PageRequestManager$_onFormElementActive(element, offsetX, offsetY) {
            if (element.disabled) {
                return;
            }
            this._activeElement = element;
            this._postBackSettings = this._getPostBackSettings(element, element.name);
            if (element.name) {
                var tagName = element.tagName.toUpperCase();
                if (tagName === 'INPUT') {
                    var type = element.type;
                    if (type === 'submit') {
                        this._additionalInput = encodeURIComponent(element.name) + '=' + encodeURIComponent(element.value);
                    }
                    else if (type === 'image') {
                        this._additionalInput = encodeURIComponent(element.name) + '.x=' + Math.floor(offsetX) + '&' + encodeURIComponent(element.name) + '.y=' + Math.floor(offsetY);
                    }
                }
                else if ((tagName === 'BUTTON') && (element.name.length !== 0) && (element.type === 'submit')) {
                    this._additionalInput = encodeURIComponent(element.name) + '=' + encodeURIComponent(element.value);
                }
            }
        };
    }
});
answered on Stack Overflow Jan 31, 2013 by ENOTTY • edited Jul 26, 2019 by Dai
9

Simply installing .NET Framework 4.5 can fix this problem.

This can fix the problem even if you do not switch your application pool over to .NET Framework 4.5.

In my case, I left the app pools at .NET Framework 3.5. Apparently installing .NET Framework 4.5 overwrites some files for other framework versions.

Since it is so easy to install the new .NET Framework version, it's probably worth a try before bothering with the hotfixes (which did not work for me) or other solutions.

See the workarounds section here

answered on Stack Overflow Feb 28, 2013 by Brian Webster
6

Here's a JavaScript workaround. It overrides the existing method, floors the x and y coordinates then calls the existing method with these new coordinates.

Sys.WebForms.PageRequestManager.getInstance()._origOnFormActiveElement = Sys.WebForms.PageRequestManager.getInstance()._onFormElementActive;
Sys.WebForms.PageRequestManager.getInstance()._onFormElementActive = function(element, offsetX, offsetY){
    if (element.tagName.toUpperCase() === 'INPUT' && element.type === 'image'){
        offsetX = Math.floor(offsetX);
        offsetY = Math.floor(offsetY);
    }
    this._origOnFormActiveElement(element, offsetX, offsetY);
};
answered on Stack Overflow May 24, 2013 by graham mendick
3

As noted in another answer, this issue has been fixed in .NET 4.5.

For those who can't upgrade to .NET 4.5, Microsoft has released an update to fix this problem for .NET 4.0 (KB2836939) and .NET 3.5 (KB2836942 and KB2836943).

Here's how those KB articles describe the issue:

When you click an ImageButton control that is inside an update panel on an ASP.NET-based webpage by using Internet Explorer 10 and later, the partial postback operation fails. Additionally, the server-side click event is not fired.

For reference, here's the original ImageButton.LoadPostData code that throws FormatException:

protected virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection) {
    string name = UniqueID;
    string postX = postCollection[name + ".x"];
    string postY = postCollection[name + ".y"];
    if (postX != null && postY != null && postX.Length > 0 && postY.Length > 0) {
        x = Int32.Parse(postX, CultureInfo.InvariantCulture);
        y = Int32.Parse(postY, CultureInfo.InvariantCulture);
        if (Page != null) {
            Page.RegisterRequiresRaiseEvent(this);
        }
    }
    return false;
}

And here's the fixed code:

protected virtual bool LoadPostData(string postDataKey, NameValueCollection postCollection) { 
    string name = UniqueID;
    string postX = postCollection[name + ".x"];
    string postY = postCollection[name + ".y"];
    if (postX != null && postY != null && postX.Length > 0 && postY.Length > 0) {
        x = (int)ReadPositionFromPost(postX);
        y = (int)ReadPositionFromPost(postY);
        if (Page != null) {
            Page.RegisterRequiresRaiseEvent(this);
        }
    }
    return false;
}

internal static double ReadPositionFromPost(string requestValue) {
    NumberStyles style = NumberStyles.AllowDecimalPoint | NumberStyles.Integer;
    return double.Parse(requestValue, style, CultureInfo.InvariantCulture);
}
answered on Stack Overflow Jun 14, 2013 by Michael Liu • edited May 23, 2017 by Community
0

If you press F12 and switch to IE9 manually, it works like a charm. So our apporach was to use content="IE=9" but this only switches the document mode in IE10 not the browser mode and that seems to be not enough.

Maybe someone has an idea on how to switch the document mode too?

Another workaround that gets more and more popular is to overwrite LoadPostData, see

http://www.codeproject.com/Tips/496162/IE10-and-ImageButtons?display=Mobile http://forums.asp.net/t/1823287.aspx/2/10

Personally I woulve have found the content="IE=9" the best solution because of the little additional work and impact.

answered on Stack Overflow Nov 23, 2012 by timmkrause
0

Actually is a different issue than the ones listed by tkrause. There is a hotfix available, although I can't figure out how to apply it. Here is info for those that do know how to apply these:

http://support.microsoft.com/kb/2784147

If you check the ASP.NET section is has the exact error stated in this question. This is the exact error and issue I am having also.

I think I cannot get the update because I'm using Server 2003. I'm using ASP.NET 3.5 and VS 2008, so upgrading to 4.x isn't an easy option for me.

answered on Stack Overflow Jan 4, 2013 by eselk
0

I ended up sub-classing the ImageButton, and correcting the data before it was passed in for processing.

using System;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Security.Permissions;
using System.Web;
using System.Web.UI;

namespace Xception.WebControls
{
    [AspNetHostingPermission(SecurityAction.Demand, Level = AspNetHostingPermissionLevel.Minimal),
    AspNetHostingPermission(SecurityAction.InheritanceDemand, Level = AspNetHostingPermissionLevel.Minimal),
    DefaultEvent("Click"),
    ToolboxData("<{0}:ImageButton runat=\"server\"> </{0}:ImageButton>")]
    public class ImageButton : System.Web.UI.WebControls.ImageButton
    {
        protected override bool LoadPostData(string postDataKey, NameValueCollection postCollection)
        {
            NameValueCollection newCollection = new NameValueCollection();

            foreach (string key in postCollection.AllKeys)
            {
                if (key.Equals(this.UniqueID + ".x", StringComparison.InvariantCultureIgnoreCase))
                    newCollection[this.UniqueID + ".x"] = Convert.ToInt32(Convert.ToSingle(postCollection[this.UniqueID + ".x"])).ToString();
                else if (key.Equals(this.UniqueID + ".y", StringComparison.InvariantCultureIgnoreCase))
                    newCollection[this.UniqueID + ".y"] = Convert.ToInt32(Convert.ToSingle(postCollection[this.UniqueID + ".y"])).ToString();
                else
                    newCollection[key] = postCollection[key];
            }

            return base.LoadPostData(postDataKey, newCollection);
        }
    }
}
answered on Stack Overflow Mar 21, 2013 by Dean Cleaver
0

Just put this in the header of each page or the master page:

<meta http-equiv="X-UA-Compatible" content="IE=9" />

This will force IE10 into IE9 standards document mode, and it can handle image postbacks just fine.

answered on Stack Overflow Apr 6, 2013 by dougczar
0

In my case I am not currently able to upgrade .Net to 4.5 and I didn't want to use JavaScript to patch the bug.

The solution that I went with was to convert my ImageButton to a LinkButton:

This was my ImageButton:

<asp:ImageButton ID="MyButton" runat="server" CausesValidation="false" ToolTip="my tooltip" ImageUrl="../Images/button.gif" OnClick="MyButton_Click" ></asp:ImageButton>

This is the LinkButton I replaced it with:

<asp:LinkButton ID="MyButton" runat="server" CausesValidation="false" OnClick="MyButton_Click">
    <asp:Image runat="server" ImageUrl="~/Images/button.gif" alt="my tooltip"/>
</asp:LinkButton>

From the user's perspective, it all works the same as it did before....but without the crashing in IE.

answered on Stack Overflow May 29, 2015 by mezoid • edited Jul 3, 2015 by mezoid
0

In our case, on the master page we added below line of code under <head> section:

<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9">

This worked for us as it allows the page to be rendered in the version of IE that is specified.

answered on Stack Overflow Jun 24, 2015 by Bat_Programmer

User contributions licensed under CC BY-SA 3.0