
Webhook 返回的数据被双重包裹:外层是 JSON 对象,内层 data 字段值却是 JSON 字符串(而非对象),需先剥离冗余花括号,再逐层反序列化,才能安全提取真实业务字段。
webhook 返回的数据被双重包裹:外层是 json 对象,内层 data 字段值却是 json 字符串(而非对象),需先剥离冗余花括号,再逐层反序列化,才能安全提取真实业务字段。
在实际集成第三方消息服务(如 WhatsApp、SMS 网关等)时,常遇到类似 Webhook 响应:看似 JSON,实则 data 字段为JSON 字符串的字符串——即“JSON-in-JSON”嵌套结构。示例响应如下:
{{
"data": "{"event":"INBOX","from":"966******","to":"966******","text":"https:\/\/fs.magicrepository.com\/incoming\/4ef5613331213ab08888fb7cf72f332c.jpg","alias":"","pushname":"","profilepicture":""}"
}}
注意:开头和结尾各有两个花括号 {{ 和 }},这并非标准 JSON,而是服务端错误或模板渲染残留(如 Handlebars 模板误输出),必须先清理。
✅ 正确解析步骤(C# 实现)
-
清理外层非法括号:使用
input[1..^1](C# 8+ 范围语法)移除首尾各一个{和},得到合法 JSON 字符串; -
解析外层 JSON:提取
data字段的原始字符串值; -
解析内层 JSON 字符串:将
data字段内容作为独立 JSON 反序列化为对象。
完整可运行代码(基于 System.Text.Json):
using System;
using System.Text.Json;
string input = @"{{ ""data"": ""{""event"":""INBOX"",""from"":""966******"",""to"":""966******"",""text"":""https://fs.magicrepository.com/incoming/4ef5613331213ab08888fb7cf72f332c.jpg"",""alias"":""",""pushname"":""",""profilepicture"":"""}"" }}";
// Step 1: Trim outer double braces (handle edge cases safely)
if (input.StartsWith("{{") && input.EndsWith("}}"))
{
input = input[2..^2].Trim(); // Remove first 2 and last 2 chars
}
// Step 2: Parse outer JSON
using JsonDocument outerDoc = JsonDocument.Parse(input);
JsonElement root = outerDoc.RootElement;
string innerJson = root.GetProperty("data").GetString()
?? throw new InvalidOperationException("Missing or null 'data' field");
// Step 3: Parse inner JSON string
using JsonDocument innerDoc = JsonDocument.Parse(innerJson);
JsonElement payload = innerDoc.RootElement;
// Now safely access fields:
string eventValue = payload.GetProperty("event").GetString(); // "INBOX"
string from = payload.GetProperty("from").GetString(); // "966******"
string text = payload.GetProperty("text").GetString(); // URL
⚠️ 注意事项与最佳实践
-
不要用
JsonConvert.DeserializeObject<dynamic></dynamic>粗暴处理:易因类型不匹配抛异常,且无法静态校验字段; -
始终验证字段存在性:
GetProperty(...)前建议用TryGetProperty()避免KeyNotFoundException; -
PHP 对应方案简述:
$cleaned = trim($input, '{}'); // 移除外层 {} $outer = json_decode($cleaned, true); $inner = json_decode($outer['data'], true); // $inner 是关联数组 echo $inner['event']; // INBOX - 根本解决建议:联系 API 提供方修正响应格式——标准做法应直接返回扁平化 JSON,而非字符串嵌套。若无法修改,务必在客户端做健壮性封装(如重试、日志、fallback 默认值)。
通过分层解析 + 显式错误处理,即可稳定提取 Webhook 中的真实业务数据,避免因格式陷阱导致集成失败。











