团队对话的 Webhook 订阅不适用于 WCF 中继

Webhook Subscription for Teams Conversation not working with WCF Relay

有人可以帮我解决这个问题吗?我无法从出错的地方进行调试。基本上,我在 Azure 中使用 WCF 中继创建了一个 WCF Rest API WebService,以便在 on-premise 和 Azure 之间建立混合连接。此外,如果我忽略任何证书验证,则该端点用于 on-premise,因为它是 self-signed 证书,但是在进行 API 调用时,我使用的是提供的 base64 编码的 public 密钥在 Azure 中发布时通过 WCF Relay。

WCF 合同和实施:

Contract Interface

Implementation

我成功地获得了 WCF 服务中的 "validationToken" 并且 return 立即在 5 秒内获得相同的 validationToken。 returning 后,它总是出错显示此消息。

Postman Client For Sending HTTP Request

Error Response and no subscription created

编辑

WCF 合同

[OperationContract]
        [WebInvoke(Method = "POST", UriTemplate = "webhookForConservation?validationToken={validationToken}", 
            BodyStyle = WebMessageBodyStyle.Bare)]
        string webhookForConservation(WebhookPayload data, string validationToken);

WCF 实现:

第一种方法 return 200 OK 状态代码:

public string webhookForConservation(WebhookPayload data, string validationToken = "")
        {
            ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
            var client = new HttpClient();
            client.DefaultRequestHeaders.Add("Accept", "text/plain");
            client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json");
            HttpResponseMessage response = null;
            WebOperationContext ctx = WebOperationContext.Current;
            if (validationToken != null && validationToken != "")
            {
                response = client.PostAsync("http://localhost:8080/conversationWebHook/conversationSubscription?validationToken=" + validationToken, null).Result;
                var apiContent = response.Content.ReadAsStringAsync().Result;
                ctx.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.OK;
                ctx.OutgoingResponse.ContentType = "text/plain";
                return apiContent;
            }
            else
            {
                StringContent strContent = new StringContent(DataContractJsonSerializerHelper.SerializeJson(data));
                strContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
                response = client.PostAsync("http://localhost:8080/conversationWebHook/conversationSubscription", strContent).Result;
            }
            var result = (response != null) ? response.Content.ReadAsStringAsync().Result : "";
            ctx.OutgoingResponse.StatusCode = System.Net.HttpStatusCode.OK;
            return result;
        }

return200状态码的第二种方法:

public WebFaultException<string> webhookForConservation(WebhookPayload data, string validationToken="")
        {
            ServicePointManager.ServerCertificateValidationCallback = (sender, cert, chain, sslPolicyErrors) => true;
            var client = new HttpClient();
            client.DefaultRequestHeaders.Add("Accept", "text/plain");
            client.DefaultRequestHeaders.TryAddWithoutValidation("Content-Type", "application/json");
            HttpResponseMessage response = null;
            if (validationToken != null && validationToken != "")
            {
                response = client.PostAsync("http://localhost:8080/conversationWebHook/conversationSubscription?validationToken=" + validationToken, null).Result;
                var apiContent = response.Content.ReadAsStringAsync().Result;
                return new WebFaultException<string>(apiContent, HttpStatusCode.OK);
            }
            else
            {
                StringContent strContent = new StringContent(DataContractJsonSerializerHelper.SerializeJson(data));
                strContent.Headers.ContentType = MediaTypeHeaderValue.Parse("application/json");
                response = client.PostAsync("http://localhost:8080/conversationWebHook/conversationSubscription", strContent).Result;
            }
            var result = (response != null) ? response.Content.ReadAsStringAsync().Result : "";
            return new WebFaultException<string>(result, HttpStatusCode.OK); ;
        }

在 returning 来自 WCF 服务的 200 OK 响应代码后看到相同的错误

直接用 Postman 调用 Relay WCF API:

Headers:

预先感谢您的所有帮助。

有两个问题阻止了 WCF 中继正常工作:

  • 中继未将响应内容类型设置为 text/plain,已通过 ctx.OutgoingResponse.ContentType = "text/plain"
  • 修复
  • 中继正在向所需的响应主体添加一个 XML 包装器,已通过将 return 值更改为 Stream
  • 解决了这个问题