feat(wechat): Enforce HTTP/1.1 protocol and improve template message request handling
All checks were successful
continuous-integration/drone/push Build is passing

- Set HTTP client to use HTTP/1.1 with exact version policy for WeChat API compatibility
- Replace PostAsJsonAsync with manual HttpRequestMessage construction for better control
- Add User-Agent and Accept headers to template message requests
- Use StringContent with explicit UTF-8 encoding for JSON serialization
- Update error logging to include request body and remove sensitive app secret from logs
- Improve diagnostic information for template message failures
This commit is contained in:
zpc 2026-03-29 21:09:26 +08:00
parent df9a1d40c9
commit 125ff21b77
2 changed files with 15 additions and 5 deletions

View File

@ -24,6 +24,8 @@ public static class InfrastructureExtensions
services.AddHttpClient("WeChat", client =>
{
client.Timeout = TimeSpan.FromSeconds(30);
client.DefaultRequestVersion = new Version(1, 1);
client.DefaultVersionPolicy = HttpVersionPolicy.RequestVersionExact;
});
services.AddHttpClient("WeChatPay", client =>
{

View File

@ -465,16 +465,24 @@ public class WeChatService : IWeChatService
};
}
var response = await _httpClient.PostAsJsonAsync(url, requestBody);
var jsonContent = System.Text.Json.JsonSerializer.Serialize(requestBody);
var httpRequest = new HttpRequestMessage(HttpMethod.Post, url)
{
Content = new StringContent(jsonContent, Encoding.UTF8, "application/json")
};
httpRequest.Headers.TryAddWithoutValidation("User-Agent", "XiangYi/1.0");
httpRequest.Headers.TryAddWithoutValidation("Accept", "application/json");
var response = await _httpClient.SendAsync(httpRequest);
var responseContent = await response.Content.ReadAsStringAsync();
// 非200时打印完整诊断信息包括响应头
if (!response.IsSuccessStatusCode || string.IsNullOrWhiteSpace(responseContent))
{
var headers = string.Join(", ", response.Headers.Select(h => $"{h.Key}={string.Join(";", h.Value)}"));
_logger.LogWarning("发送服务号模板消息失败: StatusCode={StatusCode}, Headers={Headers}, AppId={AppId}, AppSecret={AppSecret}, ToUser={ToUser}, TemplateId={TemplateId}, AccessToken={AccessToken}, IsRetry={IsRetry}, Response={Response}",
(int)response.StatusCode, headers, _options.ServiceAccount?.AppId, _options.ServiceAccount?.AppSecret,
request.ToUser, request.TemplateId, accessToken, isRetry, responseContent);
var respHeaders = string.Join(", ", response.Headers.Select(h => $"{h.Key}={string.Join(";", h.Value)}"));
_logger.LogWarning("发送服务号模板消息失败: StatusCode={StatusCode}, Headers={Headers}, AppId={AppId}, ToUser={ToUser}, TemplateId={TemplateId}, AccessToken={AccessToken}, IsRetry={IsRetry}, RequestBody={RequestBody}, Response={Response}",
(int)response.StatusCode, respHeaders, _options.ServiceAccount?.AppId,
request.ToUser, request.TemplateId, accessToken, isRetry, jsonContent, responseContent);
}
// HTTP 412 表示 access_token 失效,强制刷新后重试一次