@model DevExtreme.MVC.Demos.ViewModels.ChatViewModel
@(Html.DevExtreme().Chat()
.ID("user-chat")
.User(user => user
.Id(Model.CurrentUser.Id)
.Name(Model.CurrentUser.Name)
)
.DataSource(Model.Messages)
.ReloadOnChange(false)
.OnMessageEntered("onMessageEntered")
.OnTypingStart("userChatTypingStart")
.OnTypingEnd("userChatTypingEnd")
.OnInitialized("userChatInitialized")
)
@(Html.DevExtreme().Chat()
.ID("support-chat")
.User(user => user
.Id(Model.SupportAgent.Id)
.Name(Model.SupportAgent.Name)
.AvatarUrl(Model.SupportAgent.AvatarUrl)
)
.DataSource(Model.Messages)
.ReloadOnChange(false)
.OnMessageEntered("onMessageEntered")
.OnTypingStart("supportChatTypingStart")
.OnTypingEnd("supportChatTypingEnd")
.OnInitialized("supportChatInitialized")
)
<script>
var userChat, supportChat;
function userChatInitialized({ component }) {
userChat = component;
}
function supportChatInitialized({ component }) {
supportChat = component;
}
function onMessageEntered({ message }) {
userChat.renderMessage(message);
supportChat.renderMessage(message);
}
function userChatTypingStart({ user }) {
supportChat.option('typingUsers', [user]);
}
function userChatTypingEnd() {
supportChat.option('typingUsers', []);
}
function supportChatTypingStart({ user }) {
userChat.option('typingUsers', [user]);
}
function supportChatTypingEnd() {
userChat.option('typingUsers', []);
}
</script>
using System;
using System.Linq;
using System.Collections.Generic;
using System.Web.Mvc;
using DevExtreme.MVC.Demos.Models.Chat;
using DevExtreme.MVC.Demos.Models.SampleData;
using DevExtreme.MVC.Demos.ViewModels;
namespace DevExtreme.MVC.Demos.Controllers {
public class ChatController : Controller {
public ActionResult Overview() {
return View(new ChatViewModel {
CurrentUser = SampleData.CurrentUser,
SupportAgent = SampleData.SupportAgent,
Messages = SampleData.Messages,
});
}
}
}
using DevExtreme.MVC.Demos.Models.Chat;
using System;
using System.Collections.Generic;
namespace DevExtreme.MVC.Demos.Models.SampleData {
public partial class SampleData {
private static readonly DateTime todayDate = DateTime.Now.Date;
private static DateTime GetTimestamp(DateTime date, int offsetMinutes = 0) {
DateTime adjustedDate = date.AddMinutes(offsetMinutes);
return adjustedDate;
}
public static ChatUser CurrentUser = new ChatUser {
Id = "c94c0e76-fb49-4b9b-8f07-9f93ed93b4f3",
Name = "John Doe"
};
public static ChatUser SupportAgent = new ChatUser {
Id = "d16d1a4c-5c67-4e20-b70e-2991c22747c3",
Name = "Support Agent",
AvatarUrl = "../../Content/Images/petersmith.png"
};
public static readonly IEnumerable<Message> Messages = new[] {
new Message {
Timestamp = GetTimestamp(todayDate, -9),
Author = SupportAgent,
Text = "Hello, John!\nHow can I assist you today?",
},
new Message {
Timestamp = GetTimestamp(todayDate, -7),
Author = CurrentUser,
Text = "Hi, I'm having trouble accessing my account.",
},
new Message {
Timestamp = GetTimestamp(todayDate, -7),
Author = CurrentUser,
Text = "It says my password is incorrect."
},
new Message {
Timestamp = GetTimestamp(todayDate, -7),
Author = SupportAgent,
Text = "I can help you with that. Can you please confirm your UserID for security purposes?"
},
new Message {
Timestamp = GetTimestamp(todayDate, 1),
Author = CurrentUser,
Text = "john.doe1357"
},
new Message {
Timestamp = GetTimestamp(todayDate, 1),
Author = SupportAgent,
Text = "✅ Instructions to restore access have been sent to the email address associated with your account."
}
};
public static readonly IEnumerable<Message> MessagesWithAttachments = new[] {
new Message {
Timestamp = GetTimestamp(todayDate, -7),
Author = CurrentUser,
Text = "Hi! I'm having trouble accessing my account.\nThe website says my password is incorrect. I'm sending a few screenshots so you can see where I get the error.",
Attachments = new[] {
new MessageAttachment {
Name = "Pic1.png",
Size = 5842,
Url = "../../Content/images/Chat/Pic1.png",
},
new MessageAttachment {
Name = "Pic2.png",
Size = 6083,
Url = "../../Content/images/Chat/Pic2.png",
},
new MessageAttachment {
Name = "Pic3.png",
Size = 6180,
Url = "../../Content/images/Chat/Pic3.png",
}
},
},
new Message {
Timestamp = GetTimestamp(todayDate, -7),
Author = SupportAgent,
Text = "Hello! Thanks for including screenshots. To restore access, please follow instructions in the attached file.\nLet me know if you need anything else.",
Attachments = new[] {
new MessageAttachment {
Name = "Instructions.png",
Size = 5499,
Url = "../../Content/Images/Chat/Instructions.png",
}
},
}
};
}
}
using DevExtreme.MVC.Demos.Models.Chat;
using System.Collections.Generic;
namespace DevExtreme.MVC.Demos.ViewModels {
public class ChatViewModel {
public IEnumerable<Message> Messages { get; set; }
public IEnumerable<Message> MessagesWithAttachments { get; set; }
public ChatUser CurrentUser { get; set; }
public ChatUser SupportAgent { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Text.Json.Serialization;
namespace DevExtreme.MVC.Demos.Models.Chat
{
public class Message {
[JsonPropertyName("id")]
public string Id { get; set; }
[JsonPropertyName("timestamp")]
public DateTime Timestamp { get; set; }
[JsonPropertyName("author")]
public ChatUser Author { get; set; }
[JsonPropertyName("text")]
public string Text { get; set; }
[JsonPropertyName("isDeleted")]
public Boolean IsDeleted { get; set; }
[JsonPropertyName("isEdited")]
public Boolean IsEdited { get; set; }
[JsonPropertyName("attachments")]
public IEnumerable<MessageAttachment> Attachments { get; set; }
}
}
using System.Text.Json.Serialization;
namespace DevExtreme.MVC.Demos.Models.Chat
{
public class ChatUser {
[JsonPropertyName("id")]
public string Id { get; set; }
[JsonPropertyName("name")]
public string Name { get; set; }
[JsonPropertyName("avatarUrl")]
public string AvatarUrl { get; set; }
}
}
.demo-container {
display: flex;
gap: 20px;
}
.dx-chat {
height: 710px;
}
.dx-avatar {
border: 1px solid var(--dx-color-border);
}