在Magento2 自定义地址字段提交数据出现下面出错误
{ "message": "\"%fieldName\" is not supported. Correct the field name and try again.", "parameters": { "fieldName": "ShippingEmail" } }
- 关键文件:
vendor/magento/framework/Webapi/ServiceInputProcessor.php
在 Magento 2 的 API 请求处理流程中,ServiceInputProcessor.php
的执行时机是 在 saveAddressInformation
方法被调用之前。它的作用是 对传入的请求参数进行验证、转换和规范化,确保它们符合目标方法的参数要求。
执行顺序详解
- HTTP 请求进入 Magento
(例如POST /rest/V1/carts/mine/shipping-information
) - 路由匹配
Magento 根据webapi.xml
找到对应的服务方法:xml<route url=”/V1/carts/mine/shipping-information” method=”POST”> <service class=”Magento\Checkout\Api\ShippingInformationManagementInterface” method=”saveAddressInformation”/> </route> - 参数处理阶段(
ServiceInputProcessor
介入)ServiceInputProcessor.php
解析请求的 JSON/XML 数据。- 检查字段名是否合法(例如拒绝
ShippingEmail
,只允许email
)。 - 将原始数据转换为 PHP 对象(如
ShippingInformationInterface
实例)。
- 方法调用
参数验证通过后,才调用saveAddressInformation($cartId, $addressInformation)
。 - 业务逻辑执行
saveAddressInformation
方法内部处理配送信息保存。
关键代码流程
- HTTP Request
↓ - Magento\Webapi\Controller\Rest::dispatch()
↓ - Magento\Webapi\Controller\Rest\InputParamsResolver::resolve()
↓ - Magento\Framework\Webapi\ServiceInputProcessor::process() // 参数验证和转换
↓ - ShippingInformationManagement::saveAddressInformation() // 业务方法执行
为什么你的错误发生在 ServiceInputProcessor
?
从你的错误信息可以看出:
json
{ "message": "\"%fieldName\" is not supported.", "parameters": {"fieldName": "ShippingEmail"}, "trace": "...ServiceInputProcessor.php..." }
- 错误来源:
ServiceInputProcessor.php
在验证参数时发现非法字段ShippingEmail
。 - 根本原因:
email
必须放在shipping_address
下,而不是extension_attributes
或根层级。
如何验证执行顺序?
1. 在 ServiceInputProcessor.php
中加日志
修改 vendor/magento/framework/Webapi/ServiceInputProcessor.php
(仅限调试):
public function process($serviceClass, $serviceMethod, array $inputData)
{
error_log("正在处理参数,准备调用 $serviceClass::$serviceMethod");
error_log("输入数据: " . print_r($inputData, true));
// ...原逻辑
}
2. 在 saveAddressInformation
中加日志
public function saveAddressInformation($cartId, $addressInformation)
{
error_log("已进入 saveAddressInformation");
// ...原逻辑
}
关键结论:
- 参数错误(如字段名不合法)会在
ServiceInputProcessor
阶段直接拦截,不会进入saveAddressInformation
。 - 确保请求数据的字段名和层级完全匹配 Magento 的 API 定义.