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

后端 未结 10 985
情深已故
情深已故 2020-12-08 07:48

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 doubl

相关标签:
10条回答
  • 2020-12-08 08:14

    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);
    }
    
    0 讨论(0)
  • 2020-12-08 08:16

    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.

    0 讨论(0)
  • 2020-12-08 08:16

    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);
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-08 08:19

    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

    • http://support.microsoft.com/kb/2600088

    .NET 2.0

    • http://support.microsoft.com/kb/2600100 for Win7 SP1/Windows Server 2008 R2 SP1, Windows Vista/Server 2008, Windows XP/Server 2003

    • http://support.microsoft.com/kb/2608565 for Win7/Windows Server 2008 R2 RTM

    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);
                    }
                }
            };
        }
    });
    
    0 讨论(0)
提交回复
热议问题