在通过V4 C#开发的聊天机器人中,单击自适应卡中的“提交”按钮后,如何解决与Web聊天频道中出现500错误有关的问题?
按照@ mdrichardson-msft的建议创建此新问题,因为该问题是下面的堆栈溢出问题中的特定/其他问题:
出现我的问题
我有一个瀑布对话类,我在其中使用自适应卡选择日期时间输入,并在步骤1中使用提交按钮,然后在步骤2中单击步骤1中的提交后,将捕获并处理这些值。
当前如上述链接中所述(问题将在下面进行详细说明),当单击自适应卡中的“提交”按钮时,浏览器出现500错误:
第1步:
我正在显示具有两个日期和时间输入的自适应卡,一个用于启动,另一个用于停止
实际结果:
自适应程序可以在模拟器和网络聊天频道中成功显示,没有任何问题
步骤2:当我在步骤1中显示的自适应卡上单击SetSchedule时,应该在步骤2中捕获值并显示在屏幕上
实际结果:
在模拟器中工作正常,但在Web Chat通道漫游器中则不能。我在网络聊天频道BOT中遇到错误。请找到用于访问漫游器的HTML文件,瀑布对话框类以及随附的Adaptive card json文件以供参考。与此同时,请找到网络聊天频道中附带的错误屏幕截图,以供参考。我也通过TestinWebChat进行了测试,它也在这里抛出错误。
我已通过VSTS 2019发布了该文件,但未附带任何错误的屏幕快照,以供参考” publishsuceeded_thruvisualStudio2019.jpg”。
您能否像引导问题一样指导我解决此问题?请求您的即时帮助,这会阻止我的工作。
语言:C# SDK:V4 发布时间:Visual Studio 2019
HTML:
<!DOCTYPE html>
<html lang="en-US">
<head>
<title>Web Chat: Custom style options</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!--
For demonstration purposes, we are using the development branch of Web Chat at "/master/webchat.js".
When you are using Web Chat for production, you should use the latest stable release at "/latest/webchat.js",
or lock down on a specific version with the following format: "/4.1.0/webchat.js".
-->
<script src="https://cdn.botframework.com/botframework-webchat/master/webchat.js"></script>
<style>
html, body {
height: 100%
}
body {
margin: 0
}
#webchat {
height: 100%;
width: 100%;
}
</style>
</head>
<body>
<div id="webchat" role="main">
</div>
<script>
(async function () {
// In this demo, we are using Direct Line token from MockBot.
// To talk to your bot, you should use the token exchanged using your Direct Line secret.
// You should never put the Direct Line secret in the browser or client app.
// https://docs.microsoft.com/en-us/azure/bot-service/rest-api/bot-framework-rest-direct-line-3-0-authentication
// Token is found by going to Azure Portal > Your Web App Bot > Channels > Web Chat - Edit > Secret Keys - Show
// It looks something like this: pD*********xI.8ZbgTHof3GL_nM5***********aggt5qLOBrigZ8
const token = '<<Your Direct Line Secret Key>>';
// You can modify the style set by providing a limited set of style options
const styleOptions = {
botAvatarImage: 'https://docs.microsoft.com/en-us/azure/bot-service/v4sdk/media/logo_bot.svg?view=azure-bot-service-4.0',
botAvatarInitials: 'BF',
userAvatarImage: 'https://avatars1.githubusercontent.com/u/45868722?s=96&v=4',
userAvatarInitials: 'WC',
bubbleBackground: 'rgba(0, 0, 255, .1)',
bubbleFromUserBackground: 'rgba(0, 255, 0, .1)'
};
// We are using a customized store to add hooks to connect event
const store = window.WebChat.createStore({}, ({ dispatch }) => next => action => {
if (action.type === 'DIRECT_LINE/CONNECT_FULFILLED') {
// When we receive DIRECT_LINE/CONNECT_FULFILLED action, we will send an event activity using WEB_CHAT/SEND_EVENT
dispatch({
type: 'WEB_CHAT/SEND_EVENT',
payload: {
name: 'webchat/join',
value: { language: window.navigator.language }
}
});
}
return next(action);
});
window.WebChat.renderWebChat({
directLine: window.WebChat.createDirectLine({ token }),
styleOptions,store
}, document.getElementById('webchat'));
document.querySelector('#webchat > *').focus();
})().catch(err => console.error(err));
</script>
</body>
</html>
代码:
using Microsoft.Bot.Builder.Dialogs;
using Microsoft.Bot.Schema;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace EchoBot.Dialogs
{
public class Adaptivecarddialog : WaterfallDialog
{
public const string cards = @"./AdaptiveCard.json";
public Adaptivecarddialog(string dialogId, IEnumerable<WaterfallStep> steps = null)
: base(dialogId, steps)
{
AddStep(async (stepContext, cancellationToken) =>
{
var cardAttachment = CreateAdaptiveCardAttachment(cards);
var reply = stepContext.Context.Activity.CreateReply();
reply.Attachments = new List<Attachment>() { cardAttachment };
await stepContext.Context.SendActivityAsync(reply, cancellationToken);
var opts = new PromptOptions
{
Prompt = new Activity
{
Type = ActivityTypes.Message,
// You can comment this out if you don't want to display any text. Still works.
}
};
// Display a Text Prompt and wait for input
return await stepContext.PromptAsync(nameof(TextPrompt), opts);
});
AddStep(async (stepContext, cancellationToken) =>
{
var res = stepContext.Result.ToString();
dynamic jobject = JsonConvert.DeserializeObject(res);
string NewStartDateTime = jobject.Startdate + " " + jobject.Starttime;
string NewStopDateTime = jobject.Stopdate + " " + jobject.Stoptime;
await stepContext.Context.SendActivityAsync($"StartDateTime:{NewStartDateTime}", cancellationToken: cancellationToken);
await stepContext.Context.SendActivityAsync($"StopDateTime:{NewStopDateTime}", cancellationToken: cancellationToken);
return await stepContext.EndDialogAsync();
});
}
public static new string Id => "Adaptivecarddialog";
public static Adaptivecarddialog Instance { get; } = new Adaptivecarddialog(Id);
public static Attachment CreateAdaptiveCardAttachment(string filePath)
{
var adaptiveCardJson = File.ReadAllText(filePath);
var adaptiveCardAttachment = new Attachment()
{
ContentType = "application/vnd.microsoft.card.adaptive",
Content = JsonConvert.DeserializeObject(adaptiveCardJson),
};
return adaptiveCardAttachment;
}
}
}
自适应卡:
{
"type": "AdaptiveCard",
"body": [
{
"type": "TextBlock",
"id": "Start date text",
"separator": true,
"text": "Schedule Start DateTime:"
},
{
"type": "TextBlock",
"id": "DateTimeFormat",
"horizontalAlignment": "Center",
"separator": true,
"weight": "Bolder",
"color": "Warning",
"text": "(In UTC Time Zone)"
},
{
"type": "Input.Date",
"id": "Startdate",
"separator": true,
"value": "2019-05-24"
},
{
"type": "Input.Time",
"id": "Starttime",
"separator": true,
"value": "08:00"
},
{
"type": "TextBlock",
"id": "Stop date text",
"separator": true,
"text": "Schedule Stop DateTime:"
},
{
"type": "TextBlock",
"id": "DateTimeFormat",
"horizontalAlignment": "Center",
"separator": true,
"weight": "Bolder",
"color": "Warning",
"text": "(In UTC Time Zone)"
},
{
"type": "Input.Date",
"id": "Stopdate",
"separator": true,
"value": "2019-05-25"
},
{
"type": "Input.Time",
"id": "Stoptime",
"separator": true,
"value": "08:00"
}
],
"actions": [
{
"type": "Action.Submit",
"id": "SubmitBtn",
"title": "SetSchedule"
}
],
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"version": "1.0"
}
屏幕截图:
感谢与问候
-ChaitanyaNG
日期:2019年6月6日
在Matt的指导下,从KUDU记录详细信息以供参考:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>IIS Detailed Error - 500.0 - Internal Server Error</title>
<style type="text/css">
<!--
body{margin:0;font-size:.7em;font-family:Verdana,Arial,Helvetica,sans-serif;}
code{margin:0;color:#006600;font-size:1.1em;font-weight:bold;}
.config_source code{font-size:.8em;color:#000000;}
pre{margin:0;font-size:1.4em;word-wrap:break-word;}
ul,ol{margin:10px 0 10px 5px;}
ul.first,ol.first{margin-top:5px;}
fieldset{padding:0 15px 10px 15px;word-break:break-all;}
.summary-container fieldset{padding-bottom:5px;margin-top:4px;}
legend.no-expand-all{padding:2px 15px 4px 10px;margin:0 0 0 -12px;}
legend{color:#333333;;margin:4px 0 8px -12px;_margin-top:0px;
font-weight:bold;font-size:1em;}
a:link,a:visited{color:#007EFF;font-weight:bold;}
a:hover{text-decoration:none;}
h1{font-size:2.4em;margin:0;color:#FFF;}
h2{font-size:1.7em;margin:0;color:#CC0000;}
h3{font-size:1.4em;margin:10px 0 0 0;color:#CC0000;}
h4{font-size:1.2em;margin:10px 0 5px 0;
}#header{width:96%;margin:0 0 0 0;padding:6px 2% 6px 2%;font-family:"trebuchet MS",Verdana,sans-serif;
color:#FFF;background-color:#5C87B2;
}#content{margin:0 0 0 2%;position:relative;}
.summary-container,.content-container{background:#FFF;width:96%;margin-top:8px;padding:10px;position:relative;}
.content-container p{margin:0 0 10px 0;
}#details-left{width:35%;float:left;margin-right:2%;
}#details-right{width:63%;float:left;overflow:hidden;
}#server_version{width:96%;_height:1px;min-height:1px;margin:0 0 5px 0;padding:11px 2% 8px 2%;color:#FFFFFF;
background-color:#5A7FA5;border-bottom:1px solid #C1CFDD;border-top:1px solid #4A6C8E;font-weight:normal;
font-size:1em;color:#FFF;text-align:right;
}#server_version p{margin:5px 0;}
table{margin:4px 0 4px 0;width:100%;border:none;}
td,th{vertical-align:top;padding:3px 0;text-align:left;font-weight:normal;border:none;}
th{width:30%;text-align:right;padding-right:2%;font-weight:bold;}
thead th{background-color:#ebebeb;width:25%;
}#details-right th{width:20%;}
table tr.alt td,table tr.alt th{}
.highlight-code{color:#CC0000;font-weight:bold;font-style:italic;}
.clear{clear:both;}
.preferred{padding:0 5px 2px 5px;font-weight:normal;background:#006633;color:#FFF;font-size:.8em;}
-->
</style>
</head>
<body>
<div id="content">
<div class="content-container">
<h3>HTTP Error 500.0 - Internal Server Error</h3>
<h4>The page cannot be displayed because an internal server error has occurred.</h4>
</div>
<div class="content-container">
<fieldset><h4>Most likely causes:</h4>
<ul> <li>IIS received the request; however, an internal error occurred during the processing of the request. The root cause of this error depends on which module handles the request and what was happening in the worker process when this error occurred.</li> <li>IIS was not able to access the web.config file for the Web site or application. This can occur if the NTFS permissions are set incorrectly.</li> <li>IIS was not able to process configuration for the Web site or application.</li> <li>The authenticated user does not have permission to use this DLL.</li> <li>The request is mapped to a managed handler but the .NET Extensibility Feature is not installed.</li> </ul>
</fieldset>
</div>
<div class="content-container">
<fieldset><h4>Things you can try:</h4>
<ul> <li>Ensure that the NTFS permissions for the web.config file are correct and allow access to the Web server's machine account.</li> <li>Check the event logs to see if any additional information was logged.</li> <li>Verify the permissions for the DLL.</li> <li>Install the .NET Extensibility feature if the request is mapped to a managed handler.</li> <li>Create a tracing rule to track failed requests for this HTTP status code. For more information about creating a tracing rule for failed requests, click <a href="http://go.microsoft.com/fwlink/?LinkID=66439">here</a>. </li> </ul>
</fieldset>
</div>
<div class="content-container">
<fieldset><h4>Detailed Error Information:</h4>
<div id="details-left">
<table border="0" cellpadding="0" cellspacing="0">
<tr class="alt"><th>Module</th><td> AspNetCoreModule</td></tr>
<tr><th>Notification</th><td> ExecuteRequestHandler</td></tr>
<tr class="alt"><th>Handler</th><td> aspNetCore</td></tr>
<tr><th>Error Code</th><td> 0x00000000</td></tr>
</table>
</div>
<div id="details-right">
<table border="0" cellpadding="0" cellspacing="0">
<tr class="alt"><th>Requested URL</th><td> https://testbotforoauthprompt:80/api/messages</td></tr>
<tr><th>Physical Path</th><td> D:\home\site\wwwroot\api\messages</td></tr>
<tr class="alt"><th>Logon Method</th><td> Anonymous</td></tr>
<tr><th>Logon User</th><td> Anonymous</td></tr>
</table>
<div class="clear"></div>
</div>
</fieldset>
</div>
<div class="content-container">
<fieldset><h4>More Information:</h4>
This error means that there was a problem while processing the request. The request was received by the Web server, but during processing a fatal error occurred, causing the 500 error.
<p><a href="http://go.microsoft.com/fwlink/?LinkID=62293&IIS70Error=500,0,0x00000000,14393">View more information »</a></p>
<p>Microsoft Knowledge Base Articles:</p>
</fieldset>
</div>
</div>
</body>
</html>
2019-06-06 05:04:50 TESTBOTFOROAUTHPROMPT POST /api/messages X-ARR-LOG-ID=b3f7a170-d306-477e-b318-fbd82ec285f6 443 - 52.172.202.195 BF-DirectLine+(Microsoft-BotFramework/3.2++https://botframework.com/ua) ARRAffinity=232908322fb7729ed3fe519abf975a28a9506866f45a7a57c7acd29d79e24c2f - testbotforoauthprompt.azurewebsites.net 500 0 0 294 2493 3475
请帮助我解决此问题,我要求逐步详细地进行指导,因为我对代码和所有其他技术知识还很陌生。
如果可能,我们可以进行双方同意的Skype /团队呼叫会议,以便我们可以在需要时逐步详细地进行操作。
日期:2019年6月16日 使用其他调试点更新POST。
马特,你好
我已经使用NGROK调试了远程通道,例如在Webchat中进行测试,并且还通过仿真器来查看有什么不同的数据:
使用仿真器: 当我按下Adaptive卡内的按钮时,使用仿真器将有来自仿真器的通道数据,在解析后我将POSTBACK视为true,因此我能够转到瀑布对话框的下一步,由于放置了附加代码来处理来自自适应卡的数据
请参阅名称为“ ChannelDataComing_fromemulator.jpg”的屏幕截图作为参考。
使用Azure的TestInWebChat: 此处,Channel数据为NULL,由于无法解析它,因此代码出错了,因为没有解析它,它给出了作为对象引用错误的错误。 没有通道数据,没有POSTback,因此不会进入瀑布的下一步来处理数据。
请参见名称为“ ChannelDataComingnull_fromTestinWeBChat.jpg”的屏幕截图。
查询:
请注意,由于代码位于Activity == Message条件内,并且通道没有回发,所以代码没有完全执行,但是在发送第一个HI消息时,通道数据确实会到来在显示自适应卡中的“提交”按钮后,显示通道数据并不确定为什么吗?
答案 0 :(得分:2)
以下是对OP帖子的评论的摘要,这些评论导致了该问题的解决。
调试技术
- 确保已安装ngrok。
- 以下说明大致基于此处的指南:
- 在Visual Studio中打开解决方案。
- 在Visual Studio中开始调试。
- 记下已打开网页的localhost地址中的端口(应为3978)。
- 导航到您提取ngrok的目录。
- 在地址栏中输入cmd,然后按Enter键以打开一个新的命令提示符窗口。
- 创建一个可公开访问的URL,该URL将指定端口上的所有http流量通过隧道传输到您的计算机:
- ngrok http 3978 --host-header = localhost
- 复制https转发URL。
- 应采用https://.ngrok.io的形式。
- 使运行ngrok的命令提示符窗口保持打开状态,因为一旦关闭,URL将不再可访问。
- 停止调试。
- 在Azure门户中,打开Web App Bot资源。
- 转到Bot管理>设置>配置,然后将URL https://.azurewebsites.net的第一部分替换为 ngrok URL。
- 最终网址应采用https:/// api / messages的形式。
- 单击“保存”(您已在文本框外单击以启用“保存”按钮)。
- 转到“应用服务”>“设置”>“配置”,并记下MicrosoftAppId和MicrosoftAppPassword的值。
- .bot文件中的值是加密值,我们需要模拟器的解密值。
- 在Visual Studio中,将appId和appPassword键值对从.bot文件中的Production端点复制到Development端点。
- 确保将Development终结点的终结点值设置为localhost URL(http://localhost:3978/api/messages)。
- 在Visual Studio中保存您的更改。
- 在Visual Studio中开始调试。
- 在Azure的Web聊天中打开测试。
- 测试漫游器功能。
您应该击中您在代码中设置的任何断点。
清理步骤-重要!!!
- 将Azure中Web App Bot的消息传递终结点URL恢复为原始值并保存更改。
- 撤消/还原对.bot文件的任何更改。
- 关闭运行ngrok的命令提示符窗口。
- 关闭Bot Framework仿真器
空引用错误
已经numerous times by multiple authors对此进行了介绍,但概括地说...您要访问的对象之一或其中一个对象的属性是null。遇到断点时,请在调试器中逐行浏览代码,直到找到断行。找到中断的行后,可以将鼠标悬停在它们上,inspect your variables及其属性。
ChannelData不在WebChat频道中通过
我自己遇到了这个问题,找不到关于这种情况的任何文档,但是我设法在OnTurnAsync
方法中使用以下代码解决了这个问题:
if (dc.Context.Activity.Type == ActivityTypes.Message)
{
//PropertyInfo channelDataProperty = dc.Context.Activity.GetType().GetProperty("ChannelData");
Activity activity = dc.Context.Activity;
object rawChannelData = activity.ChannelData;
// For the Bot Framework Emulator
if (rawChannelData != null)
{
JObject channelData = JObject.Parse(rawChannelData.ToString());
if (channelData.Children().Any(c => ((JProperty)c).Name == "postBack") && activity.Value != null)
{
dc.Context.Activity.Text = "your-value-here";
}
}
// For the WebChat channel since it doesn't provide ChannelData
else if (activity.ChannelId == Channels.Webchat && activity.Value != null)
{
dc.Context.Activity.Text = "your-value-here";
}
}
(如果您愿意)可以进一步简化为:
if (dc.Context.Activity.Type == ActivityTypes.Message)
{
// For the Bot Framework Emulator AND the WebChat channel
if (dc.Context.Activity.Value != null && dc.Context.Activity.Text == null)
{
dc.Context.Activity.Text = "your-value-here";
}
}
上的简化代码应该工作的原因是因为众所周知,自适应卡是唯一应填充.Value
的{{1}}属性的时间,其余时间回发数据都在Activity
属性中,并且该数据将由WaterfallDialog中的代码自动提取。我建议您在决定使用简化代码之前先进行测试,因为您可能会遇到在自适应卡之外没有.Text
的情况。