可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
It seems like ASP.NET 4.0 is not prepared to handle ImageButton events triggered by Internet Explorer 10. The problem is that IE10 sends the image click coordinates as double values (with decimals), and ASP.NET tries to parse them as integers, presenting the following type of 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)
Googling around, some people suggest forcing IE10 to run in compatibility view. However, adding the meta tag <meta http-equiv="X-UA-Compatible" content="IE=10" />
does not solve anything; and adding <?xml version="1.0" encoding="UTF-8">
before <!DOCTYPE>
doesn't work either.
Any solutions? Could I capture the click event with Javascript and remove the decimals somehow?
Note: Upgrading to Framework 4.5 and recompiling fixes the bug. No need to change the runtime version, since it's still 4.0.
回答1:
Simply installing .NET Framework 4.5 can fix this problem.
This can fix the problem even if you do not switch your application pool over to .NET Framework 4.5.
In my case, I left the app pools at .NET Framework 3.5. Apparently installing .NET Framework 4.5 overwrites some files for other framework versions.
Since it is so easy to install the new .NET Framework version, it's probably worth a try before bothering with the hotfixes (which did not work for me) or other solutions.
See the workarounds section here
回答2:
There are hotfixes for .NET CLR 2.0 and 4.0, as described in this blog entry by Scott Hanselmann:
What the fixes do is update the ie.browser and firefox.browser files
in \Windows\Microsoft.NET\Framework\\Config\Browsers with new
and future-proofed versions of these browser definitions. Nothing else
is affected.
.NET 4
- http://support.microsoft.com/kb/2600088
.NET 2.0
http://support.microsoft.com/kb/2600100 for Win7 SP1/Windows
Server 2008 R2 SP1, Windows Vista/Server 2008, Windows XP/Server 2003
http://support.microsoft.com/kb/2608565 for Win7/Windows Server
2008 R2 RTM
Alternatively, there's a client-based javascript patch (originally posted as workaround on the Connect item with bug 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);
}
}
};
}
});
回答3:
Here's a JavaScript workaround. It overrides the existing method, floors the x and y coordinates then calls the existing method with these new coordinates.
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:
As noted in another answer, this issue has been fixed in .NET 4.5.
For those who can't upgrade to .NET 4.5, Microsoft has released an update to fix this problem for .NET 4.0 (KB2836939) and .NET 3.5 (KB2836942 and KB2836943).
Here's how those KB articles describe the issue:
When you click an ImageButton control that is inside an update panel on an ASP.NET-based webpage by using Internet Explorer 10 and later, the partial postback operation fails. Additionally, the server-side click event is not fired.
For reference, here's the original ImageButton.LoadPostData
code that throws 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;
}
And here's the fixed code:
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:
If you press F12 and switch to IE9 manually, it works like a charm. So our apporach was to use content="IE=9" but this only switches the document mode in IE10 not the browser mode and that seems to be not enough.
Maybe someone has an idea on how to switch the document mode too?
Another workaround that gets more and more popular is to overwrite LoadPostData, see
http://www.codeproject.com/Tips/496162/IE10-and-ImageButtons?display=Mobile
http://forums.asp.net/t/1823287.aspx/2/10
Personally I woulve have found the content="IE=9" the best solution because of the little additional work and impact.
回答6:
Actually is a different issue than the ones listed by tkrause. There is a hotfix available, although I can't figure out how to apply it. Here is info for those that do know how to apply these:
http://support.microsoft.com/kb/2784147
If you check the ASP.NET section is has the exact error stated in this question. This is the exact error and issue I am having also.
I think I cannot get the update because I'm using Server 2003. I'm using ASP.NET 3.5 and VS 2008, so upgrading to 4.x isn't an easy option for me.
回答7:
I ended up sub-classing the ImageButton, and correcting the data before it was passed in for processing.
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:
Just put this in the header of each page or the master page:
<meta http-equiv="X-UA-Compatible" content="IE=9" />
This will force IE10 into IE9 standards document mode, and it can handle image postbacks just fine.
回答9:
In our case, on the master page we added below line of code under <head>
section:
<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE9">
This worked for us as it allows the page to be rendered in the version of IE that is specified.
回答10:
In my case I am not currently able to upgrade .Net to 4.5 and I didn't want to use JavaScript to patch the bug.
The solution that I went with was to convert my ImageButton to a LinkButton:
This was my ImageButton:
<asp:ImageButton ID="MyButton" runat="server" CausesValidation="false" ToolTip="my tooltip" ImageUrl="../Images/button.gif" OnClick="MyButton_Click" ></asp:ImageButton>
This is the LinkButton I replaced it with:
<asp:LinkButton ID="MyButton" runat="server" CausesValidation="false" OnClick="MyButton_Click">
<asp:Image runat="server" ImageUrl="~/Images/button.gif" alt="my tooltip"/>
</asp:LinkButton>
From the user's perspective, it all works the same as it did before....but without the crashing in IE.