javascript - ubicar - IE10 envía el botón de imagen haciendo clic en las coordenadas con decimales(valores de punto flotante) que causan una excepción ParseInt32 FormatException
ejercicios de conversion de grados decimales a sexagesimales (10)
Aquí hay una solución de JavaScript. Anula el método existente, reduce las coordenadas x e y luego llama al método existente con estas nuevas coordenadas.
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);
};
Parece que ASP.NET 4.0 no está preparado para manejar los eventos ImageButton desencadenados por Internet Explorer 10. El problema es que IE10 envía las coordenadas de clic de la imagen como valores dobles (con decimales), y ASP.NET intenta analizarlas como enteros, presentando el siguiente tipo de error:
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)
Buscando en Google, algunas personas sugieren obligar a IE10 a ejecutarse en una vista de compatibilidad. Sin embargo, agregar la meta etiqueta <meta http-equiv="X-UA-Compatible" content="IE=10" />
no soluciona nada; y agregar <?xml version="1.0" encoding="UTF-8">
antes de que <!DOCTYPE>
tampoco funcione.
¿Alguna solución? ¿Puedo capturar el evento de clic con Javascript y eliminar los decimales de alguna manera?
Nota: la actualización a Framework 4.5 y la recompilación corrige el error. No es necesario cambiar la versión de tiempo de ejecución, ya que todavía es 4.0.
Como se señaló en otra respuesta , este problema se ha solucionado en .NET 4.5.
Para aquellos que no pueden actualizarse a .NET 4.5, Microsoft ha lanzado una actualización para solucionar este problema para .NET 4.0 ( KB2836939 ) y .NET 3.5 ( KB2836942 y KB2836943 ).
Aquí es cómo esos artículos de KB describen el problema:
Cuando hace clic en un control ImageButton que está dentro de un panel de actualización en una página web basada en ASP.NET utilizando Internet Explorer 10 y versiones posteriores, la operación de devolución de datos parcial falla. Además, el evento de clic del lado del servidor no se activa.
Para referencia, aquí está el código original ImageButton.LoadPostData
que lanza 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;
}
Y aquí está el código fijo:
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);
}
En mi caso, actualmente no puedo actualizar .Net a 4.5 y no quise usar JavaScript para corregir el error.
La solución con la que fui fue convertir mi ImageButton a un LinkButton:
Este fue mi ImageButton:
<asp:ImageButton ID="MyButton" runat="server" CausesValidation="false" ToolTip="my tooltip" ImageUrl="../Images/button.gif" OnClick="MyButton_Click" ></asp:ImageButton>
Este es el LinkButton con el que lo reemplacé:
<asp:LinkButton ID="MyButton" runat="server" CausesValidation="false" OnClick="MyButton_Click">
<asp:Image runat="server" ImageUrl="~/Images/button.gif" alt="my tooltip"/>
</asp:LinkButton>
Desde la perspectiva del usuario, todo funciona de la misma manera que antes ... pero sin que se bloquee en IE.
En nuestro caso, en la página maestra agregamos debajo de la línea de código en la sección <head>
:
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9">
Esto funcionó para nosotros ya que permite que la página se represente en la versión de IE que se especifica.
En realidad es un problema diferente a los enumerados por tkrause. Hay una revisión disponible, aunque no puedo averiguar cómo aplicarlo. Aquí hay información para aquellos que saben cómo aplicar estos:
http://support.microsoft.com/kb/2784147
Si verifica, la sección ASP.NET tiene el error exacto indicado en esta pregunta. Este es el error exacto y el problema que estoy teniendo también.
Creo que no puedo obtener la actualización porque estoy usando el Servidor 2003. Estoy usando ASP.NET 3.5 y VS 2008, por lo que actualizar a 4.x no es una opción fácil para mí.
Hay revisiones para .NET CLR 2.0 y 4.0, como se describe en esta entrada de blog de Scott Hanselmann :
Lo que hacen los arreglos es actualizar los archivos ie.browser y firefox.browser en / Windows / Microsoft.NET / Framework // Config / Browsers con versiones nuevas y preparadas para el futuro de estas definiciones de navegador. Nada más se ve afectado.
.NET 4
.NET 2.0
http://support.microsoft.com/kb/2600100 para Win7 SP1 / Windows Server 2008 R2 SP1, Windows Vista / Server 2008, Windows XP / Server 2003
http://support.microsoft.com/kb/2608565 para Win7 / Windows Server 2008 R2 RTM
Alternativamente, hay un parche de javascript basado en el cliente (originalmente publicado como solución en el elemento Conectar con ID de error: 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);
}
}
};
}
});
Si presiona F12 y cambia a IE9 manualmente, funciona como un amuleto. Así que nuestro objetivo era usar content = "IE = 9", pero esto solo cambia el modo de documento en IE10, no el modo de navegador y parece que no es suficiente.
Tal vez alguien tenga una idea sobre cómo cambiar el modo de documento también?
Otra solución que se vuelve más y más popular es sobrescribir LoadPostData, vea
http://www.codeproject.com/Tips/496162/IE10-and-ImageButtons?display=Mobile http://forums.asp.net/t/1823287.aspx/2/10
Personalmente, he encontrado que el contenido = "IE = 9" es la mejor solución debido al poco trabajo e impacto adicionales.
Simplemente coloque esto en el encabezado de cada página o la página maestra:
<meta http-equiv="X-UA-Compatible" content="IE=9" />
Esto forzará IE10 en el modo de documento estándar de IE9, y puede manejar las devoluciones de imagen bien.
Terminé sub-clasificando el ImageButton, y corrigiendo los datos antes de pasarlos para su procesamiento.
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);
}
}
}
La simple instalación de .NET Framework 4.5 puede solucionar este problema.
Esto puede solucionar el problema incluso si no cambia su grupo de aplicaciones a .NET Framework 4.5.
En mi caso, dejé los grupos de aplicaciones en .NET Framework 3.5. Aparentemente, la instalación de .NET Framework 4.5 sobrescribe algunos archivos para otras versiones del marco.
Dado que es tan fácil instalar la nueva versión de .NET Framework, probablemente valga la pena probarlo antes de molestarse con las revisiones (que no me funcionaron) u otras soluciones.
Vea la sección de soluciones aquí