Click here to Skip to main content
11,797,944 members (80,527 online)
Click here to Skip to main content

A Simple Chat Website Using ASP.NET and AngularJS

, 24 Aug 2013 CPOL 61.1K 5.3K 65
Rate this:
Please Sign up or sign in to vote.
This article provides information to create a simple chat website.


As the title suggests, this is a very basic website that implements global chat, meaning that the users can chat globally with each other by just registering their name. The code uses ASP.NET web services along with a little jQuery and AngularJS.

If you are new to AngularJS, its documentation can be found here.


The idea that I had in mind before creating this was to utilize the capability of AngularJS to automatically update the DOM whenever its models are updated. The source of this idea is a Google presentation that I saw some time back about AngularJS and Firebase (video). I thought that maybe we can implement something like this at a very small scale using the Application State of ASP.NET.

Using the Code

The code is fairly simple, the user's information and the global chat data is stored in the application state. Periodic web service calls are made to retrieve the data and then the angular view models are updated with that data. The DOM is updated asynchronously by the angular whenever its models are updated.

Follow the steps given below to create this chat website:

Step 1

Create a new ASP.NET website, and open the 'Global.asax' file. Now add the following code to the 'Application_Start' event.

/// <summary>
/// Code that runs on application startup
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void Application_Start(object sender, EventArgs e)
    //this is our list of users.
    Dictionary<String, String> userList = new Dictionary<String, String>();
    Application.Add("UserList", userList);

    //this is the place where we put all the global chat data.
    List<Object> globalChat = new List<Object>();
    Application.Add("GlobalChat", globalChat);

Here, we are initializing a Dictionary object to store the list of users and a List object to store the global chat data, and then adding them to the application state.

Step 2

Add a new web service to the website and name it 'ChatService'. Add the [ScriptService] attribute and the following web methods to the code behind:

public class ChatService : System.Web.Services.WebService
/// <summary>
/// Adds a new user.
/// </summary>
/// <param name="userName"></param>
/// <returns></returns>
[WebMethod(EnableSession = true)]
public String AddUser(String userName)
    //add our new user to the application object
    String newId = Session.SessionID;
    if (!((Dictionary<String, String>)Application["UserList"]).Keys.Contains(newId))
        ((Dictionary<String, String>)Application["UserList"]).Add(newId, userName);

    return "Success";

/// <summary>
/// Adds a new chat message.
/// </summary>
/// <param name="message"></param>
/// <returns></returns>
[WebMethod(EnableSession = true)]
public String AddGlobalChat(String message)
    String userId = Session.SessionID;
        new { time = DateTime.Now.ToString("hh:mm"),
              message = ((Dictionary<String, String>)Application
              ["UserList"])[userId] + ": " + message

    return "Success";

/// <summary>
/// Returns the global chat data.
/// </summary>
/// <returns>Object containing the global chat data</returns>
[WebMethod(EnableSession = true)]
public Object GetGlobalChat()
    List<Object> messages = (List<Object>)Application["GlobalChat"];
    return messages;

Here is the description of the web methods that are given above:

  • AddUser: Adds a new user to the global user list if it does not already exist. Only one user can be added per session.
  • AddGlobalChat: Adds a new message to the global chat collection.
  • GetGlobalChat: Returns a list containing all the global chat data present in the Application State. Angular view model is then later updated with this data.

Step 3

Remove the master page bindings (if any) from your default aspx page and add the following code to it for the <head> and <body> sections. Keep the rest as default.

 <head id="Head1" runat="server">
    <script type="text/javascript" 
    <script type="text/javascript" src="Helper.js"></script>
   <form id="form1" runat="server">
        <h3>Enter your name:</h3>        
        <input id = "txtName" size = "30" />&nbsp;
        <input type = "button" id = "btnAddUser" 
          value = "Add" onclick = "AddUser();" />

    <script type ="text/javascript">        
        var btnAddUser = $("#btnAddUser");
        var txtName = $("#txtName");

        function AddUser() {
            var chatService = new ServiceCall("AddUser", 
                "{'userName':'" + txtName.val() + "'}");

        function addUser_Complete() {
  "ChatPage.aspx", "_self");

The AddUser function will invoke on the onclick event of the button. This will call the web service to add the user name to our application state.

Now we will add a JavaScript file to hold the code required for the web service calls. Add a new JavaScipt file to your website and name it 'Helper.js' and add the following code to it:

; var ServiceCall = function (serviceName, serviceParams) {
    this._serviceName = serviceName;
    this._serviceParams = serviceParams;
    return this;

ServiceCall.prototype = {
    callService: function (serviceCallSuccess) {
            type: "POST",
            url: 'ChatService.asmx/' + this._serviceName,
            data: this._serviceParams,
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            success: serviceCallSuccess,
            error: function (e) {
                //alert("Error in calling service.");

var Helper = {
    //We need to escape and un-escape strings in many cases so as to avoid the corruption of the
    //json that we are passing. This can also be used in many places in the web pages, for ex: sometimes
    //we need to call functions from onclick attributes then escaping and un-escaping is better
    //than tweaking the string concatenations.
    htmlEscape: function (str) {
        return String(str)
            .replace(/&/g, '&amp;')
            .replace(/"/g, '&quot;')
            .replace(/'/g, '&#39;')
            .replace(/</g, '&lt;')
            .replace(/>/g, '&gt;');
    htmlUnescape: function (value) {
        return String(value)
            .replace(/&quot;/g, '"')
            .replace(/&#39;/g, "'")
            .replace(/&lt;/g, '<')
            .replace(/&gt;/g, '>')
            .replace(/&amp;/g, '&');

I have defined a generic serviceCall object to call our web services. This is very basic prototyping, we will inherit this serviceCall object into new objects to call our web services. For this, we will provide the method name and the parameters in the JSON format at the time of object initialization. After that, we will invoke the callService method to call the web service. We need to pass a function in the serviceCallSuccess if we want to do something on the success of our web service call.

Step 4

Now we need to add the angularJs controller. The complete documentation about angular controllers can be found here.

For this, we will add a new js file and name it 'ChatCtrl.js'. Add the following code to this file:

function ChatCtrl($scope) {
    $scope.globalChat = [];

This is very basic containing only our model for the global chat. You can even use a script tag for this code but I prefer a separate file for further expansions. We will initialize globalChat as an empty list.

Lastly, add a new aspx file to our website and name it 'ChatPage.aspx'. Add the following code to it for the <head> and <body> sections. Keep the rest as default.

<head runat="server">
    <script type="text/javascript" 
    <script type="text/javascript" 
    <script type="text/javascript" 
    <script type="text/javascript" 
    <style type="text/css">
            font-family:@Arial Unicode MS;
            margin:0 auto
<body ng-app>
    <form id="form1" runat="server">
    <div id = "container" style = " text-align:center">
            <textarea id = "txtGlobalChat" 
            rows = "20" cols = "80"></textarea>
        <div id = "divMessages" 
        ng-controller = "ChatCtrl"  class="Messages">
            <table width = "100%">
                <tr ng-repeat = "msg in globalChat">
            <input id = "txtMessage" size = "100" 
            maxlength = "90" placeholder = "Enter your message" />

    <script type ="text/javascript">
        $('#txtMessage').bind("keypress", function (e) {
            if (e.keyCode == 13) {
                return false;

        function AddGlobalChatMsg() {
            var chatService = new ServiceCall("AddGlobalChat", 
            "{'message':'" + Helper.htmlEscape($('#txtMessage').val()) + "'}");

        function addGlobalChat_Complete() {}

        function ContentLoaded() {

        function updateChatArea() {

        function getGlobalChat() {
            var chatService = new ServiceCall("GetGlobalChat", "{}");

        function getGlobalChat_Complete(msg) {
            var scope = AngularScope();
            var scroll = scrollBarAtBottom();
            scope.globalChat = [];
            var i = 0;
            for (; i < msg.d.length; i++) {
                msg.d[i].message = Helper.htmlUnescape(msg.d[i].message); //unEscape the message string
            if (scroll === true) {
                setTimeout("scrollToBottom();", 50);
            setTimeout("getGlobalChat(false);", 100);

        function scrollToBottom() {

        function AngularScope() {
            return angular.element($("#divMessages")).scope();

        function scrollBarAtBottom() {
            var divMessages = $("#divMessages");
            var scrollTop = divMessages.scrollTop();
            var height = divMessages.height();
            var scrollHeight = divMessages[0].scrollHeight;
            if (scrollTop >= scrollHeight - height) {
                return true;
            else {
                return false;

        window.addEventListener("DOMContentLoaded", ContentLoaded, false); 

We will use AngularJS to display all the chat messages and an input field to add new message. AngularJS will dynamically add <table> columns, this needs to be done periodically so I have used setTimeout to call the service again if our previous web service call is a success.

Here is the description of the methods used above:

  • AddGlobalChatMsg: Adds a new message to the global message list
  • GetGlobalChat: Retrieves all the chat messages
  • AngularScope: Returns the scope object being used for the divMessages
  • GetGlobalChat_Complete: This will update our angular model that we are using to dynamically update the chat messages to our page

AngularJS Part: Our controller here is ChatCtrl and we are using $scope.globalChat model to bind our chat data to the page. Angular will dynamically add a single row per chat message whenever our view model is updated.


That was all guys, simple enough right!

Feel free to provide your updates/bugs/corrections for this code. I hope this proves useful for some of you at some point or the other.


This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


About the Author

Software Developer
India India
Just a regular guy writing regular code Smile | :)

My Homepage

You may also be interested in...

Comments and Discussions

QuestionIs there a way for only push new messages? Pin
aberlin23-Oct-14 6:10
memberaberlin23-Oct-14 6:10 
QuestionChat Sample in ASP.NET Pin
pixel.rajeshkumar15-May-14 3:45
memberpixel.rajeshkumar15-May-14 3:45 
AnswerRe: Chat Sample in ASP.NET Pin
Afzaal Ahmad Zeeshan27-Nov-14 9:02
professionalAfzaal Ahmad Zeeshan27-Nov-14 9:02 
GeneralMy vote of 5 Pin
Mohamed Kamal26-Apr-14 9:29
memberMohamed Kamal26-Apr-14 9:29 
QuestionChat Pin
PetarS08924-Mar-14 23:18
memberPetarS08924-Mar-14 23:18 
QuestionChat web Pin
Manish Rathod13-Feb-14 23:53
memberManish Rathod13-Feb-14 23:53 
AnswerRe: Chat web Pin
Nitij Kumar14-Feb-14 5:29
memberNitij Kumar14-Feb-14 5:29 
GeneralMy vote of 5 Pin
Renju Vinod3-Oct-13 23:19
professionalRenju Vinod3-Oct-13 23:19 
GeneralRe: My vote of 5 Pin
Nitij Kumar14-Feb-14 5:29
memberNitij Kumar14-Feb-14 5:29 
QuestionAngular Js with mvc Pin
daman pal singh11-Sep-13 3:45
memberdaman pal singh11-Sep-13 3:45 
BugScroll to bottom Pin
sacad31-Aug-13 6:19
membersacad31-Aug-13 6:19 
GeneralRe: Scroll to bottom Pin
Nitij Kumar31-Aug-13 19:15
memberNitij Kumar31-Aug-13 19:15 
GeneralMy vote of 5 Pin
Member 1023406826-Aug-13 19:32
memberMember 1023406826-Aug-13 19:32 
GeneralRe: My vote of 5 Pin
Nitij Kumar31-Aug-13 19:50
memberNitij Kumar31-Aug-13 19:50 
QuestionTime display error Pin
NitinSingh15-Aug-13 17:16
memberNitinSingh15-Aug-13 17:16 
GeneralMy vote of 2 Pin
arhoads767-Aug-13 10:49
memberarhoads767-Aug-13 10:49 
GeneralRe: My vote of 2 Pin
Nitij Kumar7-Aug-13 19:54
memberNitij Kumar7-Aug-13 19:54 
GeneralMy vote of 5 Pin
raj ch1-Aug-13 0:03
memberraj ch1-Aug-13 0:03 
GeneralRe: My vote of 5 Pin
Nitij Kumar2-Aug-13 7:02
memberNitij Kumar2-Aug-13 7:02 
GeneralNice Explanation. Vote of 5!!!! Pin
parkavikarthi30-Jul-13 22:57
memberparkavikarthi30-Jul-13 22:57 
GeneralRe: Nice Explanation. Vote of 5!!!! Pin
Nitij Kumar2-Aug-13 7:02
memberNitij Kumar2-Aug-13 7:02 
GeneralMy vote of 5 Pin
Humayun Kabir Mamun30-Jul-13 22:33
memberHumayun Kabir Mamun30-Jul-13 22:33 
GeneralRe: My vote of 5 Pin
Nitij Kumar2-Aug-13 7:01
memberNitij Kumar2-Aug-13 7:01 
Questionknockout & AngularJS both are used for same purpose Pin
Tridip Bhattacharjee30-Jul-13 8:42
memberTridip Bhattacharjee30-Jul-13 8:42 
GeneralRe: knockout & AngularJS both are used for same purpose Pin
Nitij Kumar30-Jul-13 19:00
memberNitij Kumar30-Jul-13 19:00 
GeneralRe: knockout & AngularJS both are used for same purpose Pin
arhoads767-Aug-13 10:52
memberarhoads767-Aug-13 10:52 
QuestionScreen shots Pin
Boipelo30-Jul-13 4:36
memberBoipelo30-Jul-13 4:36 
QuestionI am getting an exception!! Pin
Mannava Siva Aditya30-Jul-13 2:44
memberMannava Siva Aditya30-Jul-13 2:44 
AnswerRe: I am getting an exception!! Pin
Nitij Kumar30-Jul-13 2:51
memberNitij Kumar30-Jul-13 2:51 
GeneralRe: I am getting an exception!! Pin
Mannava Siva Aditya30-Jul-13 2:56
memberMannava Siva Aditya30-Jul-13 2:56 
Question[ScriptService] Pin
Member 988248630-Jul-13 1:43
memberMember 988248630-Jul-13 1:43 
AnswerRe: [ScriptService] Pin
Nitij Kumar30-Jul-13 2:49
memberNitij Kumar30-Jul-13 2:49 
GeneralMy vote of 5 Pin
giri00129-Jul-13 20:53
membergiri00129-Jul-13 20:53 
GeneralNice Pin
CodeHawkz29-Jul-13 20:39
memberCodeHawkz29-Jul-13 20:39 
GeneralRe: Nice Pin
Nitij Kumar29-Jul-13 22:51
memberNitij Kumar29-Jul-13 22:51 
GeneralMy vote of 1 Pin
alvas29-Jul-13 14:23
memberalvas29-Jul-13 14:23 
GeneralRe: My vote of 1 Pin
Nitij Kumar29-Jul-13 17:32
memberNitij Kumar29-Jul-13 17:32 
GeneralRe: My vote of 1 Pin
alvas29-Jul-13 22:27
memberalvas29-Jul-13 22:27 
Questionplease upload ur source code in downloadable format Pin
Tridip Bhattacharjee29-Jul-13 4:38
memberTridip Bhattacharjee29-Jul-13 4:38 
BugError calling service when apostrophe is used. Pin
dadcox29-Jul-13 4:19
memberdadcox29-Jul-13 4:19 
GeneralRe: Error calling service when apostrophe is used. Pin
Nitij Kumar29-Jul-13 17:55
memberNitij Kumar29-Jul-13 17:55 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.151002.1 | Last Updated 24 Aug 2013
Article Copyright 2013 by Nitij
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid