[开发者服务器响应] 发货请求调用失败. 【ret:172935489】
礼包道具发货回传[开发者服务器响应] 请检查回包格式是否正确. 参考接入文档[返回参数]
11:39:22 [平台请求] 测试开始
11:39:22 [平台请求] 发货请求开始
11:39:24 [平台请求] 发货请求数据: {"MiniGame":{"OrderId":"1243fefd-6e36-4809-917b-1a0c261bb3a8","IsPreview":1,"ToUserOpenid":"oJWFb5eqkz579Fo0F9LO2FoaKfpI","GoodsList":[{"Id":"1","Num":100}],"Zone":1001,"SendTime":1770003562,"BatchNum":1}}
11:39:24 [开发者服务器响应] 数据: {"errCode":0}
11:39:24 [开发者服务器响应] 发货请求调用失败. 【ret:172935489】
11:39:24 [开发者服务器响应] 请检查回包格式是否正确. 参考接入文档[返回参数]
哪里返回有问题
核心问题:返回参数字段名大小写不匹配 +缺少必传字段,导致平台校验失败
平台要求的返回格式是驼峰/首字母大写规范字段 (ErrCode、ErrMsg),但你的服务器实际返回的是小写字段 {"errCode":0},且缺少平台要求的必传字段 ErrMsg,平台无法识别合法回包,因此触发 ret:172935489 错误并提示「回包格式不正确」。
平台要求的正确返回格式(预览/正式发货成功通用)
必须同时包含 ErrCode(首字母大写E) 和 ErrMsg(首字母大写E,必传) 两个字段,JSON格式严格如下:
{"ErrCode":0,"ErrMsg":"Success"}
关键规范(平台强校验,缺一不可):
-
字段名:
ErrCode(E大写)、ErrMsg(E、M大写),不能是errCode/errcode/errorCode; -
字段完整性:无论
IsPreview=1(预览)还是IsPreview=0(正式发货),必须同时返回两个字段 ,ErrMsg不能为空; -
成功状态:
ErrCode固定为0,ErrMsg固定为Success(平台按此判定成功)。
错误根源对比
| 你的实际返回 | 平台要求的正确返回 | 错误点 |
|---|---|---|
{"errCode":0} |
{"ErrCode":0,"ErrMsg":"Success"} |
1. errCode 字母小写,平台无法识别;2. 缺少必传字段ErrMsg |
修复代码(直接替换你原有返回逻辑)
将你代码中返回 {"errCode":0} 的语句,替换为以下代码(保证字段名、字段完整性完全符合平台要求):
// 无论预览(IsPreview=1)还是正式发货,成功时均返回此格式
return new JsonResult(new { ErrCode = 0, ErrMsg = "Success" });
补充:失败场景的正确返回格式(参考)
若业务执行失败,需按平台规范返回非0错误码+对应描述,字段名仍严格保持ErrCode/ErrMsg:
// 示例:用户未注册失败(可根据实际业务调整错误码和描述)
return new JsonResult(new { ErrCode = 1001, ErrMsg = "User not registered" });
额外验证:与你Python服务端的格式保持一致
你Python服务端handle_deliver_goods接口中,成功返回的正是平台要求的规范格式 {"ErrCode":0,"ErrMsg":"Success"},C#服务器需与之一致,避免前后端格式混乱:
# 你Python代码中的正确返回(C#需完全对齐)
return web.json_response({'ErrCode': 0, 'ErrMsg': 'Success'})
修复后验证
修复后平台收到的开发者服务器响应数据应为:
{"ErrCode":0,"ErrMsg":"Success"}
此时平台能正确识别回包格式,ret:172935489 错误会直接解决,发货请求调用判定为成功。
总结
-
核心错误:返回字段
errCode小写(应为ErrCode),且缺少必传字段ErrMsg; -
唯一正确格式:
{"ErrCode":0,"ErrMsg":"Success"}(两个字段必须同时存在,字段名严格大小写); -
修复关键:替换返回语句为包含
ErrCode(大写E)和ErrMsg="Success"的JsonResult; -
一致性:C#服务器返回格式需与Python服务端、平台接入文档完全对齐。
return new JsonResult(new { ErrCode = 0, ErrMsg = "Success" }); 返回的字符串还是小写的,{
"errCode": 0,
"errMsg": "Success"
}
问题根源
System.Text.Json 序列化匿名对象时,默认采用小驼峰命名策略 (首字母小写),导致定义的ErrCode/ErrMsg被自动转为errCode/errMsg,不符合平台要求的大驼峰(PascalCase) 字段名规范,这是返回字段小写的核心原因。
核心解决方案:指定序列化命名策略为大驼峰(PascalCase)
需通过JsonResult的序列化配置,强制指定命名策略为大驼峰,让字段名保持首字母大写 ,与平台要求完全匹配。以下提供 2种可行写法(直接替换原有返回代码即可,推荐写法1更简洁):
写法1:简洁版(直接配置JsonResult的SerializerSettings)
return new JsonResult(new { ErrCode = 0, ErrMsg = "Success" })
{
SerializerSettings = new Newtonsoft.Json.JsonSerializerSettings
{
ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver
{
// 核心配置:强制大驼峰命名,字段名首字母保持大写
NamingStrategy = new Newtonsoft.Json.Serialization.PascalCaseNamingStrategy()
}
}
};
写法2:完整版(先定义配置对象,再传入,可读性更高)
// 1. 定义大驼峰序列化配置
var jsonSettings = new Newtonsoft.Json.JsonSerializerSettings
{
ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver
{
NamingStrategy = new Newtonsoft.Json.Serialization.PascalCaseNamingStrategy()
}
};
// 2. 传入配置返回JsonResult,确保字段首字母大写
return new JsonResult(new { ErrCode = 0, ErrMsg = "Success" }, jsonSettings);
关键说明
-
命名策略作用 :
PascalCaseNamingStrategy是大驼峰命名策略,会强制保留字段定义时的首字母大写格式(ErrCode→ErrCode、ErrMsg→ErrMsg),彻底解决默认小驼峰的问题; -
无需改字段定义 :仍使用原有匿名对象
new { ErrCode = 0, ErrMsg = "Success" }即可,配置会自动保证序列化后的大小写; -
依赖说明 :上述代码使用的是Newtonsoft.Json(Json.NET) 相关类(ASP.NET Core项目默认集成,无需额外安装NuGet包),若提示命名空间缺失,添加以下引用即可:
using Newtonsoft.Json; using Newtonsoft.Json.Serialization;
修复后验证
配置完成后,接口返回的JSON会严格保持平台要求的格式,无任何大小写转换:
{
"ErrCode": 0,
"ErrMsg": "Success"
}
此时平台能正确识别回包格式,ret:172935489 错误会直接解决,发货请求调用判定为成功。
拓展:失败场景统一格式(复用相同配置)
若失败时也需返回规范的大驼峰字段,直接复用上述序列化配置即可,保证前后返回格式一致:
// 失败示例:用户未注册,复用大驼峰配置
var jsonSettings = new Newtonsoft.Json.JsonSerializerSettings
{
ContractResolver = new Newtonsoft.Json.Serialization.DefaultContractResolver
{
NamingStrategy = new Newtonsoft.Json.Serialization.PascalCaseNamingStrategy()
}
};
return new JsonResult(new { ErrCode = 1001, ErrMsg = "User not registered" }, jsonSettings);
// 最终返回:{"ErrCode":1001,"ErrMsg":"User not registered"}
总结
-
字段小写的根本原因:
System.Text.Json对匿名对象默认采用小驼峰序列化; -
核心修复:为
JsonResult指定PascalCaseNamingStrategy(大驼峰)序列化配置; -
关键要点:使用Newtonsoft.Json的配置类,无需修改原有字段定义,直接复用即可;
-
修复后效果:返回的JSON字段严格保持
ErrCode/ErrMsg首字母大写,完全符合平台接入文档要求。
命名空间Newtonsoft.Json.Serialization中不存在类型或命名空间名"PascalCaseNamingStrategy"(是否缺少程序集引用?)
错误根源
项目中使用的 Newtonsoft.Json 版本过低 (低于10.0.1),该版本尚未引入PascalCaseNamingStrategy类,导致编译器无法识别该类型,触发CS0234命名空间错误。
核心解决方案(2种可选,均无需升级NuGet包,直接可用)
方案1:自定义大驼峰命名策略(推荐,无版本依赖,通用所有Newtonsoft.Json版本)
手动实现一个极简的大驼峰命名解析器,替代缺失的PascalCaseNamingStrategy,代码可直接嵌入控制器使用:
// 第一步:在WeChatController.cs中添加自定义大驼峰命名策略类(放在控制器类外部/内部均可)
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
// 自定义大驼峰命名策略:强制保留字段原名称(首字母大写不转换)
public class CustomPascalCaseNamingStrategy : NamingStrategy
{
protected override string ResolvePropertyName(string name)
{
// 核心逻辑:直接返回字段原名称,不做任何大小写转换
return name;
}
}
// 第二步:使用自定义策略替换原有代码,返回正确的大驼峰JSON
if (success)
{
var jsonSettings = new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
// 使用自定义的大驼峰命名策略
NamingStrategy = new CustomPascalCaseNamingStrategy()
}
};
return new JsonResult(new { ErrCode = 0, ErrMsg = "Success" }, jsonSettings);
}
方案2:极简版(直接禁用命名转换,一行配置,最简洁)
无需自定义类,直接设置DefaultContractResolver的三个核心属性,强制保留字段原名称(首字母大写),完全适配低版本Newtonsoft.Json:
// 直接使用,无需额外定义类,一行配置解决大小写问题
if (success)
{
var jsonSettings = new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
// 核心配置:禁用所有命名转换,保留字段原定义的首字母大写
NamingStrategy = new DefaultNamingStrategy
{
ProcessDictionaryKeys = false,
OverrideSpecifiedNames = false,
ProcessExtensionDataNames = false
}
}
};
return new JsonResult(new { ErrCode = 0, ErrMsg = "Success" }, jsonSettings);
}
方案3(可选):升级Newtonsoft.Json到高版本(彻底解决类型缺失)
若希望使用原生PascalCaseNamingStrategy,可通过NuGet升级包,步骤如下:
-
右键项目 → 管理NuGet程序包 → 切换到已安装标签;
-
找到Newtonsoft.Json → 点击更新 ,选择10.0.1及以上版本(推荐最新稳定版);
-
升级完成后,原有使用
PascalCaseNamingStrategy的代码即可正常编译,无需修改。
关键说明
-
两种方案的效果一致 :最终返回的JSON均为平台要求的标准格式
{"ErrCode":0,"ErrMsg":"Success"},字段首字母严格大写,无任何转换; -
无额外依赖:两种方案均基于项目已引用的Newtonsoft.Json,无需安装新包,直接复制代码即可使用;
-
兼容所有场景:预览(IsPreview=1)和正式发货(IsPreview=0)的成功/失败返回,均可复用此配置,保证回包格式统一;
-
失败场景复用示例:
// 失败时同样使用该配置,返回规范大驼峰格式
var jsonSettings = new JsonSerializerSettings
{
ContractResolver = new DefaultContractResolver
{
NamingStrategy = new DefaultNamingStrategy
{
ProcessDictionaryKeys = false,
OverrideSpecifiedNames = false,
ProcessExtensionDataNames = false
}
}
};
return new JsonResult(new { ErrCode = 1001, ErrMsg = "User not registered" }, jsonSettings);
修复后验证
无论使用方案1还是方案2,接口最终返回的JSON将严格保持首字母大写,完全符合平台接入要求:
{
"ErrCode": 0,
"ErrMsg": "Success"
}
此时平台将正确识别回包格式,ret:172935489 错误会彻底解决,发货请求调用判定为成功。
总结
-
错误原因:Newtonsoft.Json版本过低,缺失
PascalCaseNamingStrategy类; -
最优解:方案2(极简版),无需自定义类,一行配置禁用命名转换,直接保留字段原名称;
-
次优解:方案1(自定义策略),通用所有版本,可复用在多个接口;
-
彻底解:方案3(升级包),适合后续需要使用高版本特性的场景;
-
核心效果:三种方案均能保证返回
ErrCode/ErrMsg首字母大写,完全匹配平台回包规范。