不同浏览器中的LinkBut​​ton PageMethod行为不一致

我在一个执行回发的页面上有一个LinkBut​​ton,但也有一个onClientClick事件。 我们的想法是在客户端数据的后台设置一些会话变量(不要问)。

我在Web方法中设置了一个断点来逐步执行代码,我们遇到的是取决于浏览器,PageMethods可能会返回成功消息,失败消息或根本没有消息 。 此外,无论PageMethods结果如何,都可以调用或不调用Web方法。

这是一个方便的结果小图表:

 Browser PageMethods WebMethod -------------- ------------- -------------------- IE 8, 9, 10 Success Called successfully Safari 5.1.7 Failure *Never called* Firefox 25.0.1 *Neither* Called successfully Chrome v31 Failure Called successfully 

这是四种不同的浏览器,以及四种不同的结果。

我已经尝试在服务器端和客户端代码中生成具有相同效果的链接按钮,甚至没有在WebMethod中设置会话变量,结果相同。

可以使用以下简单代码重现代码:

   function doStuff() { var a = 'a'; var b = 'b'; PageMethods.doStuffWebMethod(a, b, doStuffSuccess, doStuffFail); } function doStuffSuccess() { alert(Success!'); } function doStuffFail() { alert(Failure!'); }    
Do stuff!

 protected void Page_Load(object sender, EventArgs e) { LinkButton lbAdd = new LinkButton(); lbAdd.Text = "Web method test"; lbAdd.CausesValidation = false; lbAdd.OnClientClick = "doStuff();"; mainForm.Controls.Add(lbAdd); } [WebMethod] public static void doStuffWebMethod(string a, string b) { try { //System.Web.HttpContext.Current.Session["a"] = a; //System.Web.HttpContext.Current.Session["b"] = b; string x = a + b; } catch (Exception ex) { // } } 

问题是:

为什么我的Web方法在Safari中失败,并在三个其他浏览器中给我三个不同的返回消息之一?

如何更改此代码以使其在所提到的浏览器中工作?

调用您的Web方法失败的原因是您没有取消LinkButton的回发。 您必须从OnClientClick事件返回false才能取消回发。 下面的代码应该修复它:

 function doStuff() { var a = 'a'; var b = 'b'; PageMethods.doStuffWebMethod(a, b, doStuffSuccess, doStuffFail); return false; // Cancel postback. } function doStuffSuccess() { alert('Success!'); } function doStuffFail() { alert('Failure!'); } Do stuff! 

有关取消浏览器默认行为(回发)的更复杂的解决方案,请查看以下stackoverflow问题和答案 。

您为不同的浏览器获得不同结果的原因可能是由于浏览器供应商的不同实现。 但我不确定这一点。

您还可以通过创建网络协议跟踪来validation此行为(在Google Chrome浏览器中按F12并切换到网络选项卡)。

如果你没有从doStuff()方法返回false,该协议:

  1. 调用页面方法doStuffWebMethod 。 然后你会得到JavaScript消息框。 ( HTTP POST
  2. 您的WebForm.aspx是请求的。 ( HTTP POST
  3. 然后请求WebResource.axd和ScriptResource.axd。 ( HTTP GET

数字2和3.表示在页面方法请求之后执行回发。

如果你从doStuff()方法返回false,该协议:

  1. 只调用页面方法doStuffWebMethod 。 ( HTTP POST

第二条跟踪清楚地表明没有执行回发。

如果您希望LinkBut​​ton发生回发,那么您可以在页面方法返回后使用__doPostBack()方法在JavaScript成功处理程序中手动触发回发:

 function doStuffSuccess() { alert('Success!'); __doPostBack('<%= mybutton.UniqueID %>', ''); // trigger the postback. }