2

我想确切地知道为什么这不起作用:

[HttpPost]
public IHttpActionResult Post(Slack_Webhook json)
{
    return Ok(json.challenge);
}

public class Slack_Webhook
{
    public string type { get; set; }
    public string token { get; set; }
    public string challenge { get; set; }
}

官方文档说:

当事件发生时,我们将向该 URL 发送 HTTP POST 请求。输入 URL 后,我们将发送带有质询参数的请求,并且您的端点必须以质询值进行响应。

这是 Slack 发送的示例对象 (JSON):

{
    "token": "Jhj5dZrVaK7ZwHHjRyZWjbDl",
    "challenge": "3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P",
    "type": "url_verification"
}

编辑: 我可以写一本关于在这个问题上不起作用的代码的书......这是另一个不起作用的例子 - 仍然不知道出了什么问题:

[HttpPost]
public IHttpActionResult Post()
{
    var pairs = Request.GetQueryNameValuePairs();
    bool isValidToken = false;
    string c = "This does not work.";
    foreach(var pair in pairs)
    {
        if (pair.Key == "token")
        {
            if (pair.Value == "<UNIQUETOKEN>")
            {
                isValidToken = true;
            }
        }
        if (pair.Key == "challenge")
        {
            c = pair.Value;
        }
    }
    if (isValidToken == true)
    {
        return Json(new {challenge = c });
    }
    else
    {
        return BadRequest();
    }
}

EDIT2: 非常有趣的是,我从下面的代码中得到了 NULL 作为响应——这意味着收到的 POST 的正文是空的。任何有工作的 Slack-Integration 的人都可以试试吗?所以他们的网站是错误的,说明挑战是在正文中发送的——它还能在哪里?

// POST: api/Slack
[HttpPost]
public IHttpActionResult Post([FromBody]string json)
{
    return Json(json);
}

EDIT3: 此函数用于获取原始请求,但正文中没有任何内容 - 我没有解决方案.. Slack 的支持人员说,他们不知道 ASP.NET,我应该在这里问一个解决方案。我们又来了!;-)

[HttpPost]
public async Task<IHttpActionResult> ReceivePostAsync()
{
    string rawpostdata = await RawContentReader.Read(this.Request);
    return Json(new StringContent( rawpostdata));
}
public class RawContentReader
{
    public static async Task<string> Read(HttpRequestMessage req)
    {
        using (var contentStream = await req.Content.ReadAsStreamAsync())
        {
            contentStream.Seek(0, SeekOrigin.Begin);
            using (var sr = new StreamReader(contentStream))
            {
                return sr.ReadToEnd();
            }
        }
    }
}

结果(如预期)如下所示:

Our Request:
POST
"body": { 
     "type": "url_verification",
     "token": "<token>",
     "challenge": "<challenge>"
}
Your Response:
"code": 200
"error": "challenge_failed"
"body": {
 {"Headers":[{"Key":"Content-Type","Value":["text/plain; charset=utf-8"]}]} 
}

我想我遗漏了一些东西 - 还有另一种方法可以获取 POST-Request 的正文吗?我的意思是,我可以得到其他所有东西——除了身体(或者它说它是空的)。

EDIT4: 我试图用我发现的另一个函数来读取正文 - 没有成功,返回空字符串 - 但是为了让你知道我已经尝试过什么,这里是:

[HttpPost]
public IHttpActionResult ReceivePost()
{
    var bodyStream = new 
    StreamReader(HttpContext.Current.Request.InputStream);
    bodyStream.BaseStream.Seek(0, SeekOrigin.Begin);
    var bodyText = bodyStream.ReadToEnd();
    return Json(bodyText);
}

在尝试解决这个问题时,我学到了很多东西——但这似乎是不可能的,我想我永远不会单独解决它。数千种不同功能的尝试——我已经在所有 WebApi / ASP.NET / MVC / 中尝试了数百个参数和函数——为什么没有 BODY?它存在吗?他/她的名字是什么?它在哪里生活?如果我找到它,我真的很想和那个参数一起出去玩,它必须隐藏在彩虹尽头的一罐金子下。

4

3 回答 3

1

如果您可以使用 ASP.NET Core 2,这将达到目的:

public async Task<ActionResult> HandleEvent([FromBody] dynamic data)
    => new ContentResult {Content = data.challenge};
于 2018-02-05T09:40:32.090 回答
0

根据 OP 中链接的官方文档,您必须根据返回的内容类型来格式化您的响应。

您可能没有以预期格式之一返回值(挑战)。

收到事件后,使用挑战属性值以纯文本形式响应。在此示例中,可能是:

HTTP 200 OK
Content-type: text/plain
3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P

要执行上述操作,您需要以不同的方式返回您的请求

[HttpPost]
public IHttpActionResult Post([FromBody]Slack_Webhook json) {
    //Please verify that the token value found in the payload 
    //matches your application's configured Slack token.
    if (ModelState.IsValid && json != null && ValidToken(json.token)) {
        var response = Request.CreateResponse(HttpStatusCode.OK, json.challenge, "text/plain");
        return ResponseMessage(response);
    }
    return BadRequest();
}

文档还显示

甚至 JSON:

HTTP 200 OK
Content-type: application/json
{"challenge":"3eZbrw1aBm2rZgRNFdxV2595E9CY3gmdALWMmHkvFXO7tYXAYM8P"}

这又必须有一点不同的格式

[HttpPost]
public IHttpActionResult Post([FromBody]Slack_Webhook json) {
    //Please verify that the token value found in the payload 
    //matches your application's configured Slack token.
    if (ModelState.IsValid && json != null && ValidToken(json.token)) {
        var model = new { challenge = json.challenge };
        return Ok(model);
    }
    return BadRequest();
}
于 2017-09-09T14:33:19.370 回答
0

以下是访问数据的方法:

[HttpPost]  
[Route("something")]
public JsonResult DoSomething()
{
    var token = HttpContext.Request.Form["token"];

    // Is the same as:
    // var token = Request.Form["token"];

    return new JsonResult(token);
}

我建议使用请求箱进行进一步调试。

于 2019-11-12T17:37:39.230 回答