Implementing Inbox Messaging System in ASP.NET

In this post, I would like to write about creating a simple Messaging System for your application. Almost all user based applications require some form of messaging system. Mainly the messaging system is needed so that users within the application can send messages to one another and also, it is needed to show any form of message to the users by the Admin of the application.

I will first show the table design for this simple messaging system and then write about how one can create an implementation.

So, the table structure will basically look like this:

Most of the fields here need no clarification. The one important field that you have to make note of is “ParentMessageId“. This field is used to keep track of whether a message is a reply to a previous message or not.

Basically, if a new message was created, the ParentMessageId will be set as zero (0). If a message is a reply to a previous message, this value will be set as integer value of the previous MessageId value.

Next, the implementation, which would be something like this.


public interface IMessageService
{
void SendMessage(MessageModel messageModel);
List<MessageModel> GetAllCoversationsForUser(int userId);
int GetNewMessagesCount(int userId);
void SetMessageViewed(int messageId);
}

All we need are these four public methods and using these four methods, you can easily implement your Inbox Messaging System.

SendMessage: This method simply inserts a new entry inside our table. Again, as mentioned above, you will have to make sure that you check whether the message is an entirely new one i.e. between two users who not communicated in the past, or a reply to an existing thread. You can check that in this fashion:


var prevMessage = context.Messages.Filter(p => (p.ReceiverId == receiverId && p.SenderId == senderId) || (p.ReceiverId == senderId && p.SenderId == receiverId));

GetAllCoversationsForUser: Now, while retrieving the messages, first of all you have to retrieve all those messages where either the Sender or the Receiver user is the current user in context.


var messages = context.Messages.Filter(p => p.SenderId == userId || p.ReceiverId == userId).OrderByDescending(p=>p.MessageId);

Next, you will have to identify which one is the parent message and which ones are the child messages.

Identifying parent message is simple. All you have to do is check whether the ParentMessageId is equal to zero or not.

Below, I have shown the full implementation of how you can retrieve all the child messages for a given parent message.


private readonly List<MessageModel> messageHistory = new List<MessageModel>();

private void GetChildMessages(int messageId, List<MessageModel> lsMessages, int currentUserId)
{
var childMsg = lsMessages.FirstOrDefault(p => p.ParentMessageId == messageId);

if (childMsg != null)
{
messageHistory.Add(childMsg);
GetChildMessages(childMsg.MessageId, lsMessages, currentUserId);
}
}

In this way, using a recursive method, we can collect the child messages for a given parent message. All the child messages are available in the list “messageHistory “.

GetNewMessagesCount: This method is basically used to check if a user has any new unread messages or not so that you can show a new notification for him.

SetMessageViewed: Finally, this method is used to update a message viewed identifier once a message has been viewed by the user. One important thing to make note of on writing implementation of this method is that you have to make sure the message Sender is not the same as current user in context.


if (!childMsg.IsViewed && currentUserId!=childMsg.SenderId)
{
messageService.SetMessageViewed(childMsg.MessageId);
}

If you do not check for this, you might end up updating messages to “viewed” even when the sender views the messages.

That’s about it for our Inbox Messaging System. Simple isn’t it?

Do not hesitate to put in your questions or confusions regarding this implementation if you have any on the comments section below and I would love to help you out.

Thanks!

Tags: , , , ,