File Attachments in ASP.NET CORE Chat UI control

15 Dec 202523 minutes to read

The Chat UI control supports message attachments, enabling users to upload and send files (images, documents, and more) alongside messages for richer, more contextual conversations. Enable this functionality using the enableAttachments property and customize the behavior through the attachmentSettings configuration.

Enable file attachments

Enable file attachment support by setting the enableAttachments property to true. By default, it is false.

@using Syncfusion.EJ2.InteractiveChat;

<div style="height:380px; width:450px">
    <ejs-chatui id="chatUser" enableAttachments="true">
        <e-chatui-user id="user1" user="Albert"></e-chatui-user>
    </ejs-chatui>
</div>
using Syncfusion.EJ2.InteractiveChat;

public ChatUIUser CurrentUser { get; set; }
public ChatUIUser CurrentUserModel { get; set; } = new ChatUIUser() { Id = "user1", User = "Albert" };

public ActionResult EnableAttachments()
{
    CurrentUser = CurrentUserModel;
    ViewBag.CurrentUser = CurrentUser;
    return View();
}

Configure attachment settings

Use the e-chatui-attachmentsettings tag directive to customize file attachment behavior, including upload endpoints, file type restrictions, and size limits.

Setting saveUrl and removeUrl

Set the saveUrl and removeUrl properties to specify server endpoints for handling file uploads and removals. The saveUrl processes file uploads, while the removeUrl handles file deletion requests.

@using Syncfusion.EJ2.InteractiveChat;

<div style="height:380px; width:450px">
    <ejs-chatui id="chatUser" enableAttachments="true">
        <e-chatui-user id="user1" user="Albert"></e-chatui-user>
        <e-chatui-attachmentsettings saveUrl=@Url.Content("https://services.syncfusion.com/aspnet/production/api/FileUploader/Save") removeUrl=@Url.Content("https://services.syncfusion.com/aspnet/production/api/FileUploader/Remove")></e-chatui-attachmentsettings>
    </ejs-chatui>
</div>
using Syncfusion.EJ2.InteractiveChat;

public ChatUIUser CurrentUser { get; set; }
public ChatUIUser CurrentUserModel { get; set; } = new ChatUIUser() { Id = "user1", User = "Albert" };

public ActionResult SaveRemoveUrl()
{
    CurrentUser = CurrentUserModel;
    ViewBag.CurrentUser = CurrentUser;
    return View();
}

Setting file type

Use the allowedFileTypes property to specify which file types users can upload. This property accepts file extensions (e.g., ‘.pdf’, ‘.docx’) or MIME types to control the types of files that can be attached.

@using Syncfusion.EJ2.InteractiveChat;

<div style="height:380px; width:450px">
    <ejs-chatui id="chatUser" enableAttachments="true">
        <e-chatui-user id="user1" user="Albert"></e-chatui-user>
        <e-chatui-attachmentsettings allowedFileTypes=".pdf" saveUrl=@Url.Content("https://services.syncfusion.com/aspnet/production/api/FileUploader/Save") removeUrl=@Url.Content("https://services.syncfusion.com/aspnet/production/api/FileUploader/Remove")></e-chatui-attachmentsettings>
    </ejs-chatui>
</div>
using Syncfusion.EJ2.InteractiveChat;

public ChatUIUser CurrentUser { get; set; }
public ChatUIUser CurrentUserModel { get; set; } = new ChatUIUser() { Id = "user1", User = "Albert" };

public ActionResult AllowedFileTypes()
{
    CurrentUser = CurrentUserModel;
    ViewBag.CurrentUser = CurrentUser;
    return View();
}

Setting file size

Configure the maxFileSize property to define the maximum file size allowed for uploads. Specify the size in bytes. The default value is 30000000 bytes (approximately 30 MB). Files exceeding this limit will not be uploaded.

@using Syncfusion.EJ2.InteractiveChat;

<div style="height:380px; width:450px">
    <ejs-chatui id="chatUser" enableAttachments="true">
        <e-chatui-user id="user1" user="Albert"></e-chatui-user>
        <e-chatui-attachmentsettings maxFileSize=4000000 saveUrl=@Url.Content("https://services.syncfusion.com/aspnet/production/api/FileUploader/Save") removeUrl=@Url.Content("https://services.syncfusion.com/aspnet/production/api/FileUploader/Remove")></e-chatui-attachmentsettings>
    </ejs-chatui>
</div>
using Syncfusion.EJ2.InteractiveChat;

public ChatUIUser CurrentUser { get; set; }
public ChatUIUser CurrentUserModel { get; set; } = new ChatUIUser() { Id = "user1", User = "Albert" };

public ActionResult MaxFileSize()
{
    CurrentUser = CurrentUserModel;
    ViewBag.CurrentUser = CurrentUser;
    return View();
}

MaxFileSize

Setting save format

Control the format used to send files to the server using the saveFormat property when path is not set. It does not change how files are uploaded. The default value is Blob.

  • Blob: Used for fast, memory‑efficient local previews.
  • Base64: Reads the file as a Base64 data URL, useful when you need an inline data URL.
@using Syncfusion.EJ2.InteractiveChat;

<div style="height:380px; width:450px">
    <ejs-chatui id="chatUser" enableAttachments="true">
        <e-chatui-user id="user1" user="Albert"></e-chatui-user>
        <e-chatui-attachmentsettings saveFormat="Base64" saveUrl=@Url.Content("https://services.syncfusion.com/aspnet/production/api/FileUploader/Save") removeUrl=@Url.Content("https://services.syncfusion.com/aspnet/production/api/FileUploader/Remove")></e-chatui-attachmentsettings>
    </ejs-chatui>
</div>
using Syncfusion.EJ2.InteractiveChat;

public ChatUIUser CurrentUser { get; set; }
public ChatUIUser CurrentUserModel { get; set; } = new ChatUIUser() { Id = "user1", User = "Albert" };

public ActionResult SaveFormat()
{
    CurrentUser = CurrentUserModel;
    ViewBag.CurrentUser = CurrentUser;
    return View();
}

Setting server path

The path property to specifies the public base URL where uploaded files are (or will be) hosted. When set, it takes precedence over saveFormat.

@using Syncfusion.EJ2.InteractiveChat;

<div style="height:380px; width:450px">
    <ejs-chatui id="chatUser" enableAttachments="true">
        <e-chatui-user id="user1" user="Albert"></e-chatui-user>
        <e-chatui-attachmentsettings path="D:/CustomPathLocation" saveUrl=@Url.Content("https://services.syncfusion.com/aspnet/production/api/FileUploader/Save") removeUrl=@Url.Content("https://services.syncfusion.com/aspnet/production/api/FileUploader/Remove")></e-chatui-attachmentsettings>
    </ejs-chatui>
</div>
using Syncfusion.EJ2.InteractiveChat;

public ChatUIUser CurrentUser { get; set; }
public ChatUIUser CurrentUserModel { get; set; } = new ChatUIUser() { Id = "user1", User = "Albert" };

public ActionResult Path()
{
    CurrentUser = CurrentUserModel;
    ViewBag.CurrentUser = CurrentUser;
    return View();
}

Enabling drag-and-drop

Toggle drag-and-drop support for attachments via enableDragAndDrop property. The default value is true.

@using Syncfusion.EJ2.InteractiveChat;

<div style="height:380px; width:450px">
    <ejs-chatui id="chatUser" enableAttachments="true">
        <e-chatui-user id="user1" user="Albert"></e-chatui-user>
        <e-chatui-attachmentsettings enableDragAndDrop=false saveUrl=@Url.Content("https://services.syncfusion.com/aspnet/production/api/FileUploader/Save") removeUrl=@Url.Content("https://services.syncfusion.com/aspnet/production/api/FileUploader/Remove")></e-chatui-attachmentsettings>
    </ejs-chatui>
</div>
using Syncfusion.EJ2.InteractiveChat;

public ChatUIUser CurrentUser { get; set; }
public ChatUIUser CurrentUserModel { get; set; } = new ChatUIUser() { Id = "user1", User = "Albert" };

public ActionResult DragAndDrop()
{
    CurrentUser = CurrentUserModel;
    ViewBag.CurrentUser = CurrentUser;
    return View();
}

Setting maximum count

Restrict how many files can be attached at once using maximumCount. The default value is 10. If users select more than the allowed count, the maxfileSize error will be displayed.

@using Syncfusion.EJ2.InteractiveChat;

<div style="height:380px; width:450px">
    <ejs-chatui id="chatUser" enableAttachments="true">
        <e-chatui-user id="user1" user="Albert"></e-chatui-user>
        <e-chatui-attachmentsettings maximumCount=2 saveUrl=@Url.Content("https://services.syncfusion.com/aspnet/production/api/FileUploader/Save") removeUrl=@Url.Content("https://services.syncfusion.com/aspnet/production/api/FileUploader/Remove")></e-chatui-attachmentsettings>
    </ejs-chatui>
</div>
using Syncfusion.EJ2.InteractiveChat;

public ChatUIUser CurrentUser { get; set; }
public ChatUIUser CurrentUserModel { get; set; } = new ChatUIUser() { Id = "user1", User = "Albert" };

public ActionResult MaximumCount()
{
    CurrentUser = CurrentUserModel;
    ViewBag.CurrentUser = CurrentUser;
    return View();
}

MaximumCount

Templates

Customizing the file preview

Provide a custom UI for previewing selected files using previewTemplate. Use this to render thumbnails, filenames, progress, remove buttons, or any additional metadata prior to sending.

Customizing the attachments

Control how attachments appear inside message bubbles with attachmentTemplate. Use this to tailor the display of images, documents, or custom file types once the message is posted.

@using Syncfusion.EJ2.InteractiveChat;
<div style="height:380px; width:450px">
    <ejs-chatui id="chatUser" cssClass="chat-attachment-template" enableAttachments="true">
        <e-chatui-user id="user1" user="Albert"></e-chatui-user>
        <e-chatui-attachmentsettings saveUrl=@Url.Content("https://services.syncfusion.com/aspnet/production/api/FileUploader/Save")
                                     removeUrl=@Url.Content("https://services.syncfusion.com/aspnet/production/api/FileUploader/Remove")
                                     attachmentTemplate="#attachmentTemplate"
                                     previewTemplate="#previewTemplate">
        </e-chatui-attachmentsettings>
    </ejs-chatui>
</div>

<script id="attachmentTemplate" type="text/x-jsrender">
    ${renderAttachmentChip(selectedFile)}
</script>

<script id="previewTemplate" type="text/x-jsrender">
    ${renderPreviewCard(selectedFile)}
</script>

<script>
    function getMime(file) {
      var t = ((file && file.rawFile && file.rawFile.type) || (file && file.type) || '').toLowerCase();
      return t;
    }
    function getType(file) {
      var t = getMime(file);
      if (!t) return '';
      var parts = t.split('/');
      return parts.length > 1 ? parts[1].toUpperCase() : t.toUpperCase();
    }
    function getExt(file) {
      var name = (file && file.name) || '';
      var parts = name.split('.');
      return parts.length > 1 ? parts.pop().toUpperCase() : '';
    }
    function isImage(file) { var t = getMime(file); return t && t.indexOf('image/') === 0; }
    function isVideo(file) { var t = getMime(file); return t && t.indexOf('video/') === 0; }
    function getHumanSize(file) {
      var sizeBytes = (file && file.size) || 0;
      if (sizeBytes < 1024) return sizeBytes + ' B';
      if (sizeBytes < 1024 * 1024) return (sizeBytes / 1024).toFixed(1) + ' KB';
      return (sizeBytes / (1024 * 1024)).toFixed(1) + ' MB';
    }
    function renderAttachmentChip(file) {
      var isImg = isImage(file); var isVid = isVideo(file);
      var iconHtml = isImg
        ? '<img class="c-attach-img" src="' + (file.fileSource || '') + '" alt="' + (file.name || '') + '">'
        : (isVid ? '<span class="e-icons e-video"></span>' : '<span class="e-icons e-chat-file-icon"></span>');
      var typeText = (file && (file.type || (file.rawFile && file.rawFile.type) || '')) || '';
      return (
        '<div class="c-attach">' +
          '<div class="c-attach-thumb">' + iconHtml + '</div>' +
          '<div class="c-attach-body">' +
            '<div class="c-attach-name" title="' + (file.name || '') + '">' + (file.name || '') + '</div>' +
            '<div class="c-attach-meta">' + typeText + '</div>' +
          '</div>' +
        '</div>'
      );
    }
    function renderPreviewCard(file) {
      var badge = getExt(file) || (getType(file) || 'FILE');
      var size = getHumanSize(file);
      var mediaHtml = isImage(file)
        ? '<img class="c-media-img" src="' + (file.fileSource || '') + '" alt="' + (file.name || '') + '">'
        : (isVideo(file)
            ? '<video class="c-media-video" controls disablePictureInPicture playsInline preload="metadata" title="' + (file.name || '') + '">' +
                '<source src="' + (file.fileSource || '') + '" type="' + getMime(file) + '">' +
              '</video>'
            : '<div>No media content to display</div>');
      return (
        '<div>' +
        '<div class="c-preview--card">' +
          '<div class="c-preview-card">' +
            '<div class="c-badge-row">' +
              '<span class="c-badge">' + badge + '</span>' +
              '<span>' + size + '</span>' +
            '</div>' +
            '<div class="c-media-frame">' + mediaHtml + '</div>' +
            '<div class="c-caption">' +
              '<span class="c-name" title="' + (file.name || '') + '">' + (file.name || '') + '</span>' +
              '<a class="c-btn-link" href="' + (file.fileSource || '#') + '" target="_blank" rel="noopener noreferrer" download="' + (file.name || '') + '">Download</a>' +
            '</div>' +
          '</div>' +
        '</div>' +
        '</div>'
      );
    }
</script>

<style>
    /* Attachment template styles */
    .chat-attachment-template .c-attach {
        display: flex;
        align-items: center;
        gap: 8px;
        padding: 8px 10px;
        border-radius: 8px;
    }

    .chat-attachment-template .c-attach-thumb {
        width: 24px;
        height: 24px;
        border-radius: 6px;
        overflow: hidden;
    }

    .chat-attachment-template .c-attach-name {
        width: 100px;
        text-overflow: ellipsis;
        overflow: hidden;
        white-space: nowrap;
    }

    .chat-attachment-template .c-attach-img {
        width: 100%;
        height: 100%;
        object-fit: cover;
    }

    .chat-attachment-template .c-attach-meta {
        font-size: 11px;
        color: #757575;
    }

    .chat-attachment-template .e-footer .e-chat-drop-area .e-chat-uploaded-file-item {
        width: auto;
        max-width: fit-content;
    }
    /* Preview template styles*/
    /* Center a compact white card inside the dark preview overlay */
    .chat-attachment-template .c-preview--card {
        display: grid;
        place-items: center;
        width: 100%;
        height: 100%;
        padding: 12px;
        box-sizing: border-box;
    }

    .chat-attachment-template .c-preview-card {
        background: #fff;
        border-radius: 12px;
        box-shadow: 0 8px 24px rgba(0,0,0,0.16);
        padding: 12px;
        display: grid;
        gap: 10px;
    }
    /* Small info row (type + size) */
    .chat-attachment-template .c-badge-row {
        display: flex;
        gap: 8px;
        font-size: 12px;
        color: #616161;
    }

    .chat-attachment-template .c-badge {
        padding: 2px 8px;
        border-radius: 999px;
        background: #eef2ff;
        color: #3f51b5;
        font-weight: 600;
    }
    /* Media area with tidy aspect */
    .chat-attachment-template .c-media-frame {
        background: #0b0b0b;
        border-radius: 10px;
        overflow: hidden;
        aspect-ratio: 16/9;
        display: grid;
        place-items: center;
        font-size: large;
        font-weight: 900;
        color: azure;
    }

    .chat-attachment-template .c-media-img, .c-media-video {
        width: 100%;
        height: 100%;
        object-fit: contain;
    }
    /* Caption with ellipsis and a small action */
    .chat-attachment-template .c-caption {
        display: flex;
        align-items: center;
        justify-content: space-between;
        gap: 12px;
    }

    .chat-attachment-template .c-name {
        min-width: 0;
        flex: 1 1 auto;
        white-space: nowrap;
        overflow: hidden;
        text-overflow: ellipsis;
        font-size: 13px;
        color: #212121;
    }

    .chat-attachment-template .c-btn-link {
        font-size: 13px;
        color: #2962ff;
        text-decoration: none;
        font-weight: 600;
    }

    .chat-attachment-template .e-preview-template {
        position: absolute;
        bottom: 5px;
        width: 360px;
        height: 280px;
    }
</style>
using Syncfusion.EJ2.InteractiveChat;

public ChatUIUser CurrentUser { get; set; }
public ChatUIUser CurrentUserModel { get; set; } = new ChatUIUser() { Id = "user1", User = "Albert" };

public ActionResult Template()
{
    CurrentUser = CurrentUserModel;
    ViewBag.CurrentUser = CurrentUser;
    return View();
}

AttachmentTemplate
PreviewTemplate