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.
Ответы
Ответ 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.