有没有办法同步调用PageMethods?

时间:2011-07-14 21:45:13

标签: javascript asp.net vb.net asynchronous pagemethods

我正在尝试这样做:

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

但它仍然以异步方式运行。我需要浏览器实际等待,直到我的代码隐藏完成执行,然后才能刷新

有一个列表框加载了刚刚从数据库中删除的值,它们不应该是可见的。我遇到的问题是在执行代码隐藏之前窗口位置刷新,似乎没有任何内容被删除给用户。

5 个答案:

答案 0 :(得分:11)

使用jQuery ajax调用它?它有一个选项(async),您可以在其中选择同步/异步模式:http://api.jquery.com/jQuery.ajax/

这篇优秀的文章告诉你如何最好地从jQuery调用PageMethods: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";
  }
});

查看Crockford's JSON stringify以获取json格式化解决方案。

答案 1 :(得分:2)

如果你想避免使用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;
}

答案 2 :(得分:1)

我遇到过这个网站:

http://abhijit-j-shetty.blogspot.com/2011/04/aspnet-ajax-calling-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];

答案 3 :(得分:1)

Using jQuery在{2009}回归first recommended

另一个(非常详细)选项是实现同步WebRequestExecutor,如here(2007-07-04)所示,并且完善了here(2007-10-30)。该技术的要点是将ASP.NET AJAX Sys.Net.XMLHttpExecutor复制为名为Sys.Net.XMLHttpSyncExecutor的新类,并将调用更改为xmlHttpRequest.open以将false作为最后一个参数传递给强制同步操作。

可以使用WebRequestManager将同步执行程序插入所有请求中,如下所示:

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

或者您可能希望按请求just before it is invoked

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

This discussion是大多数这些链接的来源,还有更​​多链接。

答案 4 :(得分:0)

我写了这个,使您可以同步调用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);
}