You need to enable JavaScript to run this app. .NET WEB API多并发请求处理:GetNonce接口压测空引用异常求解
优惠活动
大模型
产品
解决方案
定价
更多

.NET WEB API多并发请求处理:GetNonce接口压测空引用异常求解

问题根因与修复方案

根因分析

你遇到的并发场景下空引用异常,核心是两类问题:

  • 代码中缺少必要的空值校验,部分分支下返回对象为null直接抛出异常
  • 依赖的服务类可能存在线程不安全实现,并发时共享变量被篡改导致返回结果为null

最容易触发你当前报错的两个隐藏点:

  1. 调用SendGetRequestToKMS返回空值时,你没有对response赋值,最终return的response为null直接抛出空引用
  2. 依赖的ProxyService、CertificateValidation等类如果内部使用了静态变量存储请求上下文,并发时多个请求会互相篡改值,导致返回的customers、custID等对象为null,后续直接访问属性时抛出异常

修复步骤

1. 新增dynamic请求参数空校验

你直接访问custReq的动态属性,没有校验字段是否存在,若请求缺mpn/manufacturer字段会直接返回null,调用ToString时抛异常:

if (custReq.mpn == null || custReq.manufacturer == null)
{
    customerResponse.responseMsg.StatusCode = HttpStatusCode.BadRequest;
    return ResponseMessage(customerResponse.responseMsg);
}
string mpnStr = custReq.mpn.ToString();
string manufacturerStr = custReq.manufacturer.ToString();

2. 新增客户端证书与客户ID空校验

X509Certificate2 clientCertforCustomer = Request.GetClientCertificate();
if (clientCertforCustomer == null)
{
    customerResponse.responseMsg.StatusCode = HttpStatusCode.Unauthorized;
    return ResponseMessage(customerResponse.responseMsg);
}
string custID = certificateValidation.CustomerInfoFromClientCert(clientCertforCustomer);
if (string.IsNullOrEmpty(custID))
{
    customerResponse.responseMsg.StatusCode = HttpStatusCode.Unauthorized;
    return ResponseMessage(customerResponse.responseMsg);
}

3. 新增代理服务返回结果空校验

var customers = proxyService.GetCustomerMPNInfo(custID, mpnStr);
if (customers == null || customers.CustomerID != custID || customers.CustomerMPN != mpnStr)
{
    customerResponse.responseMsg.StatusCode = HttpStatusCode.Unauthorized;
    return ResponseMessage(customerResponse.responseMsg);
}

4. 新增命令集合空校验

customerDetails = proxyService.GetMPNCommands(mpnStr);
if (customerDetails == null || customerDetails.Cust_Commands == null)
{
    customerResponse.responseMsg.StatusCode = HttpStatusCode.Unauthorized;
    return ResponseMessage(customerResponse.responseMsg);
}
foreach (var commandItem in customerDetails.Cust_Commands)
{
    if (commandItem == null || string.IsNullOrEmpty(commandItem.CommandName))
    {
        continue;
    }
    // 原有命令处理逻辑
}

5. 修复KMS请求返回空值的分支逻辑

string result = reqHandler.SendGetRequestToKMS(newReq, token, "Nonce");
if (string.IsNullOrEmpty(result))
{
    customerResponse.responseMsg.StatusCode = HttpStatusCode.InternalServerError;
    return ResponseMessage(customerResponse.responseMsg);
}
// 原有result拆分处理逻辑直接保留即可

并发优化建议

  • 不要每个请求都新建HttpClient,改为全局单例复用,避免高并发下socket耗尽:
// 在控制器类中定义静态单例
private static readonly HttpClient _httpClient = new HttpClient();
  • 检查ProxyService、CertificateValidation、TokenGenerator、RequestHandler的内部实现,移除请求相关的静态变量,改为局部变量存储,避免并发时数据互相篡改
  • 如果ProxyService是WCF客户端,建议使用单例或池化管理,不要每次请求都新建销毁

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.20 03:06:09