Kendo Mvc CustomKendoMvcExtensions. DataSourceRequest Filters in case of Datetime comparison. Don’t take time into consideration


return Json(requestsList.ToCustomDataSourceResult(request));


public ActionResult GetList([CustomDataSourceRequest]DataSourceRequest request)


using Kendo.Mvc;
using Kendo.Mvc.Extensions;
using Kendo.Mvc.UI;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Web.Mvc;

namespace Kendo.Mvc.Extensions
    public static class CustomKendoMvcExtensions
        /// <summary>
        /// Changes DataSourceRequest Filters in case of Datetime comparison. Does not take time into consideration
        /// //
        /// Adapted from above link.
        /// Uses CustomDataSourceRequestModelBinder.TransformFilterDescriptors function
        /// </summary>
        /// <param name="queryable"></param>
        /// <param name="request"></param>
        /// <returns></returns>
        public static DataSourceResult ToCustomDataSourceResult(this IQueryable queryable, DataSourceRequest request)
            if (request.Filters != null && request.Filters.Count > 0)

                ModelBinders.CustomDataSourceRequestModelBinder customModelBinder = new ModelBinders.CustomDataSourceRequestModelBinder();

                var transformedFilters = request.Filters.Select(customModelBinder.TransformFilterDescriptors).ToList();
                request.Filters = transformedFilters;

            return queryable.ToDataSourceResult(request);

namespace Kendo.Mvc.UI
    public class CustomDataSourceRequestAttribute : DataSourceRequestAttribute
        public override IModelBinder GetBinder()
            return new Kendo.Mvc.ModelBinders.CustomDataSourceRequestModelBinder();

namespace Kendo.Mvc.ModelBinders
    /// <summary>
    /// DateTime filtering is horribly unintuitive in Kendo Grids when a non-default (00:00:00) time is attached
    /// to the grid's datetime data. We use this custom model binder to transform the grid filters to return 
    /// results that ignore the attached time, leading to intuitive results that make users happy.
    /// To use the code, substitute the [DataSourceRequest] attribute for [CustomDataSourceRequest] in your MVC controller
    /// </summary>
    public class CustomDataSourceRequestModelBinder : IModelBinder
        public object BindModel(ControllerContext controllerContext, ModelBindingContext bindingContext)
            // Get an instance of the original kendo model binder and call the binding method
            var baseBinder = new DataSourceRequestModelBinder();
            var request = (DataSourceRequest)baseBinder.BindModel(controllerContext, bindingContext);

            if (request.Filters != null && request.Filters.Count > 0)
                var transformedFilters = request.Filters.Select(TransformFilterDescriptors).ToList();
                request.Filters = transformedFilters;

            return request;

        public IFilterDescriptor TransformFilterDescriptors(IFilterDescriptor filter)
            if (filter is CompositeFilterDescriptor)
                var compositeFilterDescriptor = filter as CompositeFilterDescriptor;
                var transformedCompositeFilterDescriptor = new CompositeFilterDescriptor { LogicalOperator = compositeFilterDescriptor.LogicalOperator };
                foreach (var filterDescriptor in compositeFilterDescriptor.FilterDescriptors)
                return transformedCompositeFilterDescriptor;
            if (filter is FilterDescriptor)
                var filterDescriptor = filter as FilterDescriptor;
                if (filterDescriptor.Value is DateTime)
                    var value = (DateTime)filterDescriptor.Value;
                    switch (filterDescriptor.Operator)
                        case FilterOperator.IsEqualTo:
                            //convert the "is equal to <date><time>" filter to a "is greater than or equal to <date> 00:00:00" AND "is less than or equal to <date> 23:59:59"
                            var isEqualCompositeFilterDescriptor = new CompositeFilterDescriptor { LogicalOperator = FilterCompositionLogicalOperator.And };
                            isEqualCompositeFilterDescriptor.FilterDescriptors.Add(new FilterDescriptor(filterDescriptor.Member,
                                FilterOperator.IsGreaterThanOrEqualTo, new DateTime(value.Year, value.Month, value.Day, 0, 0, 0)));
                            isEqualCompositeFilterDescriptor.FilterDescriptors.Add(new FilterDescriptor(filterDescriptor.Member,
                                FilterOperator.IsLessThanOrEqualTo, new DateTime(value.Year, value.Month, value.Day, 23, 59, 59)));
                            return isEqualCompositeFilterDescriptor;

                        case FilterOperator.IsNotEqualTo:
                            //convert the "is not equal to <date><time>" filter to a "is less than <date> 00:00:00" OR "is greater than <date> 23:59:59"
                            var notEqualCompositeFilterDescriptor = new CompositeFilterDescriptor { LogicalOperator = FilterCompositionLogicalOperator.Or };
                            notEqualCompositeFilterDescriptor.FilterDescriptors.Add(new FilterDescriptor(filterDescriptor.Member,
                                FilterOperator.IsLessThan, new DateTime(value.Year, value.Month, value.Day, 0, 0, 0)));
                            notEqualCompositeFilterDescriptor.FilterDescriptors.Add(new FilterDescriptor(filterDescriptor.Member,
                                FilterOperator.IsGreaterThan, new DateTime(value.Year, value.Month, value.Day, 23, 59, 59)));
                            return notEqualCompositeFilterDescriptor;

                        case FilterOperator.IsGreaterThanOrEqualTo:
                            //convert the "is greater than or equal to <date><time>" filter to a "is greater than or equal to <date> 00:00:00"
                            filterDescriptor.Value = new DateTime(value.Year, value.Month, value.Day, 0, 0, 0);
                            return filterDescriptor;

                        case FilterOperator.IsGreaterThan:
                            //convert the "is greater than <date><time>" filter to a "is greater than <date> 23:59:59"
                            filterDescriptor.Value = new DateTime(value.Year, value.Month, value.Day, 23, 59, 59);
                            return filterDescriptor;

                        case FilterOperator.IsLessThanOrEqualTo:
                            //convert the "is less than or equal to <date><time>" filter to a "is less than or equal to <date> 23:59:59"
                            filterDescriptor.Value = new DateTime(value.Year, value.Month, value.Day, 23, 59, 59);
                            return filterDescriptor;

                        case FilterOperator.IsLessThan:
                            //convert the "is less than <date><time>" filter to a "is less than <date> 00:00:00"
                            filterDescriptor.Value = new DateTime(value.Year, value.Month, value.Day, 0, 0, 0);
                            return filterDescriptor;

                            throw new Exception(string.Format("Filter operator '{0}' is not supported for DateTime member '{1}'", filterDescriptor.Operator, filterDescriptor.Member));
            return filter;

Left side, vertical, scroll through menu

If you want to create a vertical menu that scrolls through the items as you scrolls through the page



<nav id="leftMenu">
	<ul class="sidebar-nav nav leftMenuItems padding-0">
		<li><h4>Navigation Menu</h4></li>
		<li class="active">     <a id="menuItem202" href="#formSectionInstance_202">Menu Item 1</a> </li>
		<li><a id="menuItem203" href="#formSectionInstance_203">Menu Item 2<</a></li>
		<li><a id="menuItem204" href="#formSectionInstance_204">Menu Item 3<</a></li>
		<li><a id="menuItem208" href="#formSectionInstance_208">Menu Item 4<</a></li>
		<li><a id="menuItem206" href="#formSectionInstance_206">Menu Item 5<</a></li>
		<li><a id="menuItem207" href="#formSectionInstance_207_documentUpload">Menu Item 6<</a></li>



function BindEventsToFormMenuItems()
	// Cache selectors
	var lastId,
		topMenu = $("#navbar"),
		leftMenu = $("#leftMenu"),
		topMenuHeight = topMenu.outerHeight() + 15,
		// All list items
		menuItems = leftMenu.find("a"),
		// Anchors corresponding to menu items
		scrollItems = ()
			var item = $($(this).attr("href"));
			if (item.length) { return item; }

	// Bind click handler to menu items
	// so we can get a fancy scroll animation
	menuItems.each(function (index) {
		$(this).click(function (e) {
			var href = $(this).attr("href"),
				offsetTop = href === "#" ? 0 : $(href).offset().top - topMenuHeight + 1;
			$('html, body').stop().animate({
				scrollTop: offsetTop
			}, 300);
			if ($('#menu-toggle').is(':visible'))


	// Bind to scroll
	$(window).scroll(function ()
		// Get container scroll position
		var fromTop = $(this).scrollTop() + topMenuHeight + 50;

		// Get id of current scroll item
		var cur = ()
			if ($(this).offset().top < fromTop)
				return this;
		// Get the id of the current element
		cur = cur[cur.length - 1];
		var id = cur && cur.length ? cur[0].id : "";

		if (lastId !== id)
			lastId = id;
			// Set/remove active class
			  .end().filter("[href='#" + id + "']").parent().addClass("active");

SQL Server – make a copy of parent child rows

Let us say we have 2 tables that are in a parent-child relation.

We want to make a copy of the FormSectionInstance rows, but also copy and correlate the FormDetails rows.

This means copy rows from 2 tables and then set them up with the correct NEW corresponding IDs.

We could use a cursor, but a better alternative is the the MERGE INTO function.

We also create a TEMP transition table to hold the new VS old values. We use these values when we insert the CHILD values.

This way we can make the INSERT faster.

-- Copy the FormSectionInstance
DECLARE @FormSectionInstanceTable TABLE(OldFormSectionInstanceId INT, NewFormSectionInstanceId INT)

;MERGE INTO [dbo].[FormSectionInstance]
		fsi.FormSectionInstanceId [OldFormSectionInstanceId]
		, @NewFormHeaderId [NewFormHeaderId]
		, fsi.FormSectionId
		, fsi.IsClone
		, @UserId [NewCreatedByUserId]
		, GETDATE() NewCreatedDate
		, @UserId [NewUpdatedByUserId]
		, GETDATE() NewUpdatedDate
	FROM [dbo].[FormSectionInstance] fsi
	WHERE fsi.[FormHeaderId] = @FormHeaderId 
) tblSource ON 1=0 -- use always false condition
( [FormHeaderId], FormSectionId, IsClone, CreatedByUserId, CreatedDate, UpdatedByUserId, UpdatedDate)
VALUES( [NewFormHeaderId], FormSectionId, IsClone, NewCreatedByUserId, NewCreatedDate, NewUpdatedByUserId, NewUpdatedDate)
OUTPUT tblSource.[OldFormSectionInstanceId], INSERTED.FormSectionInstanceId
INTO @FormSectionInstanceTable(OldFormSectionInstanceId, NewFormSectionInstanceId);

-- Copy the FormDetail
INSERT INTO [dbo].[FormDetail]
	(FormHeaderId, FormFieldId, FormSectionInstanceId, IsOther, Value, CreatedByUserId, CreatedDate, UpdatedByUserId, UpdatedDate)
	@NewFormHeaderId, FormFieldId, fsit.NewFormSectionInstanceId, IsOther, Value, @UserId, CreatedDate, @UserId, UpdatedDate
FROM [dbo].[FormDetail] fd
INNER JOIN @FormSectionInstanceTable fsit ON fsit.OldFormSectionInstanceId = fd.FormSectionInstanceId
WHERE [FormHeaderId] = @FormHeaderId 

Web.config transform from template and transformation files

This solution is usefull when you want to debug on multiple environments.

Just add ad template file, some transformation config files and then select your desired Solution configuration.

Web config will be changed on the spot.


Also usefull when you want to publish on different environments.


You can setup different web.cofig configurations.

<Target Name="BeforeBuild">
    <TransformXml Source="$(WebFolderName)Web.Template.config" Transform="$(WebFolderName)Web.$(Configuration).config" Destination="$(WebFolderName)Web.config" />