Подтвердить что ты не робот

IE10, отправляющий клики с кликом по координатам с десятичными знаками (значениями с плавающей запятой), вызывающими исключение ParseInt32 FormatException

Кажется, что ASP.NET 4.0 не готов обрабатывать события ImageButton, инициированные Internet Explorer 10. Проблема заключается в том, что 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)

Включение в Google, некоторые люди предлагают заставить IE10 работать в режиме совместимости. Однако добавление метатега <meta http-equiv="X-UA-Compatible" content="IE=10" /> ничего не решает; и добавление <?xml version="1.0" encoding="UTF-8"> до <!DOCTYPE> тоже не работает.

Любые решения? Могу ли я захватить событие click с помощью Javascript и как-то удалить десятичные знаки?

Примечание. Обновление до версии 4.5 и перекомпиляция исправляет ошибку. Не нужно менять версию исполнения, так как она еще 4.0.

4b9b3361

Ответ 1

Просто установка .NET Framework 4.5 может решить эту проблему.

Это может устранить проблему, даже если вы не переключите пул приложений на .NET Framework 4.5.

В моем случае я оставил пулы приложений в .NET Framework 3.5. Очевидно, что установка .NET Framework 4.5 перезаписывает некоторые файлы для других версий фреймворка.

Поскольку так легко установить новую версию .NET Framework, вероятно, стоит попробовать, прежде чем беспокоиться о исправлениях (которые не работают для меня) или других решениях.

Смотрите раздел обходных решений здесь

Ответ 2

Существуют исправления для .NET CLR 2.0 и 4.0, как описано в этой записи блога Скотта Хансельмана:

Исправления - обновить файлы ie.browser и firefox.browser в \Windows\Microsoft.NET\Framework\<version>\Config\Browsers с новым и перспективные версии этих определений браузера. Ничего больше затронут.

.NET 4

.NET 2.0

Кроме того, существует клиентское исправление javascript (первоначально размещенное как обходной путь для элемента Connect с идентификатором ошибки: 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);
                }
            }
        };
    }
});

Ответ 3

Здесь обходной путь 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);
};

Ответ 4

Как указано в другом ответе, эта проблема была исправлена ​​в .NET 4.5.

Для тех, кто не может перейти на .NET 4.5, Microsoft выпустила обновление, чтобы устранить эту проблему для .NET 4.0 (KB2836939) и .NET 3.5 (KB2836942 и KB2836943).

Вот как описывают эту статью статьи KB:

Когда вы нажимаете элемент управления ImageButton, который находится внутри панели обновлений на веб-странице на основе ASP.NET, используя Internet Explorer 10 и более поздние версии, операция частичного возврата обратно не выполняется. Кроме того, событие щелчка на стороне сервера не запускается.

Для справки, здесь исходный 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);
}

Ответ 5

Если вы нажмете F12 и переключитесь в IE9 вручную, это будет как шарм. Поэтому наш apporach должен был использовать 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

Лично я woulve нашел контент = "IE = 9" лучшим решением из-за небольшой дополнительной работы и воздействия.

Ответ 6

На самом деле это другая проблема, чем те, которые перечислены tkrause. Существует исправление, хотя я не могу понять, как его применять. Вот информация для тех, кто знает, как их применять:

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

Если вы проверите раздел ASP.NET, в нем будет указана точная ошибка. Это точная ошибка и проблема, с которой я столкнулся.

Я думаю, что не могу получить обновление, потому что я использую Server 2003. Я использую ASP.NET 3.5 и VS 2008, поэтому обновление до 4.x - не простой вариант для меня.

Ответ 7

В итоге я переклассифицировал 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);
        }
    }
}

Ответ 8

Просто поместите это в заголовок каждой страницы или главной страницы:

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

Это заставит IE10 в режиме документа стандартов IE9, и он сможет обрабатывать обратные передачи изображений просто отлично.

Ответ 9

В моем случае я не могу обновить .NET до 4.5, и я не хотел использовать JavaScript для исправления ошибки.

Решением, с которым я пошел, было преобразование моего ImageButton в LinkButton:

Это был мой ImageButton:

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

Это LinkButton, я заменил его:

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

Ответ 10

В нашем случае на главной странице мы добавили строку ниже в разделе <head>:

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

Это сработало для нас, поскольку оно позволяет отображать страницу в указанной версии IE.