Любой способ сделать синхронный вызов PageMethods? - PullRequest
6 голосов
/ 15 июля 2011

Я пытаюсь сделать это:

function DelBatch()
{var userInfo = get_cookie("UserInfo");
PageMethods.DeleteBatchJSWM(userInfo, function(result)
                                          {window.location = "BatchOperations.aspx";});
}

Но все равно он работает асинхронно.Мне нужно, чтобы браузер действительно дождался завершения выполнения моего кода, затем его можно обновить

Там есть список, загруженный значениями, которые были только что удалены из базы данных, их не должно быть видно.У меня проблема в том, что местоположение окна обновляется перед выполнением кода, и кажется, что оно не было удалено пользователю.

Ответы [ 5 ]

11 голосов
/ 15 июля 2011

Назовите его, используя вместо этого jQuery ajax? Он имеет опцию (async), в которой вы можете выбрать режим синхронизации / асинхронности: http://api.jquery.com/jQuery.ajax/

Эта превосходная статья рассказывает, как лучше всего вызывать PageMethods из jQuery: http://encosia.com/using-jquery-to-directly-call-aspnet-ajax-page-methods/

По сути, все, что вам нужно сделать, это:

$.ajax({
  type: "POST",
  async: false,
  url: "yourpage.aspx/DeleteBatchJSWM",
  data: "{ put json representation of userInfo here }",
  contentType: "application/json; charset=utf-8",
  dataType: "json",
  success: function(msg) {
    window.location = "BatchOperations.aspx";
  }
});

Посмотрите на Крокфорда JSON stringify для решения для форматирования json.

2 голосов
/ 25 апреля 2012

Если вы хотите избежать использования jQuery, можно обойти другое использование PageMethod, в котором вы проверяете состояние операции с помощью функции javascript setInterval. Это немного грязно, но это делает работу, если вы хотите ноль jQuery, и имитирует синхронизацию, которую вы ищете. Я использую его для больших операций, в которых я хочу обновить индикатор выполнения для клиента или чего-то еще. Вот пример того, как вы это сделаете, учитывая, какой код вы разместили:

function DelBatch()
{

        var userInfo = get_cookie("UserInfo");
        PageMethods.DeleteBatchJSWM(userInfo, function(result) {window.location = "BatchOperations.aspx";});

        var status;

    //Check to see if it has completed every second
        var myInterval = setInterval(function ()
        {
            PageMethods.CheckDeleteBatchStatus(OnSuccess);
                if (status == "Finished")
                {
                    clearInterval(myInterval);
                        //Finished Deleting. Call your window refresh here
                WindowRefresh(); 
                }
        }, 1000);


        function OnSuccess(result)
        {
            status = result;
        }
}

Код сзади:

[WebMethod]
public static string CheckDeleteBatchStatus()
{
    string status = GetDeleteBatchStatus(); //some function to get the status of your operation
    return status;
}
1 голос
/ 13 февраля 2014

Использование jQuery было впервые рекомендовано еще в 2009 году.

Другой (чрезвычайно подробный) вариант реализует синхронный WebRequestExecutor, как показано здесь (2007-07-04) и усовершенствовано здесь (2007-10-30).Суть этого метода заключается в том, чтобы скопировать ASP.NET AJAX Sys.Net.XMLHttpExecutor в качестве нового класса с именем Sys.Net.XMLHttpSyncExecutor и изменить вызов на xmlHttpRequest.open для передачи false в качестве последнего параметра для принудительной синхронной операции.

Синхронный исполнитель может быть подключен ко всем запросам с помощью WebRequestManager , например:

Sys.Net.WebRequestManager.set_defaultExecutorType('Sys.Net.XMLHttpSyncExecutor');

, или вы можете включить его для каждого запроса простодо его вызова :

Sys.Net.WebRequestManager.add_invokingRequest(function(sender, args) {
 if (iFeelLikeRunningThisRequestSynchronously) {
  args.get_webRequest().set_executor(new Sys.Net.XMLHttpSyncExecutor());
}});

Это обсуждение является источником большинства этих ссылок и еще нескольких.

1 голос
/ 11 октября 2013

Я наткнулся на этот сайт:

http://abhijit -j-shetty.blogspot.com / 2011/04 / САШ-Ajax-вызова-pagemethods.html

, у которого был отличный метод для обработки синхронных вызовов PageMethod.

Код JavaScript следующий:

// Make sure page methods operate synchronously
XMLHttpRequest.prototype.original_open = XMLHttpRequest.prototype.open;
    XMLHttpRequest.prototype.open = function (method, url, async, user, password) {

    async = false;

    var eventArgs = Array.prototype.slice.call(arguments);

    var q = 0;
    return this.original_open.apply(this, eventArgs);
}

// Make a generic WebMethod caller:
function WebMethodCall(FunctionName, callingobj) {
    var OnSuccess = function (result, userContext, methodName) {
        callingobj.push(result);
    }

    var OnFailure = function (error, userContext, methodName) {
        callingobj.push(error.get_message());
    }

    PageMethods[FunctionName](OnSuccess, OnFailure);

}

// OK, this is kludgy, but here goes. In order to have a synchronous PageMethod call
// we need an object that persists in the namespace to stuff the result value into (like an array)
// Essentially I'm emulating a ByRef call.

// ThisResult is an empty list. The WebMethodCall function sticks a value into that list.
// The code that makes the PageMethods get called synchronously is in Common.js

// Use the functions
var ThisResult = []; // This must be of a type which persists in the namespace
WebMethodCall('HelloWorld', ThisResult);
return ThisResult[0];
0 голосов
/ 19 октября 2018

Я написал это, что позволяет вам синхронно вызывать PageMethod. Он также просто вернет результат метода и выдаст ошибку, которая может быть перехвачена в блоке try / catch, поэтому вам не нужно беспокоиться о предоставлении функций onSuccess и onError.

function synchronusPageMethod(method) {

    XMLHttpRequest.prototype.original_open = XMLHttpRequest.prototype.open;

    XMLHttpRequest.prototype.open = function (method, url, async, user, password) {
        async = false;

        var eventArgs = Array.prototype.slice.call(arguments);

        return this.original_open.apply(this, eventArgs);
    };

    var result;
    var error;

    var args = Array.prototype.slice.call(arguments).slice(1);
    args.push(function (res) {
        result = res;
    });

    args.push(function (err) {
        error = err;
    });

    method.apply(null, args);

    XMLHttpRequest.prototype.open = XMLHttpRequest.prototype.original_open;

    if (error !== undefined) {
        throw error;
    } else {
        return result;
    }
}

Используйте это так:

try {
    var result = synchronusPageMethod(PageMethods.myMethod, argument0, argument1);
    console.log(result);
} catch(error) {
    console.log(error);
}
...