26

似乎 ASP.NET 4.0 不准备处理由 Internet Explorer 10 触发的 ImageButton 事件。问题是 IE10 将图像点击坐标作为双精度值(带小数)发送,而 ASP.NET 尝试将它们解析为整数,呈现以下类型的错误:

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)

谷歌搜索,有人建议强制 IE10 在兼容性视图中运行。但是,添加元标记<meta http-equiv="X-UA-Compatible" content="IE=10" />并不能解决任何问题;并且<?xml version="1.0" encoding="UTF-8">之前添加<!DOCTYPE>也不起作用。

有什么解决办法吗?我可以使用 Javascript 捕获点击事件并以某种方式删除小数吗?

注意:升级到 Framework 4.5 并重新编译修复了该错误。无需更改运行时版本,因为它仍然是 4.0。

4

10 回答 10

22

.NET CLR 2.0 和 4.0 有修补程序,如Scott Hanselmann 的这篇博文所述:

\Windows\Microsoft.NET\Framework\<version>\Config\Browsers修复程序所做的是使用这些浏览器定义的新版本和面向未来的版本更新 ie.browser 和 firefox.browser 文件。没有其他任何影响。

.NET 4

.NET 2.0

或者,有一个基于客户端的 javascript 补丁(最初作为解决方法发布在Connect 项目上,错误 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);
                }
            }
        };
    }
});
于 2013-01-31T13:28:52.037 回答
9

只需安装 .NET Framework 4.5 即可解决此问题。

即使您不将应用程序池切换到 .NET Framework 4.5,这也可以解决问题。

就我而言,我将应用程序池保留在 .NET Framework 3.5 中。显然安装 .NET Framework 4.5 会覆盖其他框架版本的一些文件。

由于安装新的 .NET Framework 版本非常容易,因此在使用修补程序(对我不起作用)或其他解决方案之前可能值得一试。

请参阅此处的解决方法部分

于 2013-02-28T06:57:48.407 回答
7

这是一个 JavaScript 解决方法。它覆盖现有方法,设置 x 和 y 坐标,然后使用这些新坐标调用现有方法。

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);
};
于 2013-05-24T14:53:29.403 回答
3

另一个答案所述,此问题已在 .NET 4.5 中修复。

对于无法升级到 .NET 4.5 的用户,Microsoft 已发布更新以解决 .NET 4.0 ( KB2836939 ) 和 .NET 3.5 ( KB2836942KB2836943 ) 的此问题。

以下是这些知识库文章描述该问题的方式:

当您使用 Internet Explorer 10 及更高版本单击基于 ASP.NET 的网页上更新面板内的 ImageButton 控件时,部分回发操作将失败。此外,不会触发服务器端单击事件。

作为参考,这ImageButton.LoadPostData是抛出的原始代码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;
}

这是固定代码:

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);
}
于 2013-06-14T15:08:20.807 回答
0

只需将其放在每个页面或母版页的标题中:

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

这将强制 IE10 进入 IE9 标准文档模式,并且它可以很好地处理图像回发。

于 2013-04-06T02:48:56.963 回答
0

如果你按 F12 并手动切换到 IE9,它就像一个魅力。所以我们的方法是使用 content="IE=9" 但这只是在 IE10 中切换文档模式而不是浏览器模式,这似乎还不够。

也许有人对如何切换文档模式也有想法?

另一种越来越流行的解决方法是覆盖 LoadPostData,请参阅

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

就我个人而言,我会发现 content="IE=9" 是最好的解决方案,因为它几乎没有额外的工作和影响。

于 2012-11-23T09:43:37.500 回答
0

我最终对 ImageButton 进行了子类化,并在数据被传入进行处理之前对其进行了更正。

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);
        }
    }
}
于 2013-03-21T01:21:42.407 回答
0

实际上与 tkrause 列出的问题不同。有一个可用的修补程序,虽然我不知道如何应用它。以下是那些知道如何应用这些的信息:

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

如果您检查 ASP.NET 部分是否有此问题中所述的确切错误。这也是我遇到的确切错误和问题。

我想我无法获得更新,因为我使用的是 Server 2003。我使用的是 ASP.NET 3.5 和 VS 2008,所以升级到 4.x 对我来说不是一个简单的选择。

于 2013-01-04T20:10:09.917 回答
0

就我而言,我目前无法将 .Net 升级到 4.5,并且我不想使用 JavaScript 来修补错误。

我采用的解决方案是将 ImageButton 转换为 LinkBut​​ton:

这是我的 ImageButton:

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

这是我将其替换为的 LinkBut​​ton:

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

从用户的角度来看,这一切都和以前一样工作......但没有在 IE 中崩溃。

于 2015-05-29T06:59:46.053 回答
0

在我们的例子中,在母版页上,我们在以下<head>部分添加了以下代码行:

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

这对我们有用,因为它允许在指定的 IE 版本中呈现页面。

于 2015-06-24T23:27:20.897 回答