Vous êtes sur la page 1sur 21

Kendo UI in ASP.

NET MVC 5
applications
This tutorial shows how to use Telerik UI for ASP.NET MVC in ASP.NET MVC 5 applications.
The tutorial uses Visual Studio 2013 but will work with all Visual Studio versions that support
ASP.NET MVC 5. The tutorial also creates a new ASP.NET MVC 5 application but the steps to
use Kendo UI in exsiting ASP.NET MVC 5 application are the same.
The Kendo UI Visual Studio extensions automate the whole procedure which this
document describes. ## Create a new ASP.NET MVC 5 Application
To create a new ASP.NET MVC 5 Application follow these steps.
1. Open Visual Studio 2013.
2. Press CTRL+SHIFT+N to create a new project.
3. Select the Visual C# node and then Web to show all available web project templates for
C#.
4. Select ASP.NET Web Application and click OK. This will start the New ASP.NET
Project wizard.
5. Select MVC from the available templates and click OK.
6. Press CTRL+F5 to build and run the
application.

Add Telerik UI for ASP.NET MVC to the application
To use Telerik UI for ASP.NET MVC you need to include the required JavaScript and CSS files,
reference the Kendo.Mvc.dll assembly and update the web.config file of the application.
Include the JavaScript and CSS files
Kendo UI requires certain JavaScript and CSS files to be included in the page. There are two
options - either to include a local copy of those files or to use Kendo UI CDN (Content Delivery
Network).
Using local JavaScript and CSS
To copy the Kendo UI JavaScript and CSS files in the Visual Studio Solution of the application
follow these steps.
1. Navigate to the install location of Telerik UI for ASP.NET MVC**. By default it is in
**C:\Program Files (x86)\Telerik.
2. Copy the js directory from the install location and paste it in the Script folder of the
application.
3. Copy the styles directory from the install location and paste it in the Content folder of the
application.
4. Rename the Scripts/js directory to Scripts/kendo.
Rename Content/styles to Content/kendo.

After the Kendo UI JavaScript and CSS files are added in the application you can include them.
1. Open App_Start/BundleConfig.cs to add bundles for Kendo UI.
2. Add a script bundle for Kendo UI.
3. bundles.Add(new ScriptBundle("~/bundles/kendo").Include(
4. "~/Scripts/kendo/kendo.all.min.js",
5. // "~/Scripts/kendo/kendo.timezones.min.js", //
uncomment if using the Scheduler
"~/Scripts/kendo/kendo.aspnetmvc.min.js"));
6. Add a style bundle for Kendo UI.
7. bundles.Add(new StyleBundle("~/Content/kendo/css").Include(
8. "~/Content/kendo/kendo.common-bootstrap.min.css",
"~/Content/kendo/kendo.bootstrap.min.css"));
9. Tell ASP.NET bundles to allow minified files in debug mode.
bundles.IgnoreList.Clear();
10. Open the layout of the application. By default it
is Views/Shared/_Layout.cshtml (or Site.master if using ASPX).
11. Render the Kendo UI style bundle.
o Razor
@Styles.Render("~/Content/kendo/css")
o ASPX
<%: Styles.Render("~/Content/kendo/css") %>
12. Move the jQuery bundle to the head tag of the page. It is at the end of the page by
default.
13. Render the Kendo UI script bundle after jQuery.
o Razor
o @Scripts.Render("~/bundles/jquery")
@Scripts.Render("~/bundles/kendo")
o ASPX
o <%: Scripts.Render("~/bundles/jquery") %>
<%: Scripts.Render("~/bundles/kendo") %>
Using Kendo UI CDN
To include the Kendo UI JavaScript and CSS files from CDN follow these steps. Important! Don"t
forget to replace "kendo ui version" from the code snippets below with the current version of
Kendo UI e.g. "2013.2.918".
1. Open the layout of the application. By default it
is Views/Shared/_Layout.cshtml (or Site.master if using ASPX).
2. Include kendo.common-bootstrap.min.css and kendo.bootstrap.min.css. Add
a link tag within the head tag of the layout.
3. <link rel="stylesheet" href="http://cdn.kendostatic.com/<kendo ui
version>/styles/kendo.common-bootstrap.min.css" />
<link rel="stylesheet" href="http://cdn.kendostatic.com/<kendo ui
version>/styles/kendo.bootstrap.min.css" />
4. Move the jQuery bundle to the head tag of the page. It is at the end of the page by
default.
5. Include kendo.all.min.js and kendo.aspnetmvc.min.js after jQuery.
6. <script src="http://cdn.kendostatic.com/<kendo ui
version>/js/kendo.all.min.js"></script>
<script src="http://cdn.kendostatic.com/<kendo ui
version>/js/kendo.aspnetmvc.min.js"></script>
7. If using Kendo UI Scheduler include kendo.timezones.min.js after kendo.all.min.js
8. <script src="http://cdn.kendostatic.com/<kendo ui
version>/js/kendo.all.min.js"></script>
9. <script src="http://cdn.kendostatic.com/<kendo ui
version>/js/kendo.timezones.min.js"></script>
<script src="http://cdn.kendostatic.com/<kendo ui
version>/js/kendo.aspnetmvc.min.js"></script>
Add reference to Kendo.Mvc.dll
The next step is to add a reference to Kendo.Mvc.dll which is the assembly containing the
Kendo UI server-side wrappers.
1. Right-click the References node in Solution Explorer and click Add Reference.
2. Select the Browse tab of the Add Reference dialog and navigate to the install location of
Telerik UI for ASP.NET MVC.
3. Navigate to wrappers/aspnetmvc/Binaries/MVC5. This directory contains the ASP.NET
MVC 5 version of Telerik UI for ASP.NET MVC.
4. Select Kendo.Mvc.dll and click OK.
Update the web.config
The next step is to let ASP.NET MVC know of the Kendo.Mvc.UI namespace where the server-
side wrappers are. To do this update the web.config file of the web application.
1. Open Views/Web.config (or root Web.config if using ASPX).
2. Locate the namespaces tag.
3. Append an add tag to the namespaces tag.
4. <namespaces>
5. <add namespace="System.Web.Mvc" />
6. <add namespace="System.Web.Mvc.Ajax" />
7. <add namespace="System.Web.Mvc.Html" />
8. <add namespace="System.Web.Routing" />
9. <add namespace="Kendo.Mvc.UI" />
</namespaces>
Use a Kendo UI widget
Finally lets use a Kendo UI widget.
1. Open the Views/Home/Index.cshtml view (or Index.aspx if using ASPX).
2. Add a Kendo UI DatePicker widget.
o Razor
@(Html.Kendo().DatePicker().Name("datepicker"))
o ASPX
<%: Html.Kendo().DatePicker().Name("datepicker") %>
3. Press CTRL+F5 to build and run the application.

Telerik UI for ASP.NET MVC
Fundamentals
Server-side wrappers
Telerik UI for ASP.NET MVC is a set of server-side wrappers. A server-wrapper does the
following.
Allows the developer to configure a Kendo UI widget via C# or VB.NET code - set its
value, data source etc.
Renders the HTML and JavaScript needed to initialize the Kendo UI widget. The widget
options propagate to the client-side via the widget initialization script.

Configuration
Kendo HtmlHelper extension method
The Kendo HtmlHelper exposes all Kendo UI server-wrappers.

Widget options
The widget options are exposed via fluent interface.

To set an option call the corresponding method and pass the required option value.
@(Html.Kendo().NumericTextBox()
.Name("name") // set the name of the NumericTextBox
.Value(10) //set the value
.Spinners(false) // disable the spinners
)
Name
You must set the Name option of a Kendo UI widget. The value will be used as
the id and name HTML attributes (the nameHTML attribute is set only for input widgets e.g.
DatePicker, NumericTextBox, DropDownList etc.). The id HTML attribute is used to initialize the
Kendo UI widget.

Alternatively you can use NumericTextBoxFor. All Kendo UI widgets which accept a value can
be initialized via a [WidgetName]For method e.g. DatePicker -> DatePickerFor. Those methods
set the Name of the widget automatically. Thus @Html.Kendo().NumericTextBoxFor(model
=> model.Age) is the same
as@Html.Kendo().NumericTextBox().Name("Age").Value(Model.Age).
Deferred initialization
The server-side wrapper outputs the Kendo UI widget initialization script right after the widget
HTML markup. This may not be always desired, e.g. if the script files are registered at the bottom
of the page, or when nesting Kendo UI widgets. In order to move initialization statements, you
can use the following approach.
1. Call the Deferred method of the wrapper. This will suppress the immediate script
statement rendering.
2. @(Html.Kendo().NumericTextBox()
3. .Name("age")
4. .Deferred()
)
5. Call the DeferredScripts method. This will output all previously deferred initialization
statements.
@Html.Kendo().DeferredScripts()
The DeferredScripts method accepts a boolean parameter, which determines whether script
elements should be rendered automatically. This is useful if you want to render the deferred
initialization scripts inside existing script element.
<script>
@Html.Kendo().DeferredScripts(false)
</script>
You can render the deferred initialization script of a particular widget via
the DeferredScriptsFor method.
@(Html.Kendo().NumericTextBox()
.Name("age")
.Deferred()
)
<!-- other code -->
@Html.Kendo().DeferredScriptsFor("age")
The DeferredScriptsFor method also can suppress the output of script elements around the
initialization script.
<script>
@Html.Kendo().DeferredScriptsFor("age", false)
</script>
Events
To subscribe to the client-side events exposed by a Kendo UI widget use the Events method.
1. Specify the name of the JavaScript function which will handle the event.
2. @(Html.Kendo().NumericTextBox()
3. .Name("age")
4. .Events(events =>
5. events.Change("age_change") // handle the "change" event
6. .Spin("age_spin") // handle the "spin" event
7. )
)
8. Declare the event handlers.
9. <script>
10. function age_change(e) {
11. // handle the event
12. }
13. function age_spin(e) {
14. // handle the event
15. }
</script>
Client-side object
You can get a reference to the client-side object initialized by the server-side wrapper via
the data jQuery method. Use theName of the widget to form the jQuery selector and obtain the
reference in a document.ready handler. After you get the reference, you can use the widget
client-side API.
@(Html.Kendo().NumericTextBox()
.Name("age")
)
<script>
$(function(){
var numeric = $("#age").data("kendoNumericTextBox");
numeric.value(10);
});
</script>
If you have deferred the initialization of the widget, make sure you get its
instance after calling DeferredScripts orDeferredScriptsFor.
@(Html.Kendo().NumericTextBox()
.Name("age")
.Deferred()
)
@Html.Kendo().DeferredScripts()
<script>
$(function(){
var numeric = $("#age").data("kendoNumericTextBox");
numeric.value(10);
});
</script>
Client Templates
By default every Kendo UI wrapper renders a script elements with an initialization statement. If
the wrapper declaration is placed inside a Kendo UI template, this would lead to nested script
elements which is invalid. The ToClientTemplatemethod instructs the widget wrapper to
escape its own script element, so that it can be nested.
<script id="template" type="text/x-kendo-template">
@(Html.Kendo().NumericTextBox()
.Name("age").ToClientTemplate()
)
</script>
<div id="container"></div>
<script>
$(function () {
var template = kendo.template($("#template").html());
$("#container").append( template ({}) );
})
</script>

Validation
This page describes how to use client-side Validation with Telerik UI for ASP.NET MVC. The
page provides tutorials on how to use the Kendo Validator and the MVC default jQuery
validation. It also contains a list of the common problems while implementing the client-side
validation and information on how to resolve them.
Using the Kendo Validator with DataAnnotation
attributes
The Kendo Validator creates validation rules based on the unobtrusive HTML attributes. Those
unobtrusive attributes are generated by ASP.NET MVC based on the DataAnnotation attributes
applied to the Model properties. Currently, the supported DataAnnotation attributes are:
Required
StringLength
Range
RegularExpression
The Kendo Validator also creates rules for the unobtrusive attributes that are generated implicitly
by MVC for numbers and dates.
To use the Kendo Validator with the DataAnnotation attributes you should follow these steps.
1. Create a class and add the needed DataAnnotation attributes.
2. public class OrderViewModel
3. {
4. [HiddenInput(DisplayValue = false)]
5. public int OrderID { get; set; }
6.
7. [Required]
8. [Display(Name = "Customer")]
9. public string CustomerID { get; set; }
10.
11. [StringLength(15)]
12. [Display(Name = "Ship Country")]
13. public string ShipCountry { get; set; }
14.
15. [Range(1, int.MaxValue, ErrorMessage = "Freight should be
greater than 1")]
16. [DataType(DataType.Currency)]
17. public decimal? Freight { get; set; }
18.
19. [Display(Name = "Order Date")]
20. public DateTime? OrderDate { get; set; }
}
21. Pass an instance of the model to the view.
22. public ActionResult Create()
23. {
24. ViewData["customers"] = GetCustomers();
25. return View(new OrderViewModel());
}
26. Create the editors in the view based on the model and initialize the Kendo Validator on
the form.
27. @model OrderViewModel
28.
29. @using (Html.BeginForm()) {
30. <fieldset>
31. <legend>Order</legend>
32.
33. @Html.HiddenFor(model => model.OrderID)
34.
35. <div class="editor-label">
36. @Html.LabelFor(model => model.CustomerID)
37. </div>
38. <div class="editor-field">
39. @(
40. Html.Kendo().DropDownListFor(model =>
model.CustomerID)
41. .OptionLabel("Select Customer")
42. .BindTo(ViewData["customers"] as SelectList)
43. )
44. @Html.ValidationMessageFor(model => model.CustomerID)
45. </div>
46.
47. <div class="editor-label">
48. @Html.LabelFor(model => model.ShipCountry)
49. </div>
50. <div class="editor-field">
51. @Html.EditorFor(model => model.ShipCountry)
52. @Html.ValidationMessageFor(model => model.ShipCountry)
53. </div>
54.
55. <div class="editor-label">
56. @Html.LabelFor(model => model.Freight)
57. </div>
58. <div class="editor-field">
59. @Html.Kendo().NumericTextBoxFor(model =>
model.Freight)
60. @Html.ValidationMessageFor(model => model.Freight)
61. </div>
62.
63. <div class="editor-label">
64. @Html.LabelFor(model => model.OrderDate)
65. </div>
66. <div class="editor-field">
67. @Html.Kendo().DatePickerFor(model => model.OrderDate)
68. @Html.ValidationMessageFor(model => model.OrderDate)
69. </div>
70.
71. <p>
72. <input type="submit" value="Save" />
73. </p>
74. </fieldset>
75. }
76.
77. <script>
78. $(function () {
79. $("form").kendoValidator();
80. });
</script>
Implementing a custom attribute
If there is a scenario where the built-in rules cannot be used, you can implement a custom
validation attribute. To demonstrate this scenario lets include a ShippedDate field to our model
and implement a GreaterDateAttribute attribute that will check whether the selected ShippedDate
value is greater than the selected OrderDate.
1. Create a class that inherits
from ValidationAttribute and IClientValidatable and implement
the IsValidand GetClientValidationRules methods.
2. [AttributeUsage(AttributeTargets.Property, AllowMultiple = false,
Inherited = true)]
3. public class GreaterDateAttribute : ValidationAttribute,
IClientValidatable
4. {
5. public string EarlierDateField { get; set; }
6.
7. protected override ValidationResult IsValid(object value,
ValidationContext validationContext)
8. {
9. DateTime? date = value != null ? (DateTime?)value : null;
10. var earlierDateValue =
validationContext.ObjectType.GetProperty(EarlierDateField)
11. .GetValue(validationContext.ObjectInstance, null);
12. DateTime? earlierDate = earlierDateValue != null ?
(DateTime?)earlierDateValue : null;
13.
14. if (date.HasValue && earlierDate.HasValue && date <=
earlierDate)
15. {
16. return new ValidationResult(ErrorMessage);
17. }
18.
19. return ValidationResult.Success;
20. }
21.
22. public IEnumerable<ModelClientValidationRule>
GetClientValidationRules(ModelMetadata metadata, ControllerContext
context)
23. {
24. var rule = new ModelClientValidationRule
25. {
26. ErrorMessage = ErrorMessage,
27. ValidationType = "greaterdate"
28. };
29.
30. rule.ValidationParameters["earlierdate"] =
EarlierDateField;
31.
32. yield return rule;
33. }
}
34. Decorate the ShippedDate property with the newly implemented attribute.
35. public class OrderViewModel
36. {
37. //omitted for brevity
38.
39. [Display(Name = "Order Date")]
40. [DataType(DataType.Date)]
41. public DateTime? OrderDate { get; set; }
42.
43. [GreaterDate(EarlierDateField = "OrderDate", ErrorMessage =
"Shipped date should be after Order date")]
44. [DataType(DataType.Date)]
45. public DateTime? ShippedDate { get; set; }
}
46. Implement a kendo validator rule that will handle all inputs with the data-val-
greaterdate attribute.
47. @model OrderViewModel
48.
49. @using (Html.BeginForm()) {
50. <fieldset>
51. <legend>Order</legend>
52.
53. @Html.HiddenFor(model => model.OrderID)
54.
55. <div class="editor-label">
56. @Html.LabelFor(model => model.OrderDate)
57. </div>
58. <div class="editor-field">
59. @Html.DatePickerFor(model => model.OrderDate)
60. @Html.ValidationMessageFor(model => model.OrderDate)
61. </div>
62.
63. <div class="editor-label">
64. @Html.LabelFor(model => model.ShippedDate)
65. </div>
66. <div class="editor-field">
67. @Html.DatePickerFor(model => model.ShippedDate)
68. @Html.ValidationMessageFor(model => model.ShippedDate)
69. </div>
70.
71. <p>
72. <input type="submit" value="Save" />
73. </p>
74. </fieldset>
75. }
76.
77. <script>
78. $(function () {
79. $("form").kendoValidator({
80. rules: {
81. greaterdate: function (input) {
82. if (input.is("[data-val-greaterdate]") &&
input.val() != "") {
83. var date = kendo.parseDate(input.val()),
84. earlierDate =
kendo.parseDate($("[name='" + input.attr("data-val-greaterdate-
earlierdate") + "']").val());
85. return !date || !earlierDate ||
earlierDate.getTime() < date.getTime();
86. }
87.
88. return true;
89. }
90. },
91. messages: {
92. greaterdate: function (input) {
93. return input.attr("data-val-greaterdate");
94. }
95. }
96. });
97. });
</script>
Using a custom attribute in an editable widget
Editable widgets, like the Grid or the ListView, initialize the validator internally and so to specify
custom rules you should extend the Kendo Validator built-in validation rules. This approach can
also be used to define rules after the Kendo scripts have been included and to use them in all
views.
<script>
(function ($, kendo) {
$.extend(true, kendo.ui.validator, {
rules: {
greaterdate: function (input) {
if (input.is("[data-val-greaterdate]") && input.val()
!= "") {
var date = kendo.parseDate(input.val()),
earlierDate = kendo.parseDate($("[name='" +
input.attr("data-val-greaterdate-earlierdate") + "']").val());
return !date || !earlierDate ||
earlierDate.getTime() < date.getTime();
}

return true;
}
},
messages: {
greaterdate: function (input) {
return input.attr("data-val-greaterdate");
}
}
});
})(jQuery, kendo);
</script>

@(
Html.Kendo().Grid<OrderViewModel>()
.Name("grid")
.Columns(columns =>
{
columns.Bound(o => o.OrderDate);
columns.Bound(o => o.ShippedDate);
columns.Command(command => command.Edit());
})
.DataSource(source => source
.Ajax()
.Model(model => model.Id(o => o.OrderID))
.Read("Read", "Orders")
.Update("Update", "Orders")
)
)
Using the jQuery Validation
To use the jQuery validation with the Kendo widgets you should follow these steps.
1. Add the latest version of the jquery.validate and jquery.validate.unobtrusive scripts to the
project.
2. Include them in the view in which you want to validate the user input or in the layout.
3. Override the default ignore setting after including the scripts to enable validation of
hidden elements. For instance, widgets like DropDownList and NumericTextBox have a
hidden input to keep the value.
4. <script
src="@Url.Content("~/Scripts/jquery.validate.min.js")"></script>
5. <script
src="@Url.Content("~/Scripts/jquery.validate.unobtrusive.min.js")"></
script>
6. <script type="text/javascript">
7. $.validator.setDefaults({
8. ignore: ""
9. });
</script>
10. Define the model and create the editors the same way as in the Using the Kendo
Validator with DataAnnotation attributes topic.
Changing the widgets style when there is a
validation error.
The validation error classes are applied to the inputs that are validated so the style will not be
visible for widgets that use a hidden input to keep the value. In order to show an error style, the
class can be copied to the visible wrapper using the approach demonstrated in the kendo-input-
widgets-validation sample project in our GitHub repository on this page.
Troubleshooting
The validation tooltip is shown in the widget wrapper when using the
Kendo Validator
By default the tooltip is added right after the input so if the input is used to for a widget, the tooltip
will be added inside the wrapper element and will not be displayed correctly. In this case, you
should customize the tooltip position by using one of the following approaches.
Use the ValidationMessage or ValidationMessageFor helpers for the property.
@Html.Kendo().NumericTextBoxFor(model => model.UnitPrice)
@Html.ValidationMessageFor(model => model.UnitPrice)
Use the approach demonstrated here to add a placeholder.
The widgets are hidden after a postback when using the jQuery
Validation
If the client-side validation does not prevent the form to be posted and the server-side validation
fails for a property, theinput-validation-error class will be added to the input. For styling
purposes, custom classes assigned to the inputs are copied to the wrapper element and because
all elements with the error class will be hidden on validation, the widget will be hidden. In order to
avoid this behavior you should either implement a client-side validation for the rule that has
caused the validation to fail on the server or remove the class from the wrapper elements after
the widgets initialization.
@using (Html.BeginForm()) {
//omitted for brevity
}

<script type="text/javascript">
$(function () {
$(".k-widget").removeClass("input-validation-error");
});
</script>
Globalized dates and numbers are not recognized as valid when using
the Kendo Validator.
The Kendo Validator uses the current Kendo culture to determine if a value is in a valid format. In
order for the values to be recognized as valid, you should use the same culture on the client and
on the server as described in the Globalizationdocumentation.
Globalized dates and numbers are not recognized as valid when using
the jQuery validation.
The jQuery validation does not support globalized dates and numbers. In order for the values to
be recognized as valid when using a not default culture, you should override the validator date
and number methods.
jQuery.extend(jQuery.validator.methods, {
date: function (value, element) {
return this.optional(element) || kendo.parseDate(value) != null;
},
number: function (value, element) {
return this.optional(element) || kendo.parseFloat(value) != null;
}
});

Vous aimerez peut-être aussi