You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

后台Void类型PayPal校验方法改为Ajax可调用String方法超时失败如何解决

问题根因

  • 你用的ASMX是.NET Framework早期的传统Web服务技术栈,原生不支持返回Task<T>类型的异步WebMethod,Task异步编程模型推出时间远晚于ASMX规范,所以你改造后的异步方法无法被服务正确调度,会出现异步上下文死锁,请求一直挂起直到超时,这就是你设置再大的超时阈值也没用的原因。
  • 原来的async void方法能正常运行是因为属于“发射即遗忘”的执行模式,调用后立刻返回,后台异步执行逻辑不会阻塞请求线程,但也因此无法给前端返回执行结果。
  • 你的代码还存在隐藏bug:nextPayment2.AddMonths(1);这行无效,DateTime是值类型,AddMonths方法会返回新的DateTime对象,你没有接收赋值,导致后续的下次付款时间计算错误。

解决方案

方案1:改为同步实现(最稳妥,兼容性最好)

直接把异步调用逻辑改为同步执行,适配ASMX的执行模型:

[WebMethod]
public string CheckAcc()
{
    userManager um = new userManager();
    var userID = HttpContext.Current.User.Identity.GetUserId();
    um.Get(userID);
    var subid = um.ppID.Trim();
    var token = getToken();

    using (var httpClient = new HttpClient())
    {
        using (var request = new HttpRequestMessage(new HttpMethod("GET"), "https://api.paypal.com/v1/billing/subscriptions/" + subid))
        {
            var id = "";
            var nextPayment = "";
            var status = "";
            var payerEmail = "";
            var currency = "";

            request.Headers.TryAddWithoutValidation("Authorization", "Bearer " + token);

            // 同步等待异步方法执行完成
            var response = httpClient.SendAsync(request).GetAwaiter().GetResult();
            string res = response.Content.ReadAsStringAsync().GetAwaiter().GetResult();

            var obj2 = JsonConvert.DeserializeObject<dynamic>(res);

            id = obj2.id;

            nextPayment = obj2.billing_info.next_billing_time;
            if (nextPayment == null)
            {
                nextPayment = obj2.billing_info.last_payment.time;
                var nextPayment2 = Convert.ToDateTime(nextPayment);
                // 修复DateTime赋值bug
                nextPayment2 = nextPayment2.AddMonths(1);
                nextPayment = nextPayment2.ToString();
            }
            status = obj2.status;
            status = status.ToLower();
            status = FirstLetterToUpper(status);
            payerEmail = obj2.subscriber.email_address;
            currency = obj2.shipping_amount.currency_code;
            um.updatePaypal_noIPN(id, status, "Regular", nextPayment, payerEmail, currency);

            return status + ", " + payerEmail + ", ";
        }
    }
}

同步修改前端调用代码,调整接口地址和错误提示逻辑方便排查问题:

$( document ).ready(function() {
    $.ajax({
        type: "POST",
        url: '/WebServices/checkPayPal.asmx/CheckAcc',
        cache: false,
        contentType: "application/json; charset=utf-8",
        dataType: "json",
        success: OnSuccess,
        error: OnError,
        timeout: 30000 // PayPal接口常规响应时间不会超过30秒,无需设置过大
    });
});

function OnSuccess(data, status) {
    alert(data.d);
}
function OnError(data, status) {
    alert("调用失败,错误信息:" + data.responseText);
}

方案2:保留异步实现(要求.NET Framework 4.5及以上版本)

如果一定要用异步逻辑,可以修改配置和代码适配:

  1. 首先在web.config的system.web节点下添加配置开启异步支持:
<system.web>
    <httpRuntime targetFramework="4.5" />
    <pages async="true" />
</system.web>
  1. 修改后端异步方法,所有await调用后添加.ConfigureAwait(false)避免上下文死锁,同时修复DateTime赋值bug:
[WebMethod]
public async System.Threading.Tasks.Task<string> CheckAccAsync()
{
    userManager um = new userManager();
    var userID = HttpContext.Current.User.Identity.GetUserId();
    um.Get(userID);
    var subid = um.ppID.Trim();
    var token = getToken();

    using (var httpClient = new HttpClient())
    {
        using (var request = new HttpRequestMessage(new HttpMethod("GET"), "https://api.paypal.com/v1/billing/subscriptions/" + subid))
        {
            var id = "";
            var nextPayment = "";
            var status = "";
            var payerEmail = "";
            var currency = "";

            request.Headers.TryAddWithoutValidation("Authorization", "Bearer " + token);

            // 添加ConfigureAwait(false)避免上下文死锁
            var response = await httpClient.SendAsync(request).ConfigureAwait(false);
            string res = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

            var obj2 = JsonConvert.DeserializeObject<dynamic>(res);

            id = obj2.id;

            nextPayment = obj2.billing_info.next_billing_time;
            if (nextPayment == null)
            {
                nextPayment = obj2.billing_info.last_payment.time;
                var nextPayment2 = Convert.ToDateTime(nextPayment);
                // 修复DateTime赋值bug
                nextPayment2 = nextPayment2.AddMonths(1);
                nextPayment = nextPayment2.ToString();
            }
            status = obj2.status;
            status = status.ToLower();
            status = FirstLetterToUpper(status);
            payerEmail = obj2.subscriber.email_address;
            currency = obj2.shipping_amount.currency_code;
            um.updatePaypal_noIPN(id, status, "Regular", nextPayment, payerEmail, currency);

            return status + ", "+payerEmail+", ";
        }
    }
}

内容的提问来源于stack exchange,提问作者MattHodson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 12:45:02