Home >

Getting Started with Telerik Extensions for ASP.NET MVC

28. August 2009

I initially decided to try out the Telerik Extensions for ASP.NET MVC because I was looking to create a EditorTemplate (ASP.NET MVC v2 Preview 1 feature) for Date and I wanted to use the jQuery UI DatePicker wrapper that Telerik provides.

Not only was I pleased with the Fluent Interface that they used to wrap the jQuery UI Plugins, but I was also surprised and impressed by their Script and Style management system.

Web.config Changes

The first thing you’ll need to do is to make a couple of web.config changes to the Handler sections before starting to use the Telerik Extensions.

<?xml version="1.0"?>
<configuration>
    <system.web>
        <httpHandlers>
            <add verb="GET,HEAD" path="asset.axd" validate="false" type="Telerik.Web.Mvc.WebAssetHttpHandler, Telerik.Web.Mvc"/>
        </httpHandlers>
    </system.web>
    <system.webServer>
        <handlers>
            <remove name="AssetHandler"/>
            <add name="AssetHandler" preCondition="integratedMode" verb="GET,HEAD" path="asset.axd" type="Telerik.Web.Mvc.WebAssetHttpHandler, Telerik.Web.Mvc"/>      
        </handlers>
    </system.webServer>    
</configuration>

Including jQuery & jQuery UI

Before you can start using the jQuery UI wrappers, you’ll need to first include jQuery & jQuery UI into your project. For my simple project, I just did the following…

Site.Master MasterPage

<%@ Import Namespace="Telerik.Web.Mvc.UI"%>
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
    <% Html.Telerik().StyleSheetRegistrar()
        .DefaultGroup(group => group
            .Add("Site.css")
            .Add("jquery-ui-1.7.2.custom.css").Render(); %>              
</head>        
<body>
    <!-- Misc -->
    <%  Html.Telerik().ScriptRegistrar().Render(); %>            
</body>
</html>

The code will automatically insert jQuery by default and if you happened to use one of the Telerik jQuery UI Extensions then it will insert jQuery UI as well.

Note: It is important to know that the ScriptRegistrar must be directly before the end body tag in order to work.

Date EditorTemplate

Before creating the EditorTemplate, I annotated the DateOfBirth property with DataType.Date so the Template framework has additional metadata to work with.

Employee.cs View Model

using System;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using NestedTemplates.Helpers;

namespace TelerikExtensions.Models
{
    public class Employee
    {
        [UIHint("Hidden")]
        public long Id { get; set; }

        [Required(ErrorMessage = "First Name Required")]
        [StringLength(50, ErrorMessage = "Must be less than 50 characters")]
        [DisplayName("First Name")]
        public string FirstName { get; set; }

        [Required(ErrorMessage = "Last Name Required")]
        [StringLength(50, ErrorMessage = "Must be less than 50 characters")]
        [DisplayName("Last Name")]
        public string LastName { get; set; }

        [Required(ErrorMessage = "Social Security Required")]
        [StringLength(50, ErrorMessage = "Must be less than 50 characters")]
        [RegularExpression(@"^[0-9]{3}-?[0-9]{2}-?[0-9]{4}$", ErrorMessage = "Invalid Social Security Number Format")]
        [DisplayName("Social Security Number")]
        public string SocialSecurity { get; set; }

        [Required(ErrorMessage = "Date of Birth Required")]
        [StringLength(50, ErrorMessage = "Must be less than 50 characters")]
        [DataType(DataType.Date, ErrorMessage = "Date of Birth must be expressed as a date")]
        [DisplayName("Date of Birth")]
        public DateTime DateOfBirth { get; set; }
    }
}

Then I went ahead and made a EditorTemplate called Date.ascx (which matches the DataType.Date name) using the Telerik DatePicker Extension

Date.ascx EditorTemplate

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl" %>

<%@ Import Namespace="Mvc.UI.jQuery"%>

<% Html.jQuery().DatePicker()
    .Name("dateField")
    .Value((DateTime) Model).Render(); %>

Since we annotated the DateOfBirth property in our View Model with DataType.Date there isn't anything really special you need to do for ASP.NET MVC v2 Preview 1 to use it other than calling Html.EditorFor(m => m.DateOfBirth). Behind the scenes it matches up the types and uses the above EditorTemplate.

Edit.aspx View

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<TelerikExtensions.Models.Employee>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    Edit
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h2>Edit</h2>
    
    <%= Html.ValidationSummary("Edit was unsuccessful. Please correct the errors and try again.") %>
    
    <% using (Html.BeginForm()) {%>
        <p>
            <%= Html.LabelFor(m => m.FirstName) %>
            <%= Html.EditorFor(m => m.FirstName) %>
            <%= Html.ValidationMessage("FirstName", "*") %>
        </p>
        <p>
            <%= Html.LabelFor(m => m.LastName) %>
            <%= Html.EditorFor(m => m.LastName) %>
            <%= Html.ValidationMessage("LastName", "*") %>
        </p>
        <p>
            <%= Html.LabelFor(m => m.SocialSecurity) %>
            <%= Html.EditorFor(m => m.SocialSecurity) %>
            <%= Html.ValidationMessage("SocialSecurity", "*") %>
        </p>
        <p>
            <%= Html.LabelFor(m => m.DateOfBirth) %>
            <%= Html.EditorFor(m => m.DateOfBirth) %>
            <%= Html.ValidationMessage("DateOfBirth", "*") %>
        </p>   
        <p>
            <input type="submit" value="Save" />
        </p>
    <% } %>
    
    <div>
        <%=Html.ActionLink("Back to List", "Index") %>
    </div>
</asp:Content>

jQuery UI Goodness

The result is what you would expect if you had manually wired up the jQuery UI DatePicker into your project, but this time with strong type checking and a nice Fluent Interface.

jQueryUiDatePickerGoodness

Compress, Combine, & Cache

Now, what I thought was even cooler than that was that I could specify to combine, compress, and cache the scripts & styles… how cool is that!?!

<%@ Import Namespace="Telerik.Web.Mvc.UI"%>
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
    <% Html.Telerik().StyleSheetRegistrar()
        .DefaultGroup(group => group
            .Add("Site.css")
            .Add("jquery-ui-1.7.2.custom.css")
            .Combined(true)
            .Compress(true)).Render(); %>              
</head>        
<body>
    <!-- Misc -->
    <%  Html.Telerik().ScriptRegistrar().
            DefaultGroup(group => group
                .Combined(true)
                .Compress(true)
                .CacheDurationInDays(365)).Render(); %>            
</body>
</html>

Instead of compressing, combining, & caching everything together you could also choose to separate like scripts in groups like the following…

<% Html.Telerik().ScriptRegistrar().Scripts(script => script
        .AddGroup("Validation", group => group
            .Add("~/Content/Scripts/jquery.validate.min.js")
            .Add("~/Content/Scripts/xVal.jquery.validate.js")
            .Combined(true)
            .Compress(true)
            .CacheDurationInDays(365))
        .AddGroup("TableSorter", group => group
            .Add("~/Content/Scripts/metadata.js")
            .Add("~/Content/Scripts/jquery.tablesorter.js")
            .Add("~/Content/Scripts/jquery.tablesorter.pager.js")
            .Combined(true)
            .Compress(true)
            .CacheDurationInDays(365))                
    ).Render(); %>   

Gotchas

The next step was to integrate the test code into my main project. I had some initial issues resolving the jQuery & jQuery UI scripts. Initially, the Telerik Extensions look in the standard Scripts folder that the ASP.NET MVC project creates. However, I moved my Scripts folder under the Content folder alongside the Styles folder. Thanks to Todd Anglin, Kazi Manzur Rashid, & some research into their codebase I was able to put the following two lines of code in my Global.asax to override the default folder for the scripts.

using System.Web.Mvc;
using System.Web.Routing;
using Telerik.Web.Mvc;
using Telerik.Web.Mvc.UI;

namespace TelerikExtensions
{
    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            RegisterRoutes(RouteTable.Routes);

            ScriptRegistrar.FrameworkScriptPath = "~/Content/Scripts";
            WebAssetDefaultSettings.ScriptFilesPath = "~/Content/Scripts";
        }
    }
}

Summary

All in all, this is a very cool open source library that I think would be beneficial for most any ASP.NET MVC application.

Feel free to download the sample project I put together using most of the above code.


Comments

8/29/2009 2:28:01 AM #
I'm not at all a fan of this. This is a solution to a problem that does not exist. Its a bastardization of technologies (jQuery and javascript) that works fine as-is for the sole purpose of trying to stay relevant in an evolving world.

jQuery is inherently fluent (the vast majority of plugins (including all the built-in ones)) return the set of object being manipulated. You gain strong-typing, which some will argue is a benefit, and some will say is a drawback (those of us who love python or ruby for example). Either way its pretty trivial.

The reality is that server-side programming of javascript code is completely unnecessary and ass backwards when javascript is (not surprisingly) a better language for javascript than C# is. It adds meaningless complexity by adding a valueless layer that simply makes it harder to manage. In addition, it narrows your knowledge to a specific edge implementation.

The compression/merge thing is neat, but trivial to implement for free (maybe 30 minutes worth of work). (We use the free YUICompressor for .NET for compression and have merged as a build step as well as on-the-fly). I mean really, merging, streaming and caching the contents of X files together is suddenly something we need a paid library for?
9/2/2009 10:59:05 PM #
Getting Started with Telerik Extensions for ASP.NET MVC

You've been kicked (a good thing) - Trackback from DotNetKicks.com
9/8/2009 10:51:42 PM #
Pingback from webmastercrap.com

Webmaster Crap  » Blog Archive   » Web Dev .NET | Getting Started with Telerik Extensions for ASP.NET MVC
9/11/2009 9:48:54 PM #
Karl,

I agree the framework is probably a bit too much for only getting the compression/merge stuff, but from what their website says Telerik plans to expand what is offered in their library. It isn't meant to soley be a wrapper around jQuery UI although it does kinda seem like that now.

Saying all of that, I did notice some strange gotchas as I integrated it into my main project. It didn't play well with standard ways to inject jQuery block in my code. It wanted me to use their mechanism of registering through their framework, which I don't really like. I do like the YUICompressor for .NET and have integrated it into our msbuild process in the past. I think it is the way to go ;)

Sorry, took me soo long to get back to your comment. I didn't have the BlogEngine.Net email comment notification turned on when you left your comment.

I appreciate your feedback and am honored you took to the time visit my blog.
9/14/2009 5:21:39 PM #
I havent any word to appreciate this post.....Really i am impressed from this post....the person who create this post it was a great human..thanks for shared this with us.
9/14/2009 8:11:25 PM #
I havent any word to appreciate this post.....Really i am impressed from this post....the person who create this post it was a great human..thanks for shared this with us.
10/2/2009 6:33:15 PM #
#.think.in infoDose #42 (3rd September - 10th September)

#.think.in infoDose #42 (3rd September - 10th September)

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading



Olark Livehelp