web-dev-qa-db-ja.com

IE10がイメージボタンのクリック座標を小数(浮動小数点値)で送信すると、ParseInt32 FormatExceptionが発生する

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なので、ランタイムバージョンを変更する必要はありません。

26
Diego

。NET Framework 4.5をインストールするだけでこの問題を解決できます。

これにより、アプリケーションプールを.NET Framework 4.5に切り替えなくても問題を解決できます。

私の場合、アプリプールは.NET Framework 3.5のままにしました。どうやら.NET Framework 4.5をインストールすると、他のフレームワークバージョンの一部のファイルが上書きされます。

新しい.NET Frameworkバージョンをインストールするのは簡単なので、ホットフィックス(私にとっては機能しなかった)や他のソリューションに悩む前に、試してみる価値はあるでしょう。

回避策のセクションを参照してください ここ

9
Brian Webster

Scott Hanselmannによるこのブログエントリ で説明されているように、.NET CLR 2.0および4.0のホットフィックスがあります。

修正により、\Windows\Microsoft.NET\Framework\<version>\Config\Browsersのie.browserファイルとfirefox.browserファイルが、これらのブラウザー定義の新しい将来のバージョンで更新されます。他には何も影響を受けません。

.NET 4

.NET 2.0

または、クライアントベースのjavascriptパッチがあります(元は、回避策として バグ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);
                }
            }
        };
    }
});
22
ENOTTY

これが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);
};
6
graham mendick

別の答え で述べたように、この問題は.NET 4.5で修正されました。

.NET 4.5にアップグレードできない人のために、Microsoftは.NET 4.0( KB2836939 )および.NET 3.5( KB2836942 および- KB283694 )。

これらのKB記事が問題を説明する方法は次のとおりです。

Internet Explorer 10以降を使用して、ASP.NETベースのWebページの更新パネル内にあるImageButtonコントロールをクリックすると、部分的なポストバック操作が失敗します。また、サーバー側のクリックイベントは発生しません。

参考までに、こちらがオリジナルのImageButton.LoadPostDataFormatExceptionをスローするコード:

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);
}
3
Michael Liu

これを各ページまたはマスターページのヘッダーに挿入するだけです。

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

これにより、IE10はIE9標準ドキュメントモードになり、画像ポストバックを問題なく処理できます。

0
dougczar

この例では、マスターページの<head>セクションの下にコード行を追加しました。

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

これは、指定されたIEのバージョンでページをレンダリングできるため、私たちにとってはうまくいきました。

0
Bat_Programmer

F12を押して手動でIE9に切り替えると、魅力的に動作します。したがって、私たちのアプローチはcontent = "IE = 9"を使用することでしたが、これはIE10でドキュメントモードを切り替えるだけで、ブラウザーモードではなく、それだけでは十分ではないようです。

たぶん誰かがドキュメントモードを切り替える方法についてのアイデアを持っていますか?

ますます一般的になる別の回避策は、LoadPostDataを上書きすることです。

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

個人的には、追加の作業と影響がほとんどないため、content = "IE = 9"が最良のソリューションであると思います。

0
timmkrause

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);
        }
    }
}
0
Dean Cleaver

実際には、tkrauseによってリストされている問題とは別の問題です。修正プログラムが利用可能ですが、適用方法がわかりません。これらを適用する方法を知っている人のための情報はここにあります:

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

あなたがASP.NETセクションをチェックすると、この質問で述べられている正確なエラーがあります。これは正確なエラーであり、私が抱えている問題でもあります。

Server 2003を使用しているため、更新を取得できないと思います。ASP.NET3.5およびVS 2008を使用しているため、4.xへのアップグレードは簡単なオプションではありません。

0
eselk

私の場合、現在.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でクラッシュすることはありません。

0
mezoid