当我尝试执行斜杠命令时,我在 ASP.NET Core MVC 中接收来自 Slack API 的 POST 请求时遇到问题。我确实将该应用程序托管在专用服务器上(具有有效的 SSL 证书),并且可以通过 Slack API 访问它。
这是我用来从 Slack API 接收 POST 请求的方法:
[HttpPost("slash/dispatch")]
[Consumes("application/x-www-form-urlencoded")]
public async Task<ActionResult<string>> ReceiveSlashDispatchEvent([FromForm] string data)
{
try
{
// string data;
// using (var sr = new StreamReader(Request.Body))
// {
// data = await sr.ReadToEndAsync();
// }
await _slackDispatchBotService.PostMessage(new SlackChatSendRequest
{
Channel = "XXXXXXX",
Message = data
});
}
catch (Exception e)
{
return Ok($"Error: {e.Message}");
}
return Ok();
}
现在,如果我没有在方法签名中声明任何内容,它实际上会正确输入。我已经成功地使用该评论部分检索请求正文并直接在流中读取。
这是我之前在方法体中使用的类定义(每次都会失败):
public class SlackSlashDispatchEvent
{
public string Token { get; set; }
[JsonPropertyName("team_id")]
public string TeamId { get; set; }
[JsonPropertyName("team_domain")]
public string TeamDomain { get; set; }
[JsonPropertyName("enterprise_id")]
public string EnterpriseId { get; set; }
[JsonPropertyName("enterprise_name")]
public string EnterpriseName { get; set; }
[JsonPropertyName("channel_id")]
public string ChannelId { get; set; }
[JsonPropertyName("channel_name")]
public string ChannelName { get; set; }
[JsonPropertyName("user_id")]
public string UserId { get; set; }
[JsonPropertyName("user_name")]
public string UserName { get; set; }
public string Command { get; set; }
public string Text { get; set; }
[JsonPropertyName("response_url")]
public string ResponseUrl { get; set; }
[JsonPropertyName("trigger_id")]
public string TriggerId { get; set; }
}
我还访问了
Request.QueryString
字段,该字段始终为空。有人建议我应该在哪里进一步调查吗?
到目前为止,我正在使用的框架似乎无法成功地将请求正文数据转换为我在方法签名中定义的任何类型。不幸的是,我很难确定接下来的故障排除步骤是什么。
编辑 虽然我强烈认为有一种更优雅的方法可以做到这一点,但我已经实施了一个解决方案。我确实使用流阅读器来获取请求正文。
string data;
using (var sr = new StreamReader(Request.Body))
{
data = await sr.ReadToEndAsync();
}
然后我编写了这个方法来解析 URLEncoded 查询参数(出于某种原因从 Slack API 在请求正文中发送)以将其转换为我想要的类:
public static SlackSlashDispatchEvent ParseQueryString(string queryString)
{
var dict = new Dictionary<string, string>();
var items = queryString.Split('&');
foreach (var item in items)
{
var keyValue = item.Split('=');
var key = HttpUtility.UrlDecode(keyValue[0]);
var value = HttpUtility.UrlDecode(keyValue[1]);
dict.Add(key, value);
}
var stringifyDict = JsonSerializer.Serialize(dict);
return JsonSerializer.Deserialize<SlackSlashDispatchEvent>(stringifyDict)!;
}
序列化然后反序列化字典感觉效率低下,但这是我现在能想到的最好的。
**我将从我对原始帖子的编辑中复制/粘贴此内容。我会称之为答案。
编辑虽然我有一种更优雅的方式来做到这一点的强烈感觉,但我已经实施了一个解决方案。我确实使用流阅读器来获取请求正文。
string data;
using (var sr = new StreamReader(Request.Body))
{
data = await sr.ReadToEndAsync();
}
然后我编写了这个方法来解析 URLEncoded 查询参数(出于某种原因从 Slack API 在请求正文中发送)以将其转换为我想要的类:
public static SlackSlashDispatchEvent ParseQueryString(string queryString)
{
var dict = new Dictionary<string, string>();
var items = queryString.Split('&');
foreach (var item in items)
{
var keyValue = item.Split('=');
var key = HttpUtility.UrlDecode(keyValue[0]);
var value = HttpUtility.UrlDecode(keyValue[1]);
dict.Add(key, value);
}
var stringifyDict = JsonSerializer.Serialize(dict);
return JsonSerializer.Deserialize<SlackSlashDispatchEvent>(stringifyDict)!;
}
序列化然后反序列化字典感觉效率低下,但这是我现在能想到的最好的。