2013-12-12 2 views
0

У меня есть LinkButton на странице, которая выполняет обратную связь, но также имеет событие onClientClick. Идея состоит в том, чтобы установить некоторые переменные сеанса в фоновом режиме из клиентских данных (не спрашивайте).Непоследовательный LinkButton PageMethod поведение в разных браузерах

Я поместил точку перерыва в веб-методе, чтобы выполнить наш код, и то, что мы переживаем, заключается в том, что в зависимости от браузера, PageMethods могут возвращать сообщение об успешном завершении, сообщение об ошибке или нет сообщений на все. Кроме того, веб-метод может быть вызван или не вызван, независимо от результата PageMethods.

Вот маленький удобный график результатов:

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) 
    { 
     // 
    } 
} 

Вопрос:

Почему мой веб-метод неудачу в Safari, и предоставление мне один из трех разных возвратных сообщений в трех других браузерах?

Как я могу изменить этот код, чтобы заставить его работать в упомянутых браузерах?

+0

Я думал, что это было порядочный, исследуемый вопрос ... не уверен, почему двухлетний вопрос внезапно получает downvotes; должен быть мой вопрос с перфорацией для людей, которые хотят отомстить за меня ... »*' shrug' * ' – LittleBobbyTables

ответ

4

Причина, по которой вызов вашего веб-метода терпит неудачу, заключается в том, что не отменяет возврату вашего LinkButton. Вы должны вернуть false из события OnClientClick, чтобы отменить обратную передачу. Приведенный ниже код должен это исправить:

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.

Причина, по которой вы получаете разные результаты для разных браузеров, возможно, объясняется различными реализациями браузеров. Но я не уверен в этом.

Вы также можете проверить это поведение, создав трассировку сетевого протокола (нажмите F12 в браузере Google Chrome и перейдите на вкладку сети).

Протокол в случае, если вы не вернете от ложного метода DoStuff():

  1. Метод страницы doStuffWebMethod называется. Затем вы получите окно сообщения JavaScript. (HTTP POST)
  2. Запрошен ваш WebForm.aspx. (HTTP POST)
  3. Затем WebResource.axd и ScriptResource.Требуется axd. (HTTP GET)

2. Номер и 3. показывает, что обратная передача выполняется после запроса Вашего метода страницы.

Протокол в случае, если вы вернуть ложь от метода DoStuff():

  1. Только метод страницы doStuffWebMethod называется. (HTTP POST)

Вторая трасса ясно показывает, что никакой обратной передачи не выполняется.

Если вы хотите постбэк случиться для LinkButton, то вы можете вручную вызвать обратную передачу в обработчик успеха JavaScript с использованием метода __doPostBack() после метода страницы возвращается:

function doStuffSuccess() { 
    alert('Success!'); 

    __doPostBack('<%= mybutton.UniqueID %>', ''); // trigger the postback. 
} 
+0

Но я * также * хочу, чтобы postback произошел, поэтому я не возвращаю false. Вы говорите, что я пытаюсь сделать, просто невозможно? – LittleBobbyTables

+0

@LittleBobbyTables: Нет, это невозможно. Вы можете использовать метод __doPostBack() для ручного запуска обратной передачи после возврата метода страницы. Я расширил свой ответ. – Hans

+0

Спасибо, я попробую чуть-чуть и посмотрю, как это происходит. Кроме того, извините за пониженное голосование, я ошибался, пока на моем смартфоне. – LittleBobbyTables

Смежные вопросы