【问题标题】:Inconsistent LinkButton PageMethod behavior in different browsers不同浏览器中的 LinkBut​​ton PageMethod 行为不一致
【发布时间】:2013-12-31 12:43:06
【问题描述】:

我在执行回发的页面上有一个 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 中设置会话变量,结果相同。

代码可以用下面的简单代码重现:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script type="text/javascript">

    function doStuff() {
        var a = 'a';
        var b = 'b';

        PageMethods.doStuffWebMethod(a, b, doStuffSuccess, doStuffFail);
    }

    function doStuffSuccess() {
        alert(Success!');
    }
    function doStuffFail() {
        alert(Failure!');
    }

</script>

<html>
    <body style="background-color:#f3f4f6;" >

        <form runat="server" name="mainForm" id="mainForm" action="Test.aspx">

            <asp:ScriptManager ID="ScriptManager1"  EnablePageMethods="true" runat="server"></asp:ScriptManager>

            <asp:LinkButton runat="server" CausesValidation="false" OnClientClick="doStuff();">Do stuff!</asp:LinkButton>

        </form>
    </body>
</html>

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 中失败,并在其他三种浏览器中给我三种不同的返回消息之一?

如何更改此代码以使其在上述浏览器中工作?

【问题讨论】:

  • 我认为这是一个体面的、经过研究的问题……不知道为什么一个两年前的问题突然遭到反对;对于那些想报复我的人来说,这一定是我的出气筒问题……*shrug*

标签: c# javascript ajax cross-browser webmethod


【解决方案1】:

调用您的网络方法失败的原因是 您不会取消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!');
}

<asp:LinkButton ID="mybutton"  runat="server" CausesValidation="false" OnClientClick="return doStuff();">Do stuff!</asp:LinkButton>

有关取消浏览器默认行为(回发)的更复杂的解决方案,请查看以下stackoverflow question and answer

您在不同浏览器上得到不同结果的原因可能是浏览器供应商的不同实现。但我不确定。

您还可以通过创建网络协议跟踪来验证此行为 (在 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.
}

【讨论】:

  • 但我希望回发发生,因此我不会返回错误。你是说我想做的事根本不可能?
  • @LittleBobbyTables:不,这不是不可能的。您可以使用 __doPostBack() 方法在页面方法返回后手动触发回发。我已经扩展了我的答案。
  • 谢谢,稍后我会试一试,看看效果如何。另外,很抱歉投了反对票,我在智能手机上点击错误。
  • @LittleBobbyTables:没问题。我刚刚错过了您问题的回发部分。
  • 是的,成功了!我忘记了__doPostBack(因为我认为我以前不必明确地调用它)。感谢您的所有工作!
猜你喜欢
  • 2012-11-05
  • 1970-01-01
  • 2014-08-17
  • 2016-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多