Exercise 2: Adding Validation at Client Side

In the previous exercise you added a custom range validation method for the album price in the server side.

In this exercise, you will learn how to add validation at client side. For that purpose you will implement MVC3 IClientValidatable Interface at client side. This will improve the user experience, as the error message will appear before saving the album.

Task 1 – Creating a ModelClientValidationRule for price ranges

Note:
ModelClientValidationRule is an ASP.NET MVC class that provides a base class container for client validation rules sent to the browser. In order to achieve that, any generic rule should inherit from this class.

In this task, you will create a new ModelClientValidationRule called ModelClientPriceRangeValidationRule. This derived class will provide a custom validation rule.

  1. Open the begin solution MvcMusicStore.sln at Source\Ex02- Client Side Custom Validation\Begin.
  2. Create a new C# class file into Validations folder, and rename it ModelClientPriceRangeValidationRule.[cs|vb].
  3. Open ModelClientPriceRangeValidationRule.[cs|vb]. and add a reference to the System.Web.Mvc namespace:

    C#

    using System;
    FakePre-e53c9d16dd474938927f30f96267a0dd-74badce43b32457db34491dae5c44ad1FakePre-591cc867504444b7bb0bac4de5e2c52f-7c2bb3323c9743fc988526214abf6210FakePre-8cc03eb08d2d4b9d8a0ca29104d3bb38-0611069501714ed88464d397d72a3573using System.Web.Mvc;

    Visual Basic

    Imports System
    FakePre-85e8eeecad9347a28198f51ef22edd9b-621c21c4e6e24224ba1de9c20b06f864FakePre-453d425937b04fb88414f9b7d67ecfd5-4028a09a20eb4f55b9b77fc974e45850FakePre-c97efe73b43743d8a87115e016602728-35928700151746279b26a00227f4435fImports System.Web.Mvc

  4. Inherit the ModelClientPriceRangeValidationRule class from ModelClientValidationRule:

    C#

    using System;
    FakePre-7d09af9bca724f99858f71bdae515ba0-293b4ab895104165864d69831631c9f7FakePre-9740913e5b494e7eadb21ea92e242d31-f480bf581cfa4678b31c599e99e8cb75FakePre-ee6ff8192ece4b2ab8561b14aad04c4b-15dde5430545413bae4aad11d5a58324FakePre-f139a6d4f6624324a2500ee0fe12ae83-6b42808206d2451ba8519218af077b48FakePre-fc32338fcf2f463aa35f88a6eacbeaa5-5d3cd0eb224449eda30a11c3390f6c54FakePre-c183dae1d28247b78e9916445cf889cf-0ae9abe65b534c1fa1113564999231feFakePre-9d5ec9d50d6049d1b2755035cdf81221-512b8a6e254c4ed79c389db0189ad584FakePre-85adb17ceec74cf6b0f99b809eaabc2a-ab7dfa5e8b9f441bad83058ae1057224FakePre-1468dc6587964ddcb8ee21b757a9c916-5f14f288c4224c26af871b05fb2bcd4cFakePre-2360ea797934416d8a973559ff14de2f-9c96b0ae38ab4d4fadbf8a7c125f810aFakePre-41d50d0552bc4f29985c47df4a87b7f3-0cc66e6f5df64b879f42c0c013acd7f6

    Visual Basic

    Imports System
    FakePre-d109e299577d4cdca7e291ed1ffae355-bd52b0635e8a41ee998cdb2c05404d8bFakePre-088ca23e186041ad894f57c00ec88f4c-7f48c73e6ea74b1796696278d89bee5eFakePre-eaa71d94b32e4654a970fa277856f1c4-814a9a48c494454c992b2a4c78803d1eFakePre-7657e8ee6753475babfa4ca7950bcdc9-9f1238788237487997b5e57a54a3a9ebFakePre-f8e90c1477b549078b11c97068ba401b-e17ddb6bd55142b2b3c93656271510d1FakePre-6df88689daee48f4838e6d0630bee302-150d1e45dbda4b6cb906d16b06154b58FakePre-958d66769a094d3fb7e11137d17f924b-82f7b22f63c34ed1a132cb98184136f6FakePre-42de0ba22f9446599a39bdb3ece5f68f-abff4dfb630c49f28d3a8f12ef2cea25FakePre-78ef3e462aa14527aea329ee867a4319-f6edcea024804014ad21b53fca063471

Create a new class constructor for ModelClientPriceRangeValidationRule to set the base class properties with your custom parameters:

(Code Snippet – ASP.NET MVC 3 Adding validation at client side – Ex2 Constructor - CSharp)

C#

using System.Web.Mvc;
FakePre-f8d76cf8356042fab0839b3b978ed8d2-0592666692b5427c8ead07aa225d19b9FakePre-a89070a8f381417798779e27226957a9-5511b4398581477a98df919451288735FakePre-753fa9a797cb4513b4a98cf1a9eaeb7f-496fb0e137d04b7f8362fe8690ddb62aFakePre-5846435d22e04ed89c5444d7fb4a9fb0-ef9486ddcb15403db06a4c8a5e67582aFakePre-26df502c28fb42c09ed28de9829a7ac5-4513fb73fd6947ef9f003a7d4acaf7a7 public ModelClientPriceRangeValidationRule(string errorMessage, decimal minPrice, decimal maxPrice) { ErrorMessage = errorMessage; ValidationType = "priceOnRange"; ValidationParameters.Add("minPrice", minPrice); ValidationParameters.Add("maxPrice", maxPrice); }FakePre-7ec23c9ce2fc48be9459b09a23437aa2-0ac4ea8a768049b3b9a96229e8f76638FakePre-e5af44f982a94a0b834d92c075bb1455-466f9289d3dc47259dd20880eee525faFakePre-c0ed24582f7b49f49df675d26babb573-8624936740e0441489914d8eb3a19d45FakePre-75e4676a3c5a4a6b8318e1f8bba03221-08af3646eaca490b855ae34dc44b0f8b

(Code Snippet – ASP.NET MVC 3 Adding validation at client side – Ex2 Constructor - VB)

Visual Basic

Imports System.Web.Mvc
FakePre-4d0ecfa19bc342bc969221418c832e90-0a7ef2ad55b549daa38c57459f7fb631FakePre-0479ef2638c24a4b9b8d424ef936af43-74b47243c1cb4c8cb772f6c634c33ae4FakePre-d42be265033c41b0a14be4977cf2b23a-03d4609148a1464e8d1bf1e2fa146ac6 Public Sub New(ByVal errorMessage As String, ByVal minPrice As Decimal, ByVal maxPrice As Decimal) ErrorMessage = errorMessage ValidationType = "priceOnRange" ValidationParameters.Add("minPrice", minPrice) ValidationParameters.Add("maxPrice", maxPrice) End SubFakePre-1634a08df9484254b29498043d1debd9-88adb4ac2abd486ca941631be4144504FakePre-eea7627ac59d4c88809c619ed2e3dffb-33f6b4e7f7a14d54a4f22bff1176caddFakePre-6057699ca4f34b53a5b6aa5c115010d4-d8100783c4474d3ca1bff034935d8b01

Note:
In the following steps you will see how this piece is connected with the general solution.

Task 2 – Adding attribute validation at client side

In this task, you will add a method to PriceValidationAttribute class to perform validation at client-side.

  1. Open PriceValidationAttribute.[cs|vb] from \MvcMusicStore\Validations.
  2. Make the PriceValidationAttribute class implement the IClientValidatable interface

    C#

        public class PriceValidationAttribute : ValidationAttribute, IClientValidatable

    Visual Basic

    Public Class PriceValidationAttribute
    FakePre-14f804038d534e31bfc27a5ce05e2428-9a9cc0c73d9b4ced849b8cbc6a3335ebFakePre-7b026fb50d8749779a14d99033454eb8-3d88ca2c587c4f419402a83426c31cc3

  3. Make the PriceValidationAttribute override the method GetClientValidationRules

    (Code Snippet – ASP.NET MVC 3 Adding validation at client side – Ex2 GetClientValidationRules override - CSharp)

    C#

    ...
    FakePre-be9c616ffc6b43edbeaae23b47eb7799-8c15ca9dd89c4bfc8cd3698d83bbe246FakePre-a9a11ae67eab42888606d4fad11e7580-18ddd5629e0349b2bd1a5f352171ccbaFakePre-d2b4ef3632274318a6482d6fc721cbf2-86d2f32d12c44b8e873fe9ef13c96fe3FakePre-81fb85e08c644123a6ea817a9cb2675e-45f41da5ef824abf845dc918081fc87bFakePre-c46abca5165746d48694a00c83b3756a-7a672b2d05db44e49480ae92ade8d16bFakePre-11a6129babb0416da1bea18726e5f4ce-c7ee3f37ae20478aa1b18a714e9e68a2FakePre-f728602e83104c6eba3d45154aecd86e-7f5df839ae214616ab9868ace655b82dFakePre-00fad56c14c446d2a94199852a015fed-cd2721edb8f443b7b84e92d1c82c31b8 // Client-Side validation public IEnumerable<ModelClientValidationRule> GetClientValidationRules(ModelMetadata metadata, ControllerContext context) { var rule = new ModelClientPriceRangeValidationRule("The price is not in a valid range.", this.minPrice, this.maxPrice); yield return rule; }FakePre-f60260becf0143bdae9b60ed9e7aa51e-f0af02711afe42a78fe48fe6ffc86c3fFakePre-4de8b10eb33b4dc19df3e228a8910bde-65dd21a36a40451284affd3da9e3b013

    (Code Snippet – ASP.NET MVC 3 Adding validation at client side – Ex2 GetClientValidationRules override - VB)

    Visual Basic

    ... 
    FakePre-de9c67224969417ea69d81cade44cefe-6f7826a110f649688048324c25eaec13FakePre-29dfec4854bb443bb9686dd411eb3eaa-4a9a8aae4f344f6098621eccda381e30FakePre-70d016d5b1e041e897231f8eadc1eab5-cbcefc5276624edd9e1ea6b61f608725FakePre-a30a3a98679643bbab6f2c0a1075f21d-d1477b2a3c8240c79e5a3435a96a81bcFakePre-fb3aa9eb77f141fdb68bad0a4c69c759-b978211fef194c64aceae82dcad2b3a3FakePre-2b93acd71d914fd098938c513c98b2db-7a8546e97a464b5e9c3e1cd143f6122aFakePre-811fd7bd9a62465e8c4471cacee7f477-1e152e67b2eb496095ebe2a03b59867bFakePre-ed58300116594cdda1922509439278b6-6de378d32e7942f4ab139d4e0f5e3bf3FakePre-d4e6a150433a4607bd5c117bd66b78bf-843ec7cbb23a444498b7b9c2be4641d9FakePre-3e869f521c7c4046a235cd0733307553-36943ace2ee64a8084c02f197e1c1b0e 'Client-Side validation Public Function GetClientValidationRules(ByVal metadata As ModelMetadata, ByVal context As ControllerContext ) As IEnumerable(Of ModelClientValidationRule) Implements System.Web.Mvc.IClientValidatable.GetClientValidationRules Dim result = New List(Of ModelClientValidationRule) Dim rule = New ModelClientPriceRangeValidationRule("The price is not in a valid range.", Me.minPrice, Me.maxPrice) result.Add(rule) Return result End FunctionFakePre-405c4e2085ea47aaac0b08059ca6e859-c408a8cb7e6044bc8a6fe918c3bbbdceFakePre-b14d85cd4f844ab3bd872c70c13ca8bb-62fb8d5fc17e4fb091e3277e04a51bd9

Task 3 – Adding a JavaScript Function to Perform Client-Side Validation

  1. Create a new JavaScript file at \MvcMusicStore\Scripts and rename it to PriceValidation.js.
  2. Open PriceValidation.js and insert the following client side code that will validate the price range. You will note that it has the same logic as the IsValid method of PriceValidationAttribute class created in the previous exercise:

    JavaScript

    Sys.Mvc.ValidatorRegistry.validators["priceOnRange"] = function(rule) { var minPrice = rule.ValidationParameters.minPrice; var maxPrice = rule.ValidationParameters.maxPrice; var message = rule.ErrorMessage; return function (value, context) { if (value > maxPrice || value < minPrice) { return false; } return true; }; };

Task 4 – Modifying the Create View to Execute Client-Side Validation

  1. Open Create.aspx view from \Views\StoreManager.
  2. Add references to the following three JavaScript files that will take care of Ajax features, MVC validation and the custom price validation. Next, enable HTML client validation:

    HTML(C#)

    FakePre-fb5133ccd6c746e4b504b65dcdb9b750-abebd6e51f994db489b9de611c845b95FakePre-8918d14e33084f02b09d415186c8b960-2c152a7788894aa08be7877589d26643<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script> <script src="/Scripts/MicrosoftMvcValidation.js" type="text/javascript"></script> <script src="/Scripts/PriceValidation.js" type="text/javascript"></script> <% Html.EnableClientValidation(); %>FakePre-355de37a1eb3414180f43592249e5d4b-876ef672f2fb4380a9e574883a8b7577FakePre-0483bc16f0f94019be474789f0830483-4e68750dc4774f7faf917498652f753b

    HTML(Visual Basic)

    FakePre-98412d9a5bb149678a89edaf9c313381-456e3978ac01464b893d41ce1b89be34FakePre-d574d91bb8974c3f94abe01466814d94-7befc6ab82ca42069fcee307c3bf928f<script src="/Scripts/MicrosoftAjax.js" type="text/javascript"></script> <script src="/Scripts/MicrosoftMvcValidation.js" type="text/javascript"></script> <script src="/Scripts/PriceValidation.js" type="text/javascript"></script> <% Html.EnableClientValidation() %>FakePre-45da0f743a6a42bf9dd6b34b241ea170-1fa82fd13e064096b72aad1d5e33c0abFakePre-4d65de69314642caa6bd617dfe0e8891-9c4e0db011b14bf78ae45b8376cd8f25

Task 5 – Running the Application

In this task, you will test that the StoreManager create view template performs a range validation at client side when the user enters an album price.

  1. Press F5 to run the Application.
  2. The project starts in the Home page. Browse /StoreManager/Create and in the Price field enter a value outside of the validation range [0.01, 100]. You will see the following error message:

    Figure 2

    Validating an album price at client side

Next Step

Exercise 3: Using IValidatableObject custom validation