Basic Chat Using ASP .NET AJAX
- Posted: Mar 01, 2007 at 6:49 PM
- 41,602 Views
- 46 Comments
Loading User Information from Channel 9
Something went wrong getting user information from Channel 9
Loading User Information from MSDN
Something went wrong getting user information from MSDN
Loading Visual Studio Achievements
Something went wrong getting the Visual Studio Achievements
The AJAX Chat Sample shows how to build a browser based chat using ASP .NET and AJAX. ASP.NET AJAX is the easiest and most enjoyable way to start writing asynchronous Web applications using ASP.NET. The official ASP.NET AJAX
site is here, and you will want to make sure you have downloaded the last version of the framework and the control toolkit before continuing with this example.
Here's an overview of the basic chat logic; it's very simple—
To begin, create a new ASP.NET AJAX-Enabled Web Site in Visual Studio 2005
The Default.aspx file created in the new project should contain the following:
<form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server" /> </form>
Before continuing, add the EnablePartialRendering="true" attribute to the ScriptManager control. This enables you to update regions of the page individually by using UpdatePanel controls (more on that later!). You will also want to copy the App_Code folder from this examples downloadable files to your project directory. The two class files “Chat.cs” and “Chatter.cs” are needed to create our test data.
We'll need three controls right away: a BulletedList to show all of the Chatters participating in the Chat, another BulletedList (part of the control toolkit) to display chat messages (from the server application), and a TextBox to enter new chat messages (from your client browser). You may wonder why we are using a BulletedList to display chat messages rather than a TextBox or ListBox control. It would certainly be possible to use either of those alternatives, however a BulletedList allows for more flexibility when styling the HTML output, and by setting the control's CSS overflow style to auto we can create a ListBox-like experience pretty easily.
<asp:BulletedList ID="ChattersBulletedList" runat="server" /> <asp:BulletedList runat="server" ID="ChatMessageList" /> <asp:TextBox ID="NewMessageTextBox" Columns="50" runat="server" />
We'll also add a button that we will later use to trigger an asynchronous call back to
Default.aspx: <asp:Button ID="SendButton" Text="Send" runat="server" OnClick="SendMessage_Click"/> The complete form should look something like this: <form id="form1" runat="server"> <asp:ScriptManager ID="ScriptManager1" runat="server" EnablePartialRendering="true" /> Chatters<br/> <asp:BulletedList ID="ChattersBulletedList" runat="server" /> Chat Text<br/> <div style="width: 640px; height: 240px; overflow: auto;"> <asp:BulletedList runat="server" ID="ChatMessageList" /> </div> Send Message Text<br/> <asp:TextBox ID="NewMessageTextBox" Columns="50" runat="server" /><asp:Button ID="SendButton" Text="Send" runat="server" /> </form>
At this point you can run the project and check out the form.
In a real-world scenario you would of course implement some kind of user authentication for your application. For the purposes of this example we will skip all of that and simply hard-code our chat application participants in the Application context. To do this, add a new Global.asax file to your project by right-clicking the project in the solution tree, clicking “Add New Item” and choosing Global Application Class.
Since we want to simulate a group of Chatters that have logged into our site, we will create a list of Chatter objects within the Application_Start method like so—
C# List<Chatter> chatters = new List<Chatter>(); chatters.Add(new Chatter(new Guid("CD863C27-2CEE-45fd-A2E0-A69E62B816B9"), "Me")); chatters.Add(new Chatter(Guid.NewGuid(), "Juan")); chatters.Add(new Chatter(Guid.NewGuid(), "Joe")); chatters.Add(new Chatter(Guid.NewGuid(), "Eric")); chatters.Add(new Chatter(Guid.NewGuid(), "Brian")); chatters.Add(new Chatter(Guid.NewGuid(), "Kim")); chatters.Add(new Chatter(Guid.NewGuid(), "Victor")); Application.Add("Chatters", chatters);
VB Dim chatters As List(Of Chatter) = New List(Of Chatter) chatters.Add(New Chatter(New Guid("CD863C27-2CEE-45fd-A2E0-A69E62B816B9"), "Me")) chatters.Add(New Chatter(Guid.NewGuid, "Juan")) chatters.Add(New Chatter(Guid.NewGuid, "Joe")) chatters.Add(New Chatter(Guid.NewGuid, "Eric")) chatters.Add(New Chatter(Guid.NewGuid, "Brian")) chatters.Add(New Chatter(Guid.NewGuid, "Kim")) chatters.Add(New Chatter(Guid.NewGuid, "Victor")) Application.Add("Chatters", chatters)
(Be sure to add <%@ Import Namespace="System.Collections.Generic" %> at the top of the file.) This is clearly test-only data, but the import thing to note is that each Chatter gets a new random Guid except for “Me” which gets a hard-coded value. In a real-world scenario this would probably be a user identification number stored in a cookie or Session variable, but since we are lazy, we will simply have hard-code it in two places to get a similar effect.
Next we will create a list of Chat's available in the application (just one for now)—
List<Chat> chat = new List<Chat>(); chat.Add(new Chat()); Application.Add("Chats", chat);
Finally, we will loop through our list of logged-in users and associate them with the single Chat instance added above—
C# foreach (KeyValuePair<Guid, Chatter> chatter in Chatter.ActiveChatters()) { chatter.Value.Join(Chat.ActiveChats()[0]); }
VB For Each c As KeyValuePair(Of Guid, Chatter) In Chatter.ActiveChatters c.Value.Join(Chat.ActiveChats(0)) Next
The Global.asax code should look something like this—
C# void Application_Start(object sender, EventArgs e) { List<Chatter> chatters = new List<Chatter>(); chatters.Add(new Chatter(new Guid("CD863C27-2CEE-45fd-A2E0-A69E62B816B9"), "Me")); chatters.Add(new Chatter(Guid.NewGuid(), "Juan")); chatters.Add(new Chatter(Guid.NewGuid(), "Joe")); chatters.Add(new Chatter(Guid.NewGuid(), "Eric")); chatters.Add(new Chatter(Guid.NewGuid(), "Brian")); chatters.Add(new Chatter(Guid.NewGuid(), "Kim")); chatters.Add(new Chatter(Guid.NewGuid(), "Victor")); Application.Add("Chatters", chatters); List<Chat> chats = new List<Chat>(); chats.Add(new Chat()); Application.Add("Chats", chats); foreach (KeyValuePair<Guid, Chatter> chatter in Chatter.ActiveChatters()) { chatter.Value.Join(Chat.ActiveChats()[0]); } }
VB Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs) Dim chatters As List(Of Chatter) = New List(Of Chatter) chatters.Add(New Chatter(New Guid("CD863C27-2CEE-45fd-A2E0-A69E62B816B9"), "Me")) chatters.Add(New Chatter(Guid.NewGuid, "Juan")) chatters.Add(New Chatter(Guid.NewGuid, "Joe")) chatters.Add(New Chatter(Guid.NewGuid, "Eric")) chatters.Add(New Chatter(Guid.NewGuid, "Brian")) chatters.Add(New Chatter(Guid.NewGuid, "Kim")) chatters.Add(New Chatter(Guid.NewGuid, "Victor")) Application.Add("Chatters", chatters) Dim chats As List(Of Chat) = New List(Of Chat) chats.Add(New Chat) Application.Add("Chats", chats) For Each c As KeyValuePair(Of Guid, Chatter) In Chatter.ActiveChatters c.Value.Join(Chat.ActiveChats(0)) Next End Sub
When the test server first runs our project the code path above will be invoked and we will have a magical list of users in the Application context ready to chat away.
Open the code-behind file for Default.aspx (Default.aspx.cs) and add two private variables: one for our Chatter (“Me”), and one for the single Chat instance—
// You'll notice these are the same values hard-coded in the Global.asax file as well private Chat m_chat = Chat.ActiveChats()[0]; private Chatter m_chatter = Chatter.ActiveChatters()[new Guid("CD863C27-2CEE-45fd-A2E0-A69E62B816B9")]; Next, add a private method called _UpdateChatterList— private void _UpdateChatterList() { ChattersBulletedList.DataSource = m_chat.Chatters; ChattersBulletedList.DataTextField = "Name"; ChattersBulletedList.DataBind(); }
Since Chatters will enter and leave the Chat at any time, our global list of Chatters will need to update often. _UpdateChatterList binds our global list of Chatters to the appropriate BulletedList in the Web form every time we post-back to this page. We'll also need to update and display the list of messages from our Chat instance. To do this we'll add a new method called _UpdateChatMessageList—
C# private void _UpdateChatMessageList() { ChatMessageList.DataSource = m_chat.Messages; ChatMessageList.DataBind(); }
VB Private Sub _UpdateChatMessageList() ChatMessageList.DataSource = m_chat.Messages ChatMessageList.DataBind() End Sub
Any messages that have been pushed to our Chat instance since the last post-back will now be appended to our Chat message BulletedList.
The last thing we need to do is handle the button click that occurs when a Chatter sends a new message to the Chat instance. To do this add an OnClick attribute to the “Send” button in Default.aspx—
<asp:Button ID="SendButton" Text="Send" runat="server" OnClick="SendButton_Click" />
Then, add the event handler for the button click to the code-behind. We'll also call our “Update” methods after sending our chat message—
C# protected void SendButton_Click(object sender, EventArgs e) { if (!string.IsNullOrEmpty(NewMessageTextBox.Text)) { string messageSent = m_chat.SendMessage(m_chatter, NewMessageTextBox.Text); } _UpdateChatterList(); _UpdateChatMessageList(); }
VB Protected Sub SendButton_Click(ByVal sender As Object, ByVal e As EventArgs) If Not String.IsNullOrEmpty(NewMessageTextBox.Text) Then Dim messageSent As String = m_chat.SendMessage(m_chatter, NewMessageTextBox.Text) NewMessageTextBox.Text = String.Empty End If _UpdateChatterList() _UpdateChatMessageList() End Sub
This will handle the click event from the “Send” button, check if we have any text to send, then call our Chat's SendMessage method which will add the message to our global Chat object.
Try running the project and sending a few messages. The page will do a complete post-back to the server every time the “Send” button is clicked. Lame. Let's get rid of that by using the ASP.NET AJAX UpdatePanel. Download the sample project.
Recall that in the first step we added the EnablePartialRendering attribute to the ScriptManager control. Now we can actually use that functionality by wrapping our Chat controls in an UpdatePanel. In the Default.aspx file encapsulate the BulletedList controls with an UpdatePanel as follows—
<asp:UpdatePanel ID="ChatUpdatePanel" runat="server" UpdateMode="Always"> <ContentTemplate> Chatters<br/> <asp:BulletedList ID="ChattersBulletedList" runat="server" /> Chat Text<br/> <div style="width: 640px; height: 240px; overflow: auto;"> <asp:BulletedList runat="server" ID="ChatMessageList" /> </div> </ContentTemplate> </asp:UpdatePanel>
(Note that you must add a ContentTemplate element to the UpdatePanel before adding the Web controls.)
To circumvent the normal post-back processing we need to associate this UpdatePanel with a “Trigger,” so after the close of the ContentTemplate element add the following—
<Triggers> <asp:AsyncPostBackTrigger ControlID="SendButton" EventName="Click" /> </Triggers>
Now “Send” button clicks will be handled asynchronously, and we don't have to modify any of the synchronous logic we implemented above. Pretty nice!
Our chat application doesn't quite work as we'd expect it to yet. We really want the list of messages to update continuously as new messages are sent from other Chatters. We can implement this by adding a new Trigger to the Triggers element, and wiring the new Trigger to a Timer control—
...
<asp:AsyncPostBackTrigger ControlID="ChatTextTimer" EventName="Tick" /> </Triggers>
Then, add a Timer control to the page. The Interval attribute determines the amount of time between “ticks” of the timer (in milliseconds)—
<asp:Timer runat="server" ID="ChatTextTimer" Interval="1000" />
Finally, add calls to UpdateChatterList and UpdateChatMessageList in the Page_Load event handler. When the timer Tick event fires the page will post-back, the Page_Load handler will be invoked and our message list and Chatter list will update as expected. With these changes in place go ahead and run the project again. You may notice that the message list resets its scroll position to the top every time it updates. To fix this add the following JavaScript block after the closing form tag and before the closing body tag in Default.aspx—
<script type="text/javascript"> function _SetChatTextScrollPosition() { var chatText = document.getElementById("ChatText"); chatText.scrollTop = chatText.scrollHeight; window.setTimeout("_SetChatTextScrollPosition()", 1); } window.onload = function() { _SetChatTextScrollPosition(); } </script>
The list will flicker slightly as it repositions itself, but the latest message will stay in view at the bottom of the list.
To test the functionality of your new chat application connect to the test URL with two separate browser windows and type messages into one or the other. You should see your messages pop into the message list of each one no matter which browser sends the message. Enjoy!
Download the sample project.
“Tyler Schlegel is a Software Development Engineer with Personify Design, Inc. He's been developing .NET solutions since 2002.”
Comments have been closed since this content was published more than 30 days ago, but if you'd like to continue the conversation,
please create a new thread in our Forums,
or
Contact Us and let us know.
Follow the Discussion
Oops, something didn't work.
What does this mean?
Following an item on Channel 9 allows you to watch for new content and comments that you are interested in. You need to be signed in to Channel 9 to use this feature.What does this mean?
Following an item on Channel 9 allows you to watch for new content and comments that you are interested in and view them all on your notifications page.sign up for email notifications?
How would you recommend handling that a user can't scroll up? This is due to the message list is updating every second. The javascript jumps to the bottom every second.
@Randy I would add in some javascript to check if a user scrolled up. If they did then don't jump down
@Alton @jeksya working on getting the source and will move it to our server instead
@Alton @jeksya Personify Design gave me the source code and links have been updated. Should work now.
hi, very nice example to get up and going, but it would be nice if you also updated the web.config
I copied the web.config from a default asp.net 3.5 project and the whole thing compiled fine after that.
"@Randy I would add in some javascript to check if a user scrolled up. If they did then don't jump down"
Can someone help me with the code for this? I am not javascript expert.
Also, any help in getting rid of flickering?
i am not able to download this link
@rahul Link at the top of the page labeld "Download" worked for me.
Can your chatters be added live or do they need to be preloaded as above in the global asax
I am a total noob on what to do after downloading the zip file. I hope someone can guide me how to test it. I tried opening the project in visual basic 2008 but there is no project file from the sample. I really have no idea what to do next.
@lost, Looks like you'll have to create a new project to run this. sadly, looks like this example doesn't have a project file.
I would follow the article and copy the code out of the files to recreate it.
has anyone tried extending the code to add login functions? Ive tried but the messages from other chatters won't show up.
Hey I'm using this basic code for a chat that I'm about to create but I cant figure out how and where to add a function that adds the users dynamically? Can anyone help me?
I am getting error at the chat.vb and chatter.vb saying the 'Type Chatter is not defined'
Please can you help me in solving this problem?
I have the same issue!
I deleted/exclude from project the web.config file and start debugging. This created the a new web.config file and fixed all the problems I had.
Peace..
@pallavi what type of problem?
i am getting prob with chatter in glogal.asax.plz help me
Hi,
The Code is working fine but how can this be activate for instant messaging between two users.
Also how to pop up the message on the other users page,when i send him a message.
so could you help us on how to use the chat with logged in and logged out users in a session please? but only two people chatting to make it simple.....
Thanks for article and check PokeIn.codeplex.com for great ajax library with chat samples.
your code works gr8. but, what if user wants to scroll up to see previous conversation?
@davdav if you download the source code which is a link at the top of the article, you'll see the classes for those objects
chatter and chat is not defined..T_T
Is it just me, or is it now not working on final build of ASP.NET 2.0 Ajax Extensions 1.0?!
Microsoft.Web.Extensions.dll missing?!@
web config erro..How to Solve..
thanks
Thnaks for help
i had tried these but its showing some error, missing assembly or namespace for chat and chatter.
iikkkjjjjj
helllloooooo
@Randy:
Love the simplicity of the project, can you give me some tips on how to implement more than one chat room?
scroll bar is restrict to the bottom of DIV.
how can we change the code so that scroll bar can go up while we scroll the scrollbar using mouse..?
chatter and chat is not defined..
how can i solve this problem?
Hi, really interested your Basic chat.
I want to add new chatter.
I simpelly add a textbox and a button, how can I added this new user into the chatter list.
My code below make list become double.
And after added new user I want this new user become current active user. How to do it Please?
Protected Sub btnJoin_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim chatters As List(Of Chatter) = New List(Of Chatter)
chatters = CType(Application("Chatters"), List(Of Chatter))
Dim id As Guid = Guid.NewGuid
chatters.Add(New Chatter(id, txtNewUser.Text))
m_chatter = Chatter.ActiveChatters(New Guid(id.ToString))
For Each c As KeyValuePair(Of Guid, Chatter) In Chatter.ActiveChatters
c.Value.Join(Chat.ActiveChats(0))
Next
End Sub
But what if we can develop a chat that does not depend on session at all ? can I found one like that ?
http://www.uobabylon.edu.iq
thanks
There's nothing worse than a tutorial with code that doesn't work.
I just want to know hot to get Public Key Token which has mentioned in web.config file
ex:
<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules>
<add name="ScriptModule" preCondition="integratedMode" type="Microsoft.Web.UI.ScriptModule, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</modules>
<handlers>
<remove name="WebServiceHandlerFactory-ISAPI-2.0"/>
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode" type="Microsoft.Web.Script.Services.ScriptHandlerFactory, Microsoft.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="ScriptResource" verb="GET" path="ScriptResource.axd" type="Microsoft.Web.Handlers.ScriptResourceHandler"/>
</handlers>
</system.webServer>
hi
hello
I've implemented a version of this on my own website. I use windows forms authentication, and set the page authentication to logged in users. However, Ithough users can log in and join the chat page, we all get redirected to the login page after just a few messages get posted.
Is there something I should know about Ajax and forms authentication. I think the problem is because a partial post back fails authentication.
I am developing the site for a hosted service so I can't debug live.
Any suggestions?
Hi!
Thanks
Hey this is really great but can you do an one with socket programming ?
please reply asap
I'm getting error msg as index out of range at Chat.ActiveChats()[0].Any help to fix this issue?
Please Help in developing the simple chat application in asp.net...with C#.net
I just want to thank you for that snippet of javascript that scrolls to the bottom of a window. I tried EVERY example given to do this on the web, and none of them worked.
My no-frills web chat now works, is 35 lines of code in vb plus 2 update panels, 2 text boxes, and a button on the form. Easy peasy!
Remove this comment
Remove this thread
close