Microsoft Bot Framework WebChat (DirectLine) causing Postback on AJAX Page - c#

I am following the steps as detailed here: https://github.com/Microsoft/BotFramework-WebChat to implement Microsoft Bot Framework (in C# SDK). I have tested it on a standalone page and it is working fine. I require to use the DirectLine version as I have to pass values from webpage to the bot (for user initalization).
However, the page where I have to implement this is an ASP.NET WebForms (using ScriptManager and AJAXToolkit).
The issue arises when using the bot. By typing any content in the chat window and pressing enter, the whole page refreshes and the bot reinitailizes to start. This makes the bot unusable.
I am guessing that the chat control's "Send" button is somehow triggering a postback via ScriptManager causing the whole page to refresh. I had to include e.preventDefault() on the click event of the button that shows the chat window to take care of this situation. I am lost when it comes to within the Directline chat control.
Can someone help?

The issue arises when using the bot. By typing any content in the chat window and pressing enter, the whole page refreshes and the bot reinitailizes to start. This makes the bot unusable.
I have same issue when I embed my bot in webform page (.aspx), to solve this problem, I put the chat bot container <div id="mybot" /> inside UpdatePanel control and set ChildrenAsTriggers property to false, which works for me, you can try it.
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<link href="https://cdn.botframework.com/botframework-webchat/latest/botchat.css" rel="stylesheet" />
<script src="https://cdn.botframework.com/botframework-webchat/latest/botchat.js"></script>
</head>
<body>
<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<div>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" ChildrenAsTriggers="false" UpdateMode="Conditional">
<ContentTemplate>
<div id="mybot" />
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>
</html>
<script>
BotChat.App({
directLine: { secret: 'directline_secret_here' },
user: { id: '1234', firstname: 'firstname_here', lastname: 'lastname_here' },
bot: { id: 'fehantestbot' },
resize: 'detect'
}, document.getElementById("mybot"))
</script>
Screenshot of my test:

I had this issue when trying to build this into a DNN module.
Prevented it by inserting e.preventDefault to onKeyPress function in the Shell.tsx file in the BotFramework-WebChat project, and rebuilding it.
BotFramework-WebChat\src\Shell.tsx:
//...
private onKeyPress(e: React.KeyboardEvent<HTMLInputElement>) {
if (e.key === 'Enter') {
e.preventDefault(); //new line: prevent page reload
this.sendMessage();
}
}
//...

Use this code to prevent page refresh while sending chat from direclineJS webchat:
$(document).keypress(function (e) {
if (e.keyCode === 13) {
e.preventDefault();
return false;
}
});

Related

How to use ShowModalDialog Polyfill in ASP.NET Web Form?

I have a simple web form with a single button:
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="DemoWeb.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
<script src="https://unpkg.com/showmodaldialog"></script>
<script>
function showPopup() {
var ret = window.showModalDialog("Popup.aspx");
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" />
</div>
</form>
</body>
</html>
How do I make that button open Popup.aspx with ShowModalDialog Polyfill from https://github.com/niutech/showModalDialog?
I tried Default.aspx.cs like this:
using System;
namespace DemoWeb
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Button1.Attributes.Add("OnClick", "showPopup()");
}
protected void Button1_Click(object sender, EventArgs e)
{
}
}
}
It works in IE with old showModalDialog, but in Chrome popup appears and immediately disappears.
Well, if you button click is to run server side code, then you get a full page post back, and that will re-load the page.
But, you CAN have that asp.net button call 100% browser side code and NOT run the button click event stub on the server.
You can use this format:
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" Text="Button" OnClick="Button1_Click" OnClientClick="showpopup()";return false;" />
</div>
<script>
function showpopup() {
var ret = window.showModalDialog("Popup.aspx");
}
</script>
</form>
So, when you click on the asp.net button, it will call the client side function. (you use OnClientClick(). Also, we added a return false to that click event, and this will prevent the server side Button1_Click event from running. However, you can have the js code return true or false, and if the routine returns true, then the button_click (server side) code will run, but if your js returns false, then the server side event code will not run.
Also, showModalDialog has been REMOVED from most browsers. So it will not work. I suggest you adopt jQuery and also adopt jQuery.ui, and use that to pop up a dialog.
Also if a browser STILL DOES support showModalDialgo (and it HAS been removed), even if it worked, then 99% of popup blocks which now even browsers have turned on by default will block anyway.
So, to run the above with jQuery and also jQuery.ui, then your code to pop up the dialog will become this:
<form id="form1" runat="server">
<asp:Button ID="Button1" runat="server" Text="Button" Width="94px" OnClientClick="showpage();return false;" />
<br />
<br />
<div id="poppagearea">
</div>
<br />
<script>
function showpage() {
var mydiv = $('#poppagearea');
mydiv.dialog({
autoOpen: false, modal: true, title: 'My cool other page', width: '30%',
position: { my: 'top', at: 'top+150' },
buttons: {
'ok': function () {
mydiv.dialog('close');
// code here for ok click alert('user click ok');
},
'cancel': function () {
mydiv.dialog('close');
// code here for a cancel click alert('user click cancel');
}
}
});
}
</script>
</form>
So you CAN use a alert(); in pure js, or you can prompt the user with a confirm('do you want to do this'). But if you want to pop up a dialog - especially another page, then I would quite much suggest that jQuery and jQuery.UI are the way to go here.
Polyfill won't work with a server side control. Replace your asp button with an input type="button" and add the click event using addEventhandler with async and await. Control flow should stop on ShowModelDialog call then and will resume when you close the popup.

How to use Ajax for this Chat application

I want to use Ajax for my chat application instead of refreshing an Iframe every second for new messages. Someone told me to use webservices with ajax. What should I do with my code to use Ajax?
Here is the code which shows Iframe which is called every second and Iframe src has an aspx page which displays chat messages
<script type="text/javascript">
function refreshConversatio() {
document.getElementById('iframeDisplayMessage').src = 'frmMessageDisplay.aspx';
}
</script>
<body>
<div id="divMessageDisplayPage" style="height: 724px; ">
<asp:PlaceHolder ID="ContentPlaceHolderDisplayMessage" runat="server">
<iframe id="iframeDisplayMessage" name="iframeDisplayMessage" width="76%" style="background-color:White;" height="95%" frameborder="0" src="frmMessageDisplay.aspx"
onload="document.getElementById('iframeDisplayMessage').contentWindow.scrollTo(0,document.getElementById('iframeDisplayMessage').contentWindow.document.body.scrollHeight)">
</iframe>
</asp:PlaceHolder>
</div>
<script type="text/javascript">
setInterval(function () { refreshConversatio(); }, 1000)
</script>
</body>
This is the Aspx page which is called in Iframe and it has literal which displays messages
<div id="divConversation" style="width: 100%;">
<asp:Literal ID="RecepientConversation" runat="server"/>
</div>
Take a look at leveraging SignalR to accomplish the task. Patrick Fletcher has a pretty nice set of tutorials with examples for building a basic chat app.
Tutorial Link:
http://www.asp.net/signalr/overview/signalr-20/getting-started-with-signalr-20/introduction-to-signalr
http://www.asp.net/signalr

Is Dirty in ASP.NET Web Page [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Detecting Unsaved Changes using JavaScript
My Web application has 3 web forms ,I implemented the validations in my webpage.I want to implement isdirty functionality in my web application.I want to pop up a message box in my webpage when a user clicks on sign out(which is a loginstatus control) if there any changes made to the form.
Environment:
Asp.net
VS2008
c#
This could be easily done with jquery and the onbeforeunload event. Using the .serialize() function you could calculate the state of the form on the returned string once when the page loads and then in the onbeforeunload event. Then compare the two values and if they are different something indeed has changed in the form.
Example:
<%# Page Language="C#" %>
<!DOCTYPE html>
<html>
<head id="Head1" runat="server">
<title></title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js"></script>
<script type="text/javascript">
var data = '';
$(function () {
data = $('form').serialize();
});
window.onbeforeunload = function () {
if ($('form').serialize() !== data) {
return 'You have unsaved changes. Are you sure you want to navigate away?';
}
};
</script>
</head>
<body>
<form id="Form1" runat="server">
<asp:TextBox ID="FirstName" runat="server" />
<asp:TextBox ID="LastName" runat="server" TextMode="MultiLine" />
<asp:CheckBox ID="Chk" runat="server" />
<asp:HyperLink ID="Link" runat="server" Text="Go to Google" NavigateUrl="http://www.google.com" />
</form>
</body>
</html>
Some other techniques (like the one presented in the duplicate question that was voted to close for your question) involve in subscribing for the .change() event of the input elements but they are less reliable as the user could for example type abc in some input field and then delete it and if you used this technique the form would be considered as dirty although no value actually changed.
You can easily setup a popup/modal window to show-up when the user tries to leave a form/page. Here is a quick pure javascript example, that shows a message when you try to leave a page.
<body onunload="if (confirm('Save form ?')) { SaveFormMethod(); }">
If you need a better example, you should provide more details and show us your code.
Please take a look at this answer and see if it helps

Force download of a file from memory with support for downloading more than once

I am dynamically generating a file from server based on user input. I need to provide a download button which, upon clicking, downloads a file to the user's file system.
Also, the user might click the same button twice, upon which the file should download again.
The dynamic generation of file rules out the HttpResponse.TransmitFile() option, which suports mutliple download.
Almost every other option I have come across needs Response.End() to be invoked, which prevents a second download.
How do I satisfy the 'multiple download" requirement?
Read up on Virtual Path providers, which might enable me to use TransmitFile(), but that looks like an overkill for such a simple requirement.
You could try either of the following:
Re-Generate the file each the user clicks download.
Save the file to disk, and stream it from there.
Got the answer from here:
http://www.eggheadcafe.com/tutorials/aspnet/3889fc21-1562-4d1b-89e4-cea5576690b2/refresh-web-pages-after-d.aspx
Basically it uses a client side script to reload the page after a download:
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Untitled Page</title>
<script type="text/javascript" language="javascript">
var isReload = false;
function DownloadFiles()
{
if(isReload == true)
{
isReload = false;
window.location.reload();
}
else
{
isReload = true;
}
window.setTimeout("DownloadFiles()", 2000);
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label runat="server" ID="lblMsg"></asp:Label>
<asp:Button ID="Button1" runat="server" Text="Download" OnClientClick="DownloadFiles();" OnClick="Button1_Click"/>
</div>
</form>
</body>
</html>

Simulate a another button postback inside a jQuery dialog

I have the following ASPX page:
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title></title>
<script src="js/jquery-1.2.6.min.js" type="text/javascript"></script>
<script src="js/jquery-ui-1.6.custom.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
$("#dialog").dialog({
bgiframe: true,
autoOpen: false,
height: 300,
modal: true,
buttons: {
'Ok': function() {
$(this).dialog('close');
__doPostBack('TreeNew', '');
},
Cancel: function() {
$(this).dialog('close');
}
},
close: function() {
;
}
});
});
function ShowDialog() {
$('#dialog').dialog('open');
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="TreeNew" runat="server" Text="Nuevo" OnClientClick="ShowDialog(); return false;"/>
<asp:Label ID="Message" runat="server"></asp:Label>
<div id="dialog" title="Create new user">
<p id="validateTips">All form fields are required.</p>
<asp:RadioButtonList ID="ContentTypeList" runat="server">
<asp:ListItem Value="1">Text</asp:ListItem>
<asp:ListItem Value="2">Image</asp:ListItem>
<asp:ListItem Value="3">Audio</asp:ListItem>
<asp:ListItem Value="4">Video</asp:ListItem>
</asp:RadioButtonList>
</div>
</div>
</form>
</body>
</html>
When the user click on TreeNew button appears the modal dialog, then he/she choose an option an click Ok button to do a postback.
I need that the server side execute TreeNew_Click method: How can I do that?
If I use __doPostBack('TreeNew', '') it throws me the following error: "Object expected".
UPDATE:
I found the origin for the error: the function __doPostBack is not defined. I'm not going to delete the question because I think Chris Clark's answer is so interesting.
As a rule, if you find yourself ever typing the text "__doPostBack(...", you should re-evaluate your approach.
In this case, you should just put a server-side asp.net button inside the div that you are turning into the dialog and use that instead of the generates jQuery button. That way the postback code will get wired up for you. There is one caveat however - when jQuery turns your div (I'm going to assuming it's a div) into a dialog, it rips the div out of the form element. That means you have to attach it BACK to the form BEFORE the postback occurs. You can do that in the close function of the dialog. The postback will then occur properly.
If you really want to use the generated jQuery OK button, you have a couple of options. First, you can slap a server-side asp.net button on the page and hide it, then call the asp.net button's click event from the OK button's code. Second, you can emit a javascript function form the server using Page.ClientScript.GetPostBackEventReference that will contain the __doPostBack code that you were trying to hand-write above. Then call that emitted function from the OK button's JS code.

Categories