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
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.
- Open the begin solution MvcMusicStore.sln at Source\Ex02- Client Side Custom Validation\Begin.
- Create a new C# class file into Validations folder, and rename it ModelClientPriceRangeValidationRule.[cs|vb].
Open ModelClientPriceRangeValidationRule.[cs|vb]. and add a reference to the System.Web.Mvc namespace:
using System;
FakePre-e53c9d16dd474938927f30f96267a0dd-74badce43b32457db34491dae5c44ad1FakePre-591cc867504444b7bb0bac4de5e2c52f-7c2bb3323c9743fc988526214abf6210FakePre-8cc03eb08d2d4b9d8a0ca29104d3bb38-0611069501714ed88464d397d72a3573using System.Web.Mvc;
Imports System
FakePre-85e8eeecad9347a28198f51ef22edd9b-621c21c4e6e24224ba1de9c20b06f864FakePre-453d425937b04fb88414f9b7d67ecfd5-4028a09a20eb4f55b9b77fc974e45850FakePre-c97efe73b43743d8a87115e016602728-35928700151746279b26a00227f4435fImports System.Web.Mvc
Inherit the ModelClientPriceRangeValidationRule class from ModelClientValidationRule:
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
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)
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)
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
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.
- Open PriceValidationAttribute.[cs|vb] from \MvcMusicStore\Validations.
Make the PriceValidationAttribute class implement the IClientValidatable interface
public class PriceValidationAttribute : ValidationAttribute, IClientValidatable
Public Class PriceValidationAttribute
FakePre-14f804038d534e31bfc27a5ce05e2428-9a9cc0c73d9b4ced849b8cbc6a3335ebFakePre-7b026fb50d8749779a14d99033454eb8-3d88ca2c587c4f419402a83426c31cc3
Make the PriceValidationAttribute override the method GetClientValidationRules
(Code Snippet – ASP.NET MVC 3 Adding validation at client side – Ex2 GetClientValidationRules override - CSharp)
...
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)
...
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
- Create a new JavaScript file at \MvcMusicStore\Scripts and rename it to PriceValidation.js.
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:
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
- Open Create.aspx view from \Views\StoreManager.
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:
…
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
…
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.
- Press F5 to run the Application.
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