@model IEnumerable<DevExtreme.NETCore.Demos.Models.DisableDatesAppointment>
@(Html.DevExtreme().Scheduler()
    .ID("scheduler")
    .DataSource(Model)
    .TextExpr("Text")
    .StartDateExpr("StartDate")
    .EndDateExpr("EndDate")
    .Views(new[] { SchedulerViewType.WorkWeek, SchedulerViewType.Month })
    .CurrentView(SchedulerViewType.WorkWeek)
    .CurrentDate(new DateTime(2021, 4, 27))
    .FirstDayOfWeek(FirstDayOfWeek.Sunday)
    .StartDayHour(9)
    .EndDayHour(19)
    .ShowAllDayPanel(false)
    .Height(730)
    .DataCellTemplate(new JS("dataCellTemplate"))
    .DateCellTemplate(new JS("dateCellTemplate"))
    .TimeCellTemplate(new JS("timeCellTemplate"))
    .OnContentReady("onContentReady")
    .OnAppointmentFormOpening("onAppointmentFormOpening")
    .OnAppointmentAdding("onAppointmentAdding")
    .OnAppointmentUpdating("onAppointmentUpdating")
)
<script>
    var dinnerTime = { from: 12, to: 13 };
    var holidays = [
        new Date(2021, 3, 29),
        new Date(2021, 5, 6)
    ];
    var ariaDescription = () => {
        const disabledDates = holidays
            .filter((date) => !isWeekend(date))
            .map((date) => new Date(date).toLocaleDateString('en-US', {
                weekday: 'long',
                year: 'numeric',
                month: 'long',
                day: 'numeric',
            })
            );
        if (disabledDates?.length === 1) {
            return `${disabledDates} is a disabled date`;
        }
        if (disabledDates?.length > 1) {
            return `${disabledDates.join(', ')} are disabled dates`;
        }
    };
    function dataCellTemplate(itemData, itemIndex, itemElement) {
        var date = itemData.startDate;
        var isDisabled = isHoliday(date) || isWeekend(date);
        var element = $('<div />');
        if (isDisabled) {
            element.addClass('disable-date');
        } else if (isDinner(date)) {
            element.addClass('dinner');
        }
        return itemElement.append(element);
    }
    function dateCellTemplate(itemData, itemIndex, itemElement) {
        var element = $('<div>' + itemData.text + '</div>');
        if (isWeekend(itemData.date)) {
            element.addClass('disable-date');
        }
        return itemElement.append(element);
    }
    function timeCellTemplate(itemData, itemIndex, itemElement) {
        var element = $('<div>' + itemData.text + '</div>');
        var date = itemData.date;
        if (isDinner(date)) {
            element.addClass('dinner');
        }
        if (hasCoffeeCupIcon(date)) {
            element.append('<div class="cafe" />');
        }
        return itemElement.append(element);
    }
    function onContentReady(e) {
        setComponentAria(e.component?.$element());
    }
    function onAppointmentFormOpening(e) {
        var startDate = new Date(e.appointmentData.StartDate);
        if(!isValidAppointmentDate(startDate)) {
            e.cancel = true;
            notifyDisableDate();
        }
        applyDisableDatesToDateEditors(e.form);
    }
    function onAppointmentAdding(e) {
        if(!isValidAppointment(e.component, e.appointmentData)) {
            e.cancel = true;
            notifyDisableDate();
        }
    }
    function onAppointmentUpdating(e) {
        if(!isValidAppointment(e.component, e.newData)) {
            e.cancel = true;
            notifyDisableDate();
        }
    }
    function notifyDisableDate() {
        DevExpress.ui.notify("This date is disabled", "warning", 500);
    }
    function isValidAppointment(component, appointmentData) {
        var startDate = new Date(appointmentData.StartDate);
        var endDate = new Date(appointmentData.EndDate);
        var cellDuration = component.option('cellDuration');
        return isValidAppointmentInterval(startDate, endDate, cellDuration);
    }
    function isValidAppointmentInterval(startDate, endDate, cellDuration) {
        var edgeEndDate = new Date(endDate.getTime() - 1);
        if (!isValidAppointmentDate(edgeEndDate)) {
            return false;
        }
        var durationInMs = cellDuration * 60 * 1000;
        var date = startDate;
        while (date <= endDate) {
            if (!isValidAppointmentDate(date)) {
                return false;
            }
            var newDateTime = date.getTime() + durationInMs - 1;
            date.setTime(newDateTime);
        }
        return true;
    }
    function isValidAppointmentDate(date) {
        return !isHoliday(date) && !isDinner(date) && !isWeekend(date);
    }
    function isHoliday(date) {
        var localeDate = date.toLocaleDateString();
        return holidays.filter(function(holiday) {
            return holiday.toLocaleDateString() === localeDate;
        }).length > 0;
    }
    function isWeekend(date) {
        var day = date.getDay();
        return day === 0 || day === 6;
    }
    function isDinner(date) {
        var hours = date.getHours();
        return hours >= dinnerTime.from && hours < dinnerTime.to;
    }
    function hasCoffeeCupIcon(date) {
        var hours = date.getHours();
        var minutes = date.getMinutes();
        return hours === dinnerTime.from && minutes === 0;
    }
    function applyDisableDatesToDateEditors(form) {
        var startDateEditor = form.getEditor('StartDate');
        startDateEditor.option('disabledDates', holidays);
        var endDateEditor = form.getEditor('EndDate');
        endDateEditor.option('disabledDates', holidays);
    }
    function setComponentAria(element) {
        const prevAria = element?.attr('aria-label') || '';
        element?.attr('aria-label', `${prevAria} ${ariaDescription()}`);
    }
</script>
        
        using Microsoft.AspNetCore.Mvc;
using DevExtreme.NETCore.Demos.Models.SampleData;
using DevExtreme.NETCore.Demos.ViewModels;
namespace DevExtreme.NETCore.Demos.Controllers {
    public class SchedulerController : Controller {
        public ActionResult CellTemplates() {
            return View(SampleData.AppointmentsWorkHours);
        }
    }
}
        
        using System;
using System.Text.Json.Serialization;
namespace DevExtreme.NETCore.Demos.Models {
    public class Appointment {
        [JsonPropertyName("AppointmentId")]
        public int AppointmentId { get; set; }
        [JsonPropertyName("Text")]
        public string Text { get; set; }
        [JsonPropertyName("Description")]
        public string Description { get; set; }
        [JsonPropertyName("StartDate")]
        public string StartDate { get; set; }
        [JsonPropertyName("EndDate")]
        public string EndDate { get; set; }
        [JsonPropertyName("AllDay")]
        public bool AllDay { get; set; }
        [JsonPropertyName("RecurrenceRule")]
        public string RecurrenceRule { get; set; }
        [JsonPropertyName("RecurrenceException")]
        public string RecurrenceException { get; set; }
    }
    public class DisableDatesAppointment {
        [JsonPropertyName("AppointmentId")]
        public int AppointmentId { get; set; }
        [JsonPropertyName("Text")]
        public string Text { get; set; }
        [JsonPropertyName("Description")]
        public string Description { get; set; }
        [JsonPropertyName("StartDate")]
        public DateTime StartDate { get; set; }
        [JsonPropertyName("EndDate")]
        public DateTime EndDate { get; set; }
        [JsonPropertyName("AllDay")]
        public bool AllDay { get; set; }
        [JsonPropertyName("RecurrenceRule")]
        public string RecurrenceRule { get; set; }
        [JsonPropertyName("RecurrenceException")]
        public string RecurrenceException { get; set; }
    }
}
        
        using System;
using System.Collections.Generic;
using System.Linq;
namespace DevExtreme.NETCore.Demos.Models.SampleData {
    public partial class SampleData {
        public static readonly IEnumerable<DisableDatesAppointment> AppointmentsWorkHours = new[] {
            new DisableDatesAppointment {
                Text = "Website Re-Design Plan",
                StartDate = new DateTime(2021, 4, 26, 9, 30, 0),
                EndDate = new DateTime(2021, 4, 26, 11, 30, 0)
            },
            new DisableDatesAppointment {
                Text = "Install New Router in Dev Room",
                StartDate = new DateTime(2021, 4, 26, 13, 0, 0),
                EndDate = new DateTime(2021, 4, 26, 14, 0, 0)
            },
            new DisableDatesAppointment {
                Text = "Approve Personal Computer Upgrade Plan",
                StartDate = new DateTime(2021, 4, 27, 10, 0, 0),
                EndDate = new DateTime(2021, 4, 27, 11, 0, 0)
            },
            new DisableDatesAppointment {
                Text = "Final Budget Review",
                StartDate = new DateTime(2021, 4, 27, 13, 30, 0),
                EndDate = new DateTime(2021, 4, 27, 15, 0, 0)
            },
            new DisableDatesAppointment {
                Text = "New Brochures",
                StartDate = new DateTime(2021, 4, 26, 15, 0, 0),
                EndDate = new DateTime(2021, 4, 26, 16, 15, 0)
            },
            new DisableDatesAppointment {
                Text = "Install New Database",
                StartDate = new DateTime(2021, 4, 28, 9, 45, 0),
                EndDate = new DateTime(2021, 4, 28, 12, 0, 0)
            },
            new DisableDatesAppointment {
                Text = "Approve New Online Marketing Strategy",
                StartDate = new DateTime(2021, 4, 28, 14, 30, 0),
                EndDate = new DateTime(2021, 4, 28, 16, 30, 0)
            },
            new DisableDatesAppointment {
                Text = "Upgrade Personal Computers",
                StartDate = new DateTime(2021, 4, 27, 15, 30, 0),
                EndDate = new DateTime(2021, 4, 27, 16, 45, 0)
            },
            new DisableDatesAppointment {
                Text = "Prepare 2021 Marketing Plan",
                StartDate = new DateTime(2021, 5, 3, 13, 0, 0),
                EndDate = new DateTime(2021, 5, 3, 15, 0, 0)
            },
            new DisableDatesAppointment {
                Text = "Brochure Design Review",
                StartDate = new DateTime(2021, 5, 4, 15, 30, 0),
                EndDate = new DateTime(2021, 5, 5, 0, 0, 0)
            },
            new DisableDatesAppointment {
                Text = "Create Icons for Website",
                StartDate = new DateTime(2021, 4, 30, 10, 0, 0),
                EndDate = new DateTime(2021, 4, 30, 12, 0, 0)
            },
            new DisableDatesAppointment {
                Text = "Upgrade Server Hardware",
                StartDate = new DateTime(2021, 4, 30, 16, 30, 0),
                EndDate = new DateTime(2021, 4, 30, 18, 0, 0)
            },
            new DisableDatesAppointment {
                Text = "Submit New Website Design",
                StartDate = new DateTime(2021, 5, 5, 10, 0, 0),
                EndDate = new DateTime(2021, 5, 5, 11, 30, 0)
            },
            new DisableDatesAppointment {
                Text = "Launch New Website",
                StartDate = new DateTime(2021, 4, 30, 14, 30, 0),
                EndDate = new DateTime(2021, 4, 30, 16, 10, 0)
            }
        };
    }
}
        
        @-moz-document url-prefix() {
    .dx-scheduler-work-space-month .dx-scheduler-date-table-cell {
        position: relative;
    }
    .dx-scheduler-work-space-month .dx-scheduler-date-table-cell .disable-date {
        position: absolute;
        width: 100%;
        height: 100%;
    }
}
.disable-date,
.dinner {
    height: 100%;
    width: 100%;
}
.disable-date {
    background-image:
      repeating-linear-gradient(
        135deg,
        rgba(247, 234, 224, 1),
        rgba(247, 234, 224, 1) 4px,
        transparent 4px,
        transparent 9px
      );
    color: rgba(178, 74, 0, 1);
}
.dx-scheduler-header-panel-cell .disable-date {
    display: flex;
    flex-direction: column;
    justify-content: center;
}
.dx-theme-fluent .dx-scheduler-header-panel-cell .disable-date,
.dx-theme-material .dx-scheduler-header-panel-cell .disable-date {
    flex-direction: row;
    align-items: flex-end;
    justify-content: initial;
}
.dinner {
    background: #FBF1EB;
}
.dx-scheduler-time-panel-cell .dinner {
    color: #C25100;
    font-weight: 400;
    background: transparent;
}
.dx-draggable {
    cursor: auto;
}
td.dx-scheduler-time-panel-cell .dinner .cafe {
    height: 200%;
    width: 100%;
    left: 50%;
    -webkit-mask: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M20 3H4v10c0 2.21 1.79 4 4 4h6c2.21 0 4-1.79 4-4v-3h2c1.11 0 2-.9 2-2V5c0-1.11-.89-2-2-2zm0 5h-2V5h2v3zM4 19h16v2H4z"/></svg>');
    -webkit-mask-repeat: no-repeat;
    -webkit-mask-position-y: 50%;
    -webkit-mask-position-x: 100%;
    margin-top: -4px;
    background-color: #C25100;
}
.dx-scheduler-date-table-cell {
    padding: 0;
    opacity: 1;
}
@media all and (-ms-high-contrast:none)
{
    td.dx-scheduler-time-panel-cell .dinner .cafe {
        background-color: transparent;
    }
}