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

Actions on Google智能家居项目无法解析QUERY响应问题排查

问题场景

在Google Home应用中对灯泡执行开/关操作时,平台会先后发送EXECUTE请求、用于状态校验的QUERY请求,该流程逻辑本身符合预期,但出现Actions on Google项目无法解析我方返回的QUERY响应的故障。

问题说明
  • 首先明确:我方不存在C# JSON解析类相关基础问题,故障表现为Actions on Google无法识别我方返回的QUERY响应。我方已严格参照Google官方文档规定的格式构造响应内容,但Web控制台持续报错,暂未定位问题根因。
  • Google Cloud Console中抛出的错误日志如下:
{
  "insertId": "166g06lg15lgekt",
  "jsonPayload": {
      "executionLog": {
          "executionResults": [
              {
                "actionResults": [
                    {
                        "action": {
                            "actionType": "STATE_QUERY"
                        },
                        "device": {
                            "deviceType": "OUTLET"
                        },
                        "status": {
                            "externalDebugString": "JSON payload not an object.",
                            "isSuccess": false,
                            "statusType": "PARTNER_RESPONSE_INVALID_PAYLOAD"
                        }
                    }
                ],
                "executionType": "PARTNER_CLOUD",
                "latencyMsec": "191",
                "requestId": "4734217757620110233"
            }
        ]
    },
    "locale": "en-US"
},
"logName": "projects/smartlightproject-f47f4/logs/assistant_smarthome%2Fassistant_smarthome_logs",
"receiveTimestamp": "2022-07-13T13:23:04.088211105Z",
"resource": {
    "labels": {
        "project_id": "smartlightproject-f47f4"
    },
    "type": "assistant_action_project"
},
"severity": "ERROR",
"timestamp": "2022-07-13T13:23:04.088211105Z"
}
  • 我方接收到的QUERY请求报文如下:
{
    "inputs": [
        {
            "intent": "action.devices.QUERY",
            "payload": {
                "devices": [
                    {
                        "customData": {
                            "barValue": true,
                            "bazValue": "foo",
                            "fooValue": 74
                        },
                        "id": "123"
                    }
                ]
            }
        }
    ],
    "requestId": "5460596871498683621"
}
  • 我方预期返回的QUERY响应报文如下:
{
    "requestId": "5460596871498683621",
    "payload": {
        "devices": {
            "123": {
                "on": true,
                "online": true
            }
        }
    }
}
  • 我方基于ASP.NET编写本地履约逻辑,当前返回QUERY响应的实现代码如下:
var queryObj = JsonConvert.DeserializeObject<dynamic>("{\"requestId\":\"" + requestId + "\",\"payload\":{\"devices\":{\"123\":{\"on\":true,\"online\":true}}}}}");
_logger.LogInformation("Odpowiedź na żądanie QUERY." + originalRequest + "\n\n" + JsonConvert.SerializeObject((object)queryObj));
return Ok((object)queryObj);
故障根因

报错JSON payload not an object已经明确说明Google侧收到的响应不是合法JSON对象,问题出在ASP.NET接口的响应序列化环节,和Google侧解析逻辑无关:

  1. 现有代码逻辑冗余且存在序列化兼容问题:先手动拼接JSON字符串,反序列化为Newtonsoft.Json的JObject(dynamic类型)后再传给Ok()方法。如果项目没有显式配置Newtonsoft.Json作为Web API的响应序列化器,ASP.NET Core默认的System.Text.Json无法正确识别JObject类型,会把JToken的内部属性(Path、Root、ChildrenTokens等)全部序列化,输出结构完全异常的内容,甚至直接生成非对象结构的JSON。
  2. 手动拼接JSON字符串的写法本身存在转义风险,只要requestId包含引号、特殊转义字符,就会生成非法JSON,直接触发解析失败。
  3. 日志中打印的是手动调用JsonConvert.SerializeObject得到的字符串,和Web API框架最终序列化后写入响应流的内容并不一致,所以才会出现“自认格式正确但平台始终报错”的矛盾情况。
修复方案

优先选择无依赖的稳妥方案,彻底规避框架序列化行为的不确定性:

  1. 废弃“拼JSON字符串→反序列化→传回框架再序列化”的冗余写法,直接用匿名对象构造响应结构,手动序列化得到标准JSON字符串后,直接返回指定application/json类型的内容结果,跳过框架的二次序列化逻辑。
    修复后的参考代码:
// 用匿名对象构造响应结构,从根源避免字符串拼接的转义错误
var queryResponse = new
{
    requestId = requestId,
    payload = new
    {
        devices = new Dictionary<string, object>
        {
            ["123"] = new { on = true, online = true }
        }
    }
};
// 统一用Newtonsoft序列化,保证JSON结构完全符合预期
var responseJson = JsonConvert.SerializeObject(queryResponse);
_logger.LogInformation("QUERY请求处理完成,原始请求:{OriginalRequest}\n响应内容:{ResponseJson}", originalRequest, responseJson);
// 直接输出JSON字符串,指定正确Content-Type,避免框架二次序列化导致结构异常
return Content(responseJson, "application/json");
  1. 部署后先用Postman、curl等工具直接调用QUERY接口,确认响应体结构和预期完全一致后,再到Google平台重试即可。
  2. 如果希望保留Ok()返回对象的编码习惯,需要在服务配置阶段显式指定MVC使用Newtonsoft.Json作为序列化器,否则JObject类型无法被默认序列化器正确处理,配置代码如下:
// Program.cs中配置控制器服务时,追加NewtonsoftJson序列化支持
builder.Services.AddControllers().AddNewtonsoftJson();

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 15:09:18