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

Acumatica 23R2 WebHook编译报错及500错误求助

Acumatica 23R2 WebHook 500错误排查与修复

问题背景

基于Acumatica WebHook实现的客户审批通知发送、响应接收及系统数据更新流程,在23R1环境运行正常,但升级到23R2后出现编译错误,调用生成的WebHook URL时返回500内部服务器错误。

代码片段

using PX.Data;
using PX.Data.Webhooks;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web;
using PX.Api.Webhooks.DAC;
using PX.Objects.SO;
using PX.SM;
using PX.Objects.CS;
using PX.Api.Services;
using INFOLicence;
namespace CustomWebhook
{
    public class ArtApprovalJobWebHooksServerHandler : IWebhookHandler
    {
        private NameValueCollection _queryParameters;

        private const string cLocationCD = "KeyValues";
        private const string cMode = "Mode";
        private const string cSendMode = "SendNotification";
        private const string cGetMode = "ReceiveResponse";

        async Task<IHttpActionResult> IWebhookHandler.ProcessRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            using (var scope = GetUserScope())
            {
                _queryParameters = HttpUtility.ParseQueryString(request.RequestUri.Query);

                string htmlResponse = string.Empty;
                if (!_queryParameters.AllKeys.Contains(cLocationCD))
                    throw new Exception($"The {cLocationCD} Parameter was not specified in the Query String");
                var collectorID = _queryParameters[cLocationCD];
                try
                {
                    string sMode = string.Empty;
                    string values = collectorID;//Password.Decrypt(collectorID);
                    string[] arr = values.Split(new char[] { ';' });
                    string ordertype = arr[1];
                    string ordernbr = arr[2];
                    string locationcd = arr[4];
                    string setuptype = arr[0];
                    string jobcode = arr[3];
                    if (!_queryParameters.AllKeys.Contains(cMode))
                    {
                        //if nothing is specified for a mode Parameter we will assume GetSurvey
                        sMode = "SendNotification";
                    }
                    else
                    {
                        sMode = _queryParameters[cMode];
                    }

                    switch (sMode)
                    {
                        case cSendMode:
                            htmlResponse = GetSendAuth(cLocationCD, ordertype, ordernbr, locationcd, setuptype,jobcode); // invoking page from customer side for approval
                            break;
                        case cGetMode:
                            htmlResponse = SubmitApproval(collectorID, request); // Updating customer response
                            break;
                        default:
                            //htmlResponse = ReturnModeNotRecognized(sMode);
                            break;
                    }
                }
                catch (PXException e)
                {
                    throw e;
                }
                return new HtmlActionResult(htmlResponse);
            }
        }
    }
}

请求URL

http://localhost/PrintShop23R2/Webhooks/Company/7fc9c9e3-05c9-4514-93d3-50a4beae9dcc?KeyValues=S;SO;SO007463;000001005;Location%201&Mode=SendNotification

返回错误信息

{
    "title": "An error has occurred.",
    "status": 500,
    "traceId": "80166d95-91d6-47fb-9b5a-b9224934962e"
}

排查与修复方向

1. 编译错误根源:API兼容性变化

Acumatica 23R2基于.NET 6构建,部分旧版API已被弃用或替换:

  • HttpUtility.ParseQueryString:该方法属于System.Web命名空间,在.NET Core环境下推荐使用Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery替代,避免依赖过时组件。
  • IWebhookHandler接口:检查23R2中该接口的签名是否变更,确保实现方法的参数、返回值与新版本匹配。
  • HtmlActionResult:若该自定义类未在项目中定义,或依赖的System.Web.Http组件在23R2中被调整,需重新实现IHttpActionResult接口返回HTML内容,示例:
    public class HtmlActionResult : IHttpActionResult
    {
        private readonly string _htmlContent;
        public HtmlActionResult(string htmlContent) => _htmlContent = htmlContent;
        public Task<HttpResponseMessage> ExecuteAsync(CancellationToken cancellationToken)
        {
            var response = new HttpResponseMessage(HttpStatusCode.OK);
            response.Content = new StringContent(_htmlContent, Encoding.UTF8, "text/html");
            return Task.FromResult(response);
        }
    }
    

2. 未捕获异常导致500错误

当前代码仅捕获PXException,其他类型异常(如数组越界、空引用)会直接抛出,触发500错误:

  • 扩展异常捕获范围,添加通用异常处理,并记录详细日志:
    catch (Exception e)
    {
        PX.Logger.Log.Error(e, "WebHook processing failed");
        throw new HttpResponseException(HttpStatusCode.InternalServerError);
    }
    
  • 对KeyValues分割后的数组添加长度校验,避免越界:
    string[] arr = values.Split(new char[] { ';' });
    if (arr.Length < 5)
        throw new Exception("Invalid KeyValues format: expected 5 segments separated by semicolon");
    

3. 权限上下文问题

GetUserScope()方法未在代码中展示,需确保其在23R2中正确创建权限上下文:

  • 使用Acumatica官方推荐的PXLogin.CreateLoginScope方法替代旧的权限上下文创建方式,确保WebHook请求以正确的用户身份执行数据操作。

4. WebHook注册验证

检查23R2中WebHook的注册流程是否变更:

  • 确认WebHook在系统中已正确注册,关联的处理程序类命名空间、类名无误。
  • 验证WebHook的公司ID、GUID与请求URL中的参数匹配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 14:20:36