<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://devlicio.us/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Lazy Developer : C#</title><link>http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/C_2300_/default.aspx</link><description>Tags: C#</description><dc:language>en</dc:language><generator>CommunityServer 2008.5 SP1 (Build: 31106.3070)</generator><item><title>Atlas Extenders Crash Course - Part 3 – The Page Integration</title><link>http://devlicio.us/blogs/ziemowit_skowronski/archive/2006/11/21/atlas-extenders-crash-course-part-3-the-page-integration.aspx</link><pubDate>Tue, 21 Nov 2006 12:09:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:715</guid><dc:creator>Jimmy</dc:creator><slash:comments>3</slash:comments><description>&lt;p&gt;Welcome again in the last part of this series. So far we made the extender with bunch of features and then we had migrated to the new ASP.NET AJAX framework. So there only one left to do in order to get fully functional extender. As a current state our course contains the following parts:
&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://devlicio.us/blogs/ziemowit_skowronski/archive/2006/10/04/Atlas-Extender-Crash-Course-_1320_-Part-1_3A00_-Introduction.aspx"&gt;Introduction&lt;/a&gt; – what Atlas Extender is and how to create our own validation extender,
&lt;/li&gt;

&lt;li&gt;&lt;a href="http://devlicio.us/blogs/ziemowit_skowronski/archive/2006/10/10/Atlas-Extender-Crash-Course-_1320_-Part-2_3A00_-Page-Methods.aspx"&gt;Page methods&lt;/a&gt; – how to add AJAX server-side validation,
&lt;/li&gt;

&lt;li&gt;&lt;a href="http://devlicio.us/blogs/ziemowit_skowronski/archive/2006/11/01/Atlas-Extenders-Crash-Course-_2D00_-Part-2.5-_2D00_-Migration.aspx"&gt;Migration&lt;/a&gt; – from Atlas to ASP.NET 2.0 AJAX,
&lt;/li&gt;

&lt;li&gt;Integration with the page – how to integrate extender with the ASP.NET page to perform full form validation.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In order to make the extender usable as a part of the page, we have to put it into validation cycle of the page. What we have to do is to find a way, how to stop form before submitting till all server-side validation requests are not accomplished. Let us first look at normal validation cycle and how our extender fit into that cycle. 
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://devlicio.us/photos/brendan/images/716/original.aspx" target="_blank"&gt;&lt;img src="http://devlicio.us/photos/brendan/images/716/original.aspx" border="0" height="286" width="342"&gt;&lt;/a&gt;&lt;br&gt;&lt;a href="http://devlicio.us/photos/brendan/picture716.aspx" target="_blank"&gt;&lt;br&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;Simplified submit cycle is shown on figure 1. Basically, function WebForm_OnSubmit() is attached the form's onsubmit event. This function is very simple itself and returns true, which allows submit, if validation is successful. Using validation groups makes all things a bit more complicated, but everything is done in scripts that are located in resources, so we will not care about them. In the normal page when all validators perform their validation successful, page is submitted, otherwise error messages are displayed, but when we insert our extender all cycle will be broken (Figure 2). 
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://devlicio.us/photos/brendan/images/717/original.aspx" target="_blank"&gt;&lt;img src="http://devlicio.us/photos/brendan/images/717/425x347.aspx" border="0" height="347" width="425"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;When the extender is set up to perform the server-side validation, the validation method returns false which stops the page from being submitted. That is quite reasonable, as we have to wait for the server-side validation results. The main problem is that we can't perform submit just after the server-side validation ends successfully because there can be more than one extenders and all the server-side validation checks pending and needs to be completed before we will decide if we can allow submit or not. So the best way is to count somehow how many server-side validations started and check this counter after each one is finished (Figure 3).
&lt;/p&gt;

&lt;p&gt;&lt;a href="http://devlicio.us/photos/brendan/images/718/original.aspx" target="_blank"&gt;&lt;img src="http://devlicio.us/photos/brendan/images/718/381x425.aspx" border="0"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;In fact, there are only two changes in the code we have to do. First what we will need is to count all server-side validations. In order to do this, we will add two global variables to store the counters. Then, we have to modify slightly the extender behaviour script and add a few lines into validate() and _onMethodComplete() functions (I've removed rest of function bodies in order to make changes more visible):
&lt;/p&gt;
&lt;textarea name="code" class="BLOCKED SCRIPTnogutter" cols="80" rows="10"&gt;validate : function(sender, args) {
    //...
    //increase counter
    __AtlasValidatorExtendersInvalid ++;
    __AtlasValidatorExtendersInProgress ++;
    //...
  }        
},
_onMethodComplete : function (sender, eventArgs) {
    //...
    __AtlasValidatorExtendersInProgress--;
    if (sender.get_result() == "") 
    {
      //decrease counter if success
      __AtlasValidatorExtendersInvalid--;
      this._setNormal();
    }
    else 
    {
      this._setError(sender.get_result());
    }
    formSubmitMockup();
    //...
  }
},
&lt;/textarea&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;So it's quite simple. You can see two counter variables there __AtlasValidatorExtendersInvalid and __AtlasValidatorExtendersInProgress. First one is the number of the invalid results while second one is the number of validations pending. Other world, when __AtlasValidatorExtendersInProgress equals zero then all validation calls were completed, and when __AtlasValidatorExtendersInvalid equals zero then all validation were successful. So, before we will call the server-side validation method, both counters are increased and later then, when asynchronous call is completed, counters are decreased according to the result. At the end of _onMethodComplete() you can notice I'm calling formSubmitMockup() function.
&lt;/p&gt;

&lt;p&gt;This function is a mock-up function that is used to intercept the form submit event and forces it to wait for validation results. In simple format, that function looks as follow:
&lt;/p&gt;
&lt;textarea name="code" class="BLOCKED SCRIPTnogutter" cols="80" rows="10"&gt; 
formSubmitMockup = function() {
  var originalSubmit = false; 
  if (__AtlasValidatorExtendersInProgress &amp;lt;= 0) {
    originalSubmit = WebForm_OnSubmit();
    if (__AtlasValidatorExtendersInvalid &amp;gt; 0 || !originalSubmit) {
      __AtlasValidatorExtendersInProgress = 0;
      __AtlasValidatorExtendersInvalid = 0;
      return false;
    } else {
      theForm.onsubmit = null;
      theForm.submit();
    }
  } else {
    return false;
  }
}
&lt;/textarea&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;As you can see, there is no magic here. First we are calling an original submit function WebForm_OnSubmit() and its result is remembered for later use. Because this original function will cause validation, so all asynchronous validations will be started and our counters will be set at some value. Then counter is checked and if is greater than zero, false is returned to stop form being submitted. After each of the server-side validations is completed counters are decreased and this mock-up function is called and every time counters are checked and if both are equal zero, the form is submitted.
&lt;/p&gt;

&lt;p&gt;Actually this mock-up function and counters has to be added to the page only once, so can't be included in behaviour script. Instead if that, we will add OnPreRender() event to the extender class. Finally then, all additional code looks as follow:
&lt;/p&gt;
&lt;textarea name="code" class="c#:nogutter" cols="80" rows="10"&gt; 
protected override void OnPreRender(EventArgs e)
{
  base.OnPreRender(e);
  if (!Page.ClientScript.IsStartupScriptRegistered("ValidatorExtender"))
  {
    string script = "var __AtlasValidatorExtendersInProgress = 0;\n" +
                    "var __AtlasValidatorExtendersInvalid = 0;\n" +
                    "\n" +
                    "formSubmitMockup = function() {\n" +
                    "  var originalSubmit = false; \n" +
                    "  if (__AtlasValidatorExtendersInProgress &amp;lt;= 0) {\n" +
                    "    originalSubmit = WebForm_OnSubmit();\n" +
                    "    if (__AtlasValidatorExtendersInvalid &amp;gt; 0 || !originalSubmit) {\n" +
                    "      __AtlasValidatorExtendersInProgress = 0;\n" +
                    "      __AtlasValidatorExtendersInvalid = 0;\n" +
                    "      return false;\n" +
                    "    } else {\n" +
                    "      theForm.onsubmit = null;\n" +
                    "      theForm.submit();\n" +
                    "    }\n" +
                    "  } else {\n" +
                    "    return false;\n" +
                    "  }\n" +
                    "}\n" +
                    "theForm.onsubmit = formSubmitMockup;\n";
    Page.ClientScript.RegisterStartupScript(this.GetType(), "ValidatorExtender", script, true);
  }
}
&lt;/textarea&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Well, looks as we finished that small course, hope you enjoyed it. I hope I explained what I've done and all of this is readable and understandable as well. You can download all sources and binary files from the &lt;a href="http://www.codeplex.com/ajaxset"&gt;project page&lt;/a&gt; I've set up yesterday on the codeplex. As my intention is to create a bit more than one validator, you can expect that this page will grow soon with new extenders. If you will have any questions or comments use blog or codeplex page as prefer.
&lt;/p&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=715" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/AJAX/default.aspx">AJAX</category><category domain="http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/Extender+Project/default.aspx">Extender Project</category></item><item><title>Must-have Typed DataSet extensions</title><link>http://devlicio.us/blogs/ziemowit_skowronski/archive/2006/11/16/must-have-typed-dataset-extensions.aspx</link><pubDate>Thu, 16 Nov 2006 17:19:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:644</guid><dc:creator>Jimmy</dc:creator><slash:comments>18</slash:comments><description>
&lt;p&gt;Of course if you are using them.
&lt;/p&gt;

&lt;p&gt;Currently almost none is using standard data access methods in bigger projects. All the Data Access Layer (DAL) methods become very popular nowadays, just look at the most popular such as NHibernate, Sooda or the incoming ADO.NET. There is also an old friend among them, Typed DataSets which is better than many developers can imagine. Personally, I'm using it and I can't see any reason to switch to an another solution as this one works really fine and, apart some errors or some annoying features, gives a lot of good functionality. One of those good features is that the Typed DataSet is generated as a partial class and can be easily extend.
&lt;/p&gt;

&lt;p&gt;I my daily work I'm finding dozens of reasons for extending Typed DataSets at all levels, from adapters to rows and tables adding some logic, additional data control or so. There are two main reasons among all, why every generated adapter should be extended: transaction and timeout. Those two things are one of the most annoying lacks in the solution. By default, the Typed DataSet can't be executed inside of the transaction which is quite important issue in every more complicated project. Last time I found timeout as other annoying problem, as I had a few queries that needs a bit more than standard 40 seconds for execution. To bypass these two issues use simple code below:&lt;/p&gt;
&lt;textarea name="code" class="c#:nogutter" cols="80" rows="10"&gt;   
namespace MyAdapters
{
  public partial class MyTableAdapter
  {
    private SqlTransaction _transaction;
    public SqlTransaction Transaction
    {
      get { return _transaction; }
      set
      {
        _transaction = value;
        _connection = _transaction.Connection;
        if (_adapter == null)
          this.InitAdapter();
        foreach (SqlCommand command in this.CommandCollection)
        {
          command.Transaction = _transaction;
        }
        this.Adapter.InsertCommand.Transaction = _transaction;
        this.Adapter.UpdateCommand.Transaction = _transaction;
        this.Adapter.DeleteCommand.Transaction = _transaction;
      }
    }
    public void SetCommandTimeout(int timeout)
    {
      foreach (IDbCommand command in CommandCollection)
        command.CommandTimeout = timeout;
    }
  }
}
&lt;/textarea&gt; 
&lt;p&gt;Happy coding&lt;br&gt;&lt;/p&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=644" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Atlas Extenders Crash Course - Part 2.5 - Migration</title><link>http://devlicio.us/blogs/ziemowit_skowronski/archive/2006/11/01/Atlas-Extenders-Crash-Course-_2D00_-Part-2.5-_2D00_-Migration.aspx</link><pubDate>Wed, 01 Nov 2006 13:32:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:440</guid><dc:creator>Jimmy</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Welcome in the second and half post in the series dedicated adventures with Atlas Extenders. Originally, this series consist of three parts, but some changes in the world forces me to add one more post into the series:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://devlicio.us/blogs/ziemowit_skowronski/archive/2006/10/04/Atlas-Extender-Crash-Course-_1320_-Part-1_3A00_-Introduction.aspx"&gt;Introduction&lt;/a&gt; – what Atlas Extender is and how to create our own validation extender,
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://devlicio.us/blogs/ziemowit_skowronski/archive/2006/10/10/Atlas-Extender-Crash-Course-_1320_-Part-2_3A00_-Page-Methods.aspx"&gt;Page methods&lt;/a&gt; – how to add AJAX server-side validation,
&lt;/li&gt;
&lt;li&gt;Migration – from Atlas to ASP.NET 2.0 AJAX,
&lt;/li&gt;
&lt;li&gt;Integration with page – how to integrate extender with ASP.NET page to perform full form validation.
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Last time I was blogging about new release of the Atlas. Honestly, I was the very first with that news, but none noticed that. What a pity. Anyway, I promised to write a bit more about changes and because I'm working on extender it is good opportunity to see how these changes are working in real life. 
&lt;/p&gt;
&lt;p&gt;First of all, as I've mention before, several fundamental changes were made in the extender structure. Instead of four source files (Behavior.js, Designer.cs, Extender.cs and Property.cs) only three left. All properties have been relocated into the base Extender class.  That's mean that we can't use multiple properties for the extender anymore, as it was in previous version, but we have to add separate extenders for every control we want to extend. It is not a big deal but a little waste of screen space.
&lt;/p&gt;
&lt;p&gt;Ok, the migration. After removing old references and namespace declarations as well, and after adding new ones, we can start converting existing extender. 
&lt;/p&gt;
&lt;p&gt;Firstly, in the ValidatorExtender.cs, the class declaration should be changed for inherited from the ExtenderControlBase, as generic version of this base class does not exist anymore. Then all properties from the ValidatorProperties.cs should be copied to the Extender class and each of them should be followed by the ExtenderControlProperty attribute. Old Propertises.cs can be removed from the project now. Finally, the TargetControlType attribute should be added just before the Extender class to define type of target control. This allows us to limit extender to selected control type only. 
&lt;/p&gt;
&lt;p&gt;Next step is a quick change in the ValidatorDesigner.cs, where the Designer class declaration should be modified to
&lt;/p&gt;
&lt;div class="code"&gt;
&lt;div style="background:white none repeat scroll 0% 50%;font-family:Consolas;font-size:8pt;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;p style="margin:0px;"&gt;&lt;span style="color:blue;"&gt;class&lt;/span&gt; &lt;span style="color:teal;"&gt;ValidatorDesigner&lt;/span&gt; :&amp;nbsp; &lt;span style="color:teal;"&gt;ExtenderControlBaseDesigner&lt;/span&gt;&amp;lt;&lt;span style="color:teal;"&gt;ValidatorExtender&lt;/span&gt;&amp;gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;{&lt;/p&gt;
&lt;p style="margin:0px;"&gt;}&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Finally, we should change the ValidatorBahavior.js file where is a lot of important changes. The new Behavior.js consists of two parts, Validator.ValidatorBehavior object and prototype Validator.ValidatorBehavior.prototype. Because our old Behavior.js consists of only one part, we have to split our code. All property declarations should stay in main object whereas rest should go into prototype. 
&lt;/p&gt;
&lt;p&gt;After splitting copying and reformatting the code, we have to ensure if we are using "this." in every field declaration and everywhere we are using them later. The getDescriptor() function is no longer required so should be removed. Because object doesn't contain this.control property anymore, rename all its occurrences of from "this.control.elements" to "this.get_element()". Then, everywhere we are using $(name) it should be changed to $get(name) and finally, last two lines should be replaced as follows:
&lt;/p&gt;
&lt;div class="code"&gt;
&lt;div style="background:white none repeat scroll 0% 50%;font-family:Consolas;font-size:8pt;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;p style="margin:0px;"&gt;&lt;span style="color:green;"&gt;//before&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;Validator.ValidatorBehavior.registerSealedClass(&lt;span style="color:maroon;"&gt;'Validator.ValidatorBehavior'&lt;/span&gt;, Microsoft.AtlasControlExtender.BehaviorBase);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;Sys.TypeDescriptor.addType(&lt;span style="color:maroon;"&gt;'Validator'&lt;/span&gt;.toLowerCase() &lt;span style="color:green;"&gt;/* Safari Compat */&lt;/span&gt;, &lt;span style="color:maroon;"&gt;'ValidatorBehavior'&lt;/span&gt;, Validator.ValidatorBehavior);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&lt;span style="color:green;"&gt;//after&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;Validator.ValidatorBehavior.registerClass(&lt;span style="color:maroon;"&gt;'Validator.ValidatorBehavior'&lt;/span&gt;, AjaxControlToolkit.BehaviorBase);&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;After completing this boring part, we can start refactoring more important things around calling the WebMethod. In the first shot, _onMethodAborted function should be removed and then, arguments in all three functions left should be changed to (sender, eventArgs). To get user context we need now to use sender.get_userContext() and sender.get_result() in _onMethodComplete to get result.
&lt;/p&gt;
&lt;p&gt;Last thing to do is changing the way, how the WebMethod is invoked. Because this part of framework has been completely changed, we can't use Sys.Net.PageMethod.invoke() anymore. Instead of that, we have Sys.Net.ServiceMethodRequest class that will do exactly the same, so the WebMethod call will now looks as follow:
&lt;/p&gt;
&lt;div class="code"&gt;
&lt;div style="background:white none repeat scroll 0% 50%;font-family:Consolas;font-size:8pt;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;var&lt;/span&gt; svr = &lt;span style="color:blue;"&gt;new&lt;/span&gt; Sys.Net.ServiceMethodRequest();&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; svr.set_methodName(&lt;span style="color:blue;"&gt;this&lt;/span&gt;._serviceMethod);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; svr.get_parameters()[&lt;span style="color:maroon;"&gt;"Value"&lt;/span&gt;] = args.Value;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; svr.get_parameters()[&lt;span style="color:maroon;"&gt;"IsValid"&lt;/span&gt;] = args.IsValid;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; svr.add_completed(Function.createDelegate(&lt;span style="color:blue;"&gt;this&lt;/span&gt;, &lt;span style="color:blue;"&gt;this&lt;/span&gt;._onMethodComplete));&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; svr.add_error(Function.createDelegate(&lt;span style="color:blue;"&gt;this&lt;/span&gt;, &lt;span style="color:blue;"&gt;this&lt;/span&gt;._onMethodError));&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; svr.add_timeout(Function.createDelegate(&lt;span style="color:blue;"&gt;this&lt;/span&gt;, &lt;span style="color:blue;"&gt;this&lt;/span&gt;._onMethodTimeout));&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; svr.invoke(&lt;span style="color:blue;"&gt;this&lt;/span&gt;._currentCallID);&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Well, that class does the same but not exactly. I've found unexpected problems with calling the WebMethod. I've found somewhere (can't find it again) information that there is an issue in framework that allows to call WebMethods only when is located in script block in aspx page. Hope this will be corrected soon.
&lt;/p&gt;
&lt;p&gt;Process of the migration of the web application itself is well described in guide, provided on ASP.NET 2.0 AJAX webpage so that's all for now. After tests everything is working well and I can focus again on finishing extender, so the next, final part will be ready soon.&lt;/p&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=440" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/AJAX/default.aspx">AJAX</category><category domain="http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/Extender+Project/default.aspx">Extender Project</category></item><item><title>Mysterious Generic TreeSet&lt;T&gt;</title><link>http://devlicio.us/blogs/ziemowit_skowronski/archive/2006/10/13/Mysterious-Generic-TreeSet_3C00_T_3E00_.aspx</link><pubDate>Fri, 13 Oct 2006 13:20:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:319</guid><dc:creator>Jimmy</dc:creator><slash:comments>2</slash:comments><description>&lt;p&gt;Just a few minutes ago, I was looking for something in the System. Collections.Generic using Reflector. I turned on visibility for Private members in options and then I saw something new, a TreeSet&amp;lt;T&amp;gt;. A few days before I was playing with tree structures, so this class turned my attention. After a short search on google, I found a kinf of &lt;a href="http://www.itu.dk/research/c5/Release1.0/c5doc/types/C5.TreeSet%601.htm"&gt;documentation&lt;/a&gt; on Danish university webpage.
&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An implementation of Red-Black trees as an indexed, sorted collection with set semantics, cf. CLRS. TreeBag&amp;lt;T&amp;gt; for a version with bag semantics. TreeDictionary&amp;lt;K,V&amp;gt; for a sorted dictionary based on this tree implementation. The comparer (sorting order) may be either natural, because the item type is comparable (generic: or non-generic: System.IComparable) or it can be external and supplied by the user in the constructor.TODO: describe performance hereTODO: discuss persistence and its useful usage modes. Warn about the space leak possible with other usage modes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What the Red-Black tree is? According to &lt;a href="http://en.wikipedia.org/wiki/Red-black_tree"&gt;Wikipedia&lt;/a&gt;:
&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A red-black tree is a type of self-balancing binary search tree, a data structure used in computer science, typically used to implement associative arrays. The original structure was invented in 1972 by Rudolf Bayer who called them &amp;quot;symmetric binary B-trees&amp;quot;, but acquired its modern name in a paper in 1978 by Leo J. Guibas and Robert Sedgewick. It is complex, but has good worst-case running time for its operations and is efficient in practice: it can search, insert, and delete in O(log n) time, where n is the number of elements in the tree.
&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Sounds great but &amp;hellip; this is the internal class in System.Collections.Generic. Has anyone the slightest idea why is this class still kept in secret internal goods? That could be so useful. That is not fair.
&lt;/p&gt;

&lt;p&gt;I am going to cry alone.&lt;/p&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=319" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>Atlas Extender Crash Course – Part 2: Page Methods</title><link>http://devlicio.us/blogs/ziemowit_skowronski/archive/2006/10/10/Atlas-Extender-Crash-Course-_1320_-Part-2_3A00_-Page-Methods.aspx</link><pubDate>Tue, 10 Oct 2006 15:11:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:292</guid><dc:creator>Jimmy</dc:creator><slash:comments>0</slash:comments><description>&lt;p&gt;Welcome in the second post in the series dedicated adventures with Atlas Extenders. This series consist of three parts:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;div&gt;&lt;a href="http://devlicio.us/blogs/ziemowit_skowronski/archive/2006/10/04/Atlas-Extender-Crash-Course-_1320_-Part-1_3A00_-Introduction.aspx"&gt;Introduction&lt;/a&gt; – what Atlas Extender is and how to create our own validation extender,
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;div&gt;Page methods – how to add AJAX server-side validation,
&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;&lt;div&gt;Integration with page – how to integrate extender with ASP.NET page to perform full form validation.
&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Previous part has introduced us into Atlas Extender where we have had created simple extender with client behaviour. As I mention before, we have to repeat extender declaration in aspx for each validator we want to extend. In fact, there is no problem with this, but we have to add an extra two lines for every validator, only to declare extender itself. The same way control tree grows, we have to use and remember number of id’s and so on. Nothing serious but it is not and elegant solution. In order to make it more friendly and elegant, we will modify our extender in way, which will allow us using only one extender and adding only properties for each validator:
&lt;/p&gt;
&lt;div class="code"&gt;
&lt;div style="background:white none repeat scroll 0% 50%;font-family:Consolas;font-size:8pt;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;cc1&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:maroon;"&gt;ValidatorExtender&lt;/span&gt; &lt;span style="color:red;"&gt;ID&lt;/span&gt;&lt;span style="color:blue;"&gt;="ValidatorExtender1"&lt;/span&gt; &lt;span style="color:red;"&gt;runat&lt;/span&gt;&lt;span style="color:blue;"&gt;="server"&lt;/span&gt; &lt;span style="color:red;"&gt;ScriptPath&lt;/span&gt;&lt;span style="color:blue;"&gt;="ValidatorExtenderBehavior.js"&lt;/span&gt; &lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt; &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;cc1&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:maroon;"&gt;ValidatorProperties&lt;/span&gt; &lt;span style="color:red;"&gt;ErrorCssClass&lt;/span&gt;&lt;span style="color:blue;"&gt;="error"&lt;/span&gt; &lt;span style="color:red;"&gt;TargetControlID&lt;/span&gt;&lt;span style="color:blue;"&gt;="TestValidator"&lt;/span&gt; &lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;cc1&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:maroon;"&gt;ValidatorProperties&lt;/span&gt; &lt;span style="color:red;"&gt;ErrorCssClass&lt;/span&gt;&lt;span style="color:blue;"&gt;="error"&lt;/span&gt; &lt;span style="color:red;"&gt;TargetControlID&lt;/span&gt;&lt;span style="color:blue;"&gt;="TestValidator2"&lt;/span&gt; &lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color:maroon;"&gt;cc1&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:maroon;"&gt;ValidatorExtender&lt;/span&gt;&lt;span style="color:blue;"&gt;&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;This task is simpler than it looks like when I was writing the first part. We do not have to iterate through properties or do other weird and difficult task. In fact, there is nothing to do about this, just simple change declaration as shown above. 
&lt;/p&gt;
&lt;p&gt;Let us then jump to the next part and see how things are going with server-side validation. As I mention in the first part, extender will not work with the CustomValidator, mainly because, by default this type of validator have no client script validation we can catch and use. Unfortunately, the CustomValidator is perfect for complex validation such as validation against a database. To keep this feature, and even make it better, we can use a Page Method, which is server-side method executed asynchronously in the background, what makes it perfect to perform server validation. So let us do some coding. 
&lt;/p&gt;
&lt;p&gt;First, we need new properties in the extender: ServiceMethod where server-side method will be stored and UpdatingCssClass for class that will indicate that control is during validation. Let’s then add the following code in ValidatorProperties.cs 
&lt;/p&gt;
&lt;div class="code"&gt;
&lt;div style="background:white none repeat scroll 0% 50%;font-family:Consolas;font-size:8pt;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; The method name of the web service of page method to call.&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; [&lt;span style="color:teal;"&gt;DefaultValue&lt;/span&gt;(&lt;span style="color:maroon;"&gt;""&lt;/span&gt;)]&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; [System.Diagnostics.CodeAnalysis.&lt;span style="color:teal;"&gt;SuppressMessage&lt;/span&gt;(&lt;span style="color:maroon;"&gt;"Microsoft.Globalization"&lt;/span&gt;, &lt;span style="color:maroon;"&gt;"CA1303:DoNotPassLiteralsAsLocalizedParameters"&lt;/span&gt;, Justification = &lt;span style="color:maroon;"&gt;"Assembly is not localized"&lt;/span&gt;)]&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; ServiceMethod&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;get&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; GetPropertyStringValue(&lt;span style="color:maroon;"&gt;"ServiceMethod"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; 

&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;set&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; SetPropertyStringValue(&lt;span style="color:maroon;"&gt;"ServiceMethod"&lt;/span&gt;, &lt;span style="color:blue;"&gt;value&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; &lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; A CSS style to 

apply while the validation is in progress&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:gray;"&gt;///&lt;/span&gt;&lt;span style="color:green;"&gt; 

&lt;/span&gt;&lt;span style="color:gray;"&gt;&amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; [&lt;span style="color:teal;"&gt;DefaultValue&lt;/span&gt;(&lt;span style="color:maroon;"&gt;""&lt;/span&gt;)]&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; UpdatingCssClass&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;get&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; GetPropertyStringValue(&lt;span style="color:maroon;"&gt;"UpdatingCssClass"&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;set&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; SetPropertyStringValue(&lt;span style="color:maroon;"&gt;"UpdatingCssClass"&lt;/span&gt;, &lt;span style="color:blue;"&gt;value&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and corresponding code in ValidatorBehavior.js
&lt;/p&gt;
&lt;div class="code"&gt;
&lt;div style="background:white none repeat scroll 0% 50%;font-family:Consolas;font-size:8pt;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;var&lt;/span&gt; 

_updatingCssClass;&amp;nbsp; &lt;span style="color:green;"&gt;//updating css class for fields&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;var&lt;/span&gt; _serviceMethod;&amp;nbsp; &lt;span style="color:green;"&gt;//web method with validation&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.getDescriptor = &lt;span style="color:blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;var&lt;/span&gt; td = Validator.ValidatorBehavior.callBaseMethod(&lt;span style="color:blue;"&gt;this&lt;/span&gt;, &lt;span style="color:maroon;"&gt;'getDescriptor'&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; td.addProperty(&lt;span style="color:maroon;"&gt;'ErrorCssClass'&lt;/span&gt;, 

String);&amp;nbsp; &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; td.addProperty(&lt;span style="color:maroon;"&gt;'ServiceMethod'&lt;/span&gt;, String); &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; td.addProperty(&lt;span style="color:maroon;"&gt;'UpdatingCssClass'&lt;/span&gt;, String); &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; 

td.addProperty(&lt;span style="color:maroon;"&gt;'IsValid'&lt;/span&gt;, Boolean);&amp;nbsp; &amp;nbsp; &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; td;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.get_ServiceMethod = &lt;span style="color:blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; _serviceMethod;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.set_ServiceMethod = &lt;span style="color:blue;"&gt;function&lt;/span&gt;(value) {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (_serviceMethod != value) {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _serviceMethod = value;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.raisePropertyChanged(&lt;span style="color:maroon;"&gt;'ServiceMethod'&lt;/span&gt;);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; }&amp;nbsp; &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.get_UpdatingCssClass = &lt;span style="color:blue;"&gt;function&lt;/span&gt;() {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; 

&amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; _updatingCssClass;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.set_UpdatingCssClass = &lt;span style="color:blue;"&gt;function&lt;/span&gt;(value) {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; 

_updatingCssClass = value;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;In order to execute Page Method we will have to modify evaluationfunctionMockup function created before, but first let us look how this should work. Because executing of the Page Method can possibly be relatively long, like contacting database or making other difficult tasks, we have to do this asynchronously using Sys.Net.PageMethod.invoke() method from Atlas. This method runs selected server-side method asynchronously and assigns event handlers. Investigation of the Atlas client class library allows finding possible, however I am not entirely sure about last three parameters. I have estimated this syntax based on Sys.Net.WebMethod.invoke, which seems to be similar, but if anyone knows exact syntax, send me info please. This or another way possible syntax could be:
&lt;/p&gt;
&lt;div class="code"&gt;
&lt;div style="background:white none repeat scroll 0% 50%;font-family:Consolas;font-size:8pt;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; Sys.Net.PageMethod.invoke = &lt;span style="color:blue;"&gt;function&lt;/span&gt;(&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; methodName,&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  &lt;span style="color:green;"&gt;//name of 

the method to execute&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; params,&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;  &lt;span style="color:green;"&gt;//parameters&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; onMethodComplete,&amp;nbsp;  &lt;span style="color:green;"&gt;//function to be executed when 

method has been completed&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; onMethodTimeout,&amp;nbsp; &amp;nbsp; &lt;span style="color:green;"&gt;//function to be 

executed on timeout&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; onMethodError,&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:green;"&gt;//function to be executed 

on error&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; onMethodAborted,&amp;nbsp; &amp;nbsp; &lt;span style="color:green;"&gt;//function to be executed when methos 

execution has been aborted&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; userContext,&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:green;"&gt;//user 

context &lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; timeoutInterval,&amp;nbsp; &amp;nbsp; &lt;span style="color:green;"&gt;//timeout&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; priority,&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; useGetMethod&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; )&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;As I mention, we have to modify evaluationfunctionMockup function to run Page Method. This modification id quite simple:
&lt;/p&gt;
&lt;div class="code"&gt;
&lt;div style="background:white none repeat scroll 0% 50%;font-family:Consolas;font-size:8pt;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.evaluationfunctionMockup = &lt;span style="color:blue;"&gt;function&lt;/span&gt;(val) {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;var&lt;/span&gt; value = &lt;span style="color:maroon;"&gt;""&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;var&lt;/span&gt; isValid = 

val.defaultEvaluationfunction(val); &lt;span style="color:green;"&gt;//call original validation function&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (&lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:blue;"&gt;this&lt;/span&gt;.control.element.controltovalidate) == &lt;span style="color:maroon;"&gt;"string"&lt;/span&gt;) {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; value = ValidatorGetValue(&lt;span style="color:blue;"&gt;this&lt;/span&gt;.control.element.controltovalidate);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;var&lt;/span&gt; controltovalidate = $(&lt;span style="color:blue;"&gt;this&lt;/span&gt;.control.element.controltovalidate);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:green;"&gt;//set visual style for assigned field according to validation result&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (!isValid) { &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; controltovalidate.className = 

_errorCssClass;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; controltovalidate.title = &lt;span style="color:blue;"&gt;this&lt;/span&gt;.control.element.defaultErrorMessage;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; } &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;else&lt;/span&gt; &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (_serviceMethod) {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;var&lt;/span&gt; args = {Value:value, 

IsValid:isValid};&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.validate(val, args);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; isValid = &lt;span style="color:blue;"&gt;false&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; } &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;else&lt;/span&gt; &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&amp;nbsp; &amp;nbsp;  &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; controltovalidate.className = controltovalidate.defultClassName;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; 

&amp;nbsp; &amp;nbsp; controltovalidate.title = &lt;span style="color:maroon;"&gt;""&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; isValid;&amp;nbsp; &lt;span style="color:green;"&gt;//return 

validation result for further processing&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;At very beginning, default client validation is checked. I have assumed that the client side validation have priority over the server. If validator is valid, and the extender’s property ServiceMethod has been set, arguments are prepared and this.validate() function is executed. This function changes the CSS class as defined in the UpdatingCssClass property and calls the Page Method. Because, standard validator adds onChange event validation to the validated control we should disable the control to avoid executing another validation until current one will complete.
&lt;/p&gt;
&lt;div class="code"&gt;
&lt;div style="background:white none repeat scroll 0% 50%;font-family:Consolas;font-size:8pt;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.validate = &lt;span style="color:blue;"&gt;function&lt;/span&gt;(sender, args) {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; _currentCallID = 

++_callID;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (_serviceMethod) {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 

&lt;span style="color:blue;"&gt;var&lt;/span&gt; controltovalidate = $(&lt;span style="color:blue;"&gt;this&lt;/span&gt;.control.element.controltovalidate);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; controltovalidate.disabled = &lt;span style="color:blue;"&gt;true&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 

controltovalidate.className = _updatingCssClass;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp;  &lt;span style="color:green;"&gt;// Call the helper web 

service&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; Sys.Net.PageMethod.invoke(&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 

_serviceMethod,&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; { &lt;span style="color:maroon;"&gt;'Value'&lt;/span&gt; : args.Value, &lt;span style="color:maroon;"&gt;'IsValid'&lt;/span&gt; : args.IsValid },&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Function.createDelegate(&lt;span style="color:blue;"&gt;this&lt;/span&gt;, &lt;span style="color:blue;"&gt;this&lt;/span&gt;._onMethodComplete),&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 

Function.createDelegate(&lt;span style="color:blue;"&gt;this&lt;/span&gt;, &lt;span style="color:blue;"&gt;this&lt;/span&gt;._onMethodTimeout),&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; 

&amp;nbsp; &amp;nbsp; &amp;nbsp; Function.createDelegate(&lt;span style="color:blue;"&gt;this&lt;/span&gt;, &lt;span style="color:blue;"&gt;this&lt;/span&gt;._onMethodError),&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Function.createDelegate(&lt;span style="color:blue;"&gt;this&lt;/span&gt;, &lt;span style="color:blue;"&gt;this&lt;/span&gt;._onMethodAborted),&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; _currentCallID&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 

);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; }&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;When Page Method execution will complete, _onMethodComplete() function will be called, where the validation is finalised. I’ve assume that validation is successful Page Methods returns an empty string while when validation will not succeed than validation message will be returned. The control is set back enabled, then control’s CSS class is set according to the validation result, and finally validator property isvalid is set to indicate the validation result.
&lt;/p&gt;
&lt;div class="code"&gt;
&lt;div style="background:white none repeat scroll 0% 50%;font-family:Consolas;font-size:8pt;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;._onMethodComplete = &lt;span style="color:blue;"&gt;function&lt;/span&gt; (result, response, userContext) {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; 

&lt;span style="color:blue;"&gt;if&lt;/span&gt; (userContext != _currentCallID) &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:green;"&gt;// Time has passed; make sure the element is still 

accessible&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (&lt;span style="color:blue;"&gt;this&lt;/span&gt;.control &amp;amp;&amp;amp; 

&lt;span style="color:blue;"&gt;this&lt;/span&gt;.control.element) {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;var&lt;/span&gt; 

controltovalidate = $(&lt;span style="color:blue;"&gt;this&lt;/span&gt;.control.element.controltovalidate);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 

controltovalidate.disabled = &lt;span style="color:blue;"&gt;false&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; 

(result == &lt;span style="color:maroon;"&gt;""&lt;/span&gt;) &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 

&amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.control.element.isvalid = &lt;span style="color:blue;"&gt;true&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; 

&amp;nbsp; &amp;nbsp; controltovalidate.className = controltovalidate.defultClassName;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 

controltovalidate.title = &lt;span style="color:maroon;"&gt;""&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; 

&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;else&lt;/span&gt; &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; 

&amp;nbsp; controltovalidate.className = _errorCssClass;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; controltovalidate.title = result;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.control.element.isvalid = &lt;span style="color:blue;"&gt;false&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; 

}&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Functions for other three events that could possibly happen during Page Method execution are quite basic:
&lt;/p&gt;
&lt;div class="code"&gt;
&lt;div style="background:white none repeat scroll 0% 50%;font-family:Consolas;font-size:8pt;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;._onMethodError = &lt;span style="color:blue;"&gt;function&lt;/span&gt;(result, response, userContext) {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; 

&amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (userContext != _currentCallID) &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.control.element.innerHTML = &lt;span style="color:maroon;"&gt;"WebService call failed: "&lt;/span&gt; + response.get_statusCode();&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;._onMethodTimeout = &lt;span style="color:blue;"&gt;function&lt;/span&gt;(request, userContext) {&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (userContext != 

_currentCallID) &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; 

&amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.control.element.innerHTML = &lt;span style="color:maroon;"&gt;"Webservice call timed out."&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; }&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;._onMethodAborted = 

&lt;span style="color:blue;"&gt;function&lt;/span&gt;(request, userContext) {&amp;nbsp;  &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;if&lt;/span&gt; (userContext != _currentCallID) &lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;this&lt;/span&gt;.control.element.innerHTML = &lt;span style="color:maroon;"&gt;"Webservice call 

aborted."&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;Therefore, we have done. In order to test, let us change declaration in the page
&lt;/p&gt;
&lt;div class="code"&gt;
&lt;div style="background:white none repeat scroll 0% 50%;font-family:Consolas;font-size:8pt;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color:maroon;"&gt;cc1&lt;/span&gt;&lt;span style="color:blue;"&gt;:&lt;/span&gt;&lt;span style="color:maroon;"&gt;ValidatorProperties&lt;/span&gt; &lt;span style="color:red;"&gt;ErrorCssClass&lt;/span&gt;&lt;span style="color:blue;"&gt;="error"&lt;/span&gt; &lt;span style="color:red;"&gt;TargetControlID&lt;/span&gt;&lt;span style="color:blue;"&gt;="TestValidator"&lt;/span&gt; &lt;span style="color:red;"&gt;ServiceMethod&lt;/span&gt;&lt;span style="color:blue;"&gt;="ServerSideValidation"&lt;/span&gt; &lt;span style="color:red;"&gt;UpdatingCssClass&lt;/span&gt;&lt;span style="color:blue;"&gt;="updating"&lt;/span&gt; &lt;span style="color:blue;"&gt;/&amp;gt;&lt;/span&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;and add validation method to the page code behind.
&lt;/p&gt;
&lt;div class="code"&gt;
&lt;div style="background:white none repeat scroll 0% 50%;font-family:Consolas;font-size:8pt;color:black;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; [System.Web.Services.&lt;span style="color:teal;"&gt;WebMethod&lt;/span&gt;]&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &lt;span style="color:blue;"&gt;public&lt;/span&gt; &lt;span style="color:blue;"&gt;string&lt;/span&gt; 

ServerSideValidation(&lt;span style="color:blue;"&gt;string&lt;/span&gt; value, &lt;span style="color:blue;"&gt;bool&lt;/span&gt; isValid)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; 

{&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; System.Threading.&lt;span style="color:teal;"&gt;Thread&lt;/span&gt;.Sleep(2500);&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; 

&lt;span style="color:blue;"&gt;if&lt;/span&gt; (value != &lt;span style="color:maroon;"&gt;"1234"&lt;/span&gt;)&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:maroon;"&gt;"value from server should be '1234'"&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;else&lt;/span&gt;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="color:blue;"&gt;return&lt;/span&gt; &lt;span style="color:maroon;"&gt;""&lt;/span&gt;;&lt;/p&gt;
&lt;p style="margin:0px;"&gt;&amp;nbsp; }&lt;/p&gt;
&lt;/div&gt;
&lt;/div&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;As you probably have already noticed, our extender can now validate using Page Methods, but form will not care about results of this validation. Application is rather limited do far. In the next part, I will show how to stop form from postback until all validation calls complete.&lt;/p&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=292" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/AJAX/default.aspx">AJAX</category><category domain="http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/Extender+Project/default.aspx">Extender Project</category></item><item><title>Atlas Extender Crash Course – Part 1: Introduction</title><link>http://devlicio.us/blogs/ziemowit_skowronski/archive/2006/10/04/Atlas-Extender-Crash-Course-_1320_-Part-1_3A00_-Introduction.aspx</link><pubDate>Wed, 04 Oct 2006 15:54:00 GMT</pubDate><guid isPermaLink="false">40756a8b-6212-4073-9d98-6c26781577de:197</guid><dc:creator>Jimmy</dc:creator><slash:comments>2</slash:comments><description>&lt;P&gt;I don’t actually remember when I’ve met Atlas very first time, but it was some time ago. For almost everything I was working on, UpdatePanel and a few controls from Toolkit were absolutely fine and everything worked well, so there was no need to do anything more. Then my time&amp;nbsp;came. I always had problems with validators, especially with displaying messages, exclamations and other visual stuff. Whatever I’ve done, I was not satisfied with the results. All these exclamations, stars and messages has stopped me&amp;nbsp;from creating a slick interface. What I’ve always wanted was just simply change the way input field displays when there is an error by changing its class or so. &lt;/P&gt;
&lt;P&gt;The very first idea to make myself happier was to create a bunch of classes that would extend the standard validators but instead of displaying messages, it would change properties of the validated input control. Sounds easy but doesn’t solve the postback problem at all. So I’ve decided to use an Atlas extender and just extend and change the validators’ functionality. In this series, I will show you how to extend the standard ASP.NET validator with some new exciting features. If everything will be fine and the sky will not fall onto my head we will finish in four or so parts with server side validation and couple other funny things. &lt;/P&gt;
&lt;P&gt;Let us begin with a short introduction into the Atlas extender. Extender is a class that wraps the other components to extend their functionality, very similar to the decorator pattern. After adding Atlas Control Project to the site, we will see a number of files created. &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;A href="http://devlicio.us/photos/brendan/images/198/original.aspx" target=_blank&gt;&lt;IMG height=148 src="http://devlicio.us/photos/brendan/images/198/original.aspx" width=207 border=0&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;The extender&amp;nbsp;is composed&amp;nbsp;of Java Script file with all client side behaviour and three server side classes. In this part, we are about extending some client side behaviour so we will focus on two parts only, Java Script and server side Properties. &lt;/P&gt;
&lt;P&gt;Before we will begin coding, let us look what we want to achieve. The standard validator looks … well everyone knows already how it looks like. We want to hide an error message that displayed by default, then change CSS class of the validated control assigned to and finally add the message as a tooltip. &lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;A href="http://devlicio.us/photos/brendan/images/199/original.aspx" target=_blank&gt;&lt;IMG height=76 src="http://devlicio.us/photos/brendan/images/199/original.aspx" width=400 border=0&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;Basic steps of creating extenders are described in Atlas Control Toolbox, so I will just mention the most important things here. To make the extender easier to use, we should limit it only to controls inherited from BaseValidator, so we should change part of declarations in ValidatorExtender.cs, ValidatorDesigner.cs and ValidatorProperties.cs classes similar to this: &lt;/P&gt;
&lt;DIV class=code&gt;
&lt;DIV style="FONT-SIZE:8pt;BACKGROUND:white 0% 50%;COLOR:black;FONT-FAMILY:Consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;class&lt;/SPAN&gt; &lt;SPAN style="COLOR:teal;"&gt;ValidatorProperties&lt;/SPAN&gt; : &lt;SPAN style="COLOR:teal;"&gt;TargetControlPropertiesBase&lt;/SPAN&gt;&amp;lt;&lt;SPAN style="COLOR:teal;"&gt;BaseValidator&lt;/SPAN&gt;&amp;gt;&lt;/P&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;Next step is adding the property for CSS class name that will be assigned to the validated control: &lt;/P&gt;
&lt;DIV class=code style="FONT-SIZE:8pt;BACKGROUND:white 0% 50%;COLOR:black;FONT-FAMILY:Consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;P style="MARGIN:0px;"&gt;[&lt;SPAN style="COLOR:teal;"&gt;DefaultValue&lt;/SPAN&gt;(&lt;SPAN style="COLOR:maroon;"&gt;""&lt;/SPAN&gt;)]&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:blue;"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;string&lt;/SPAN&gt; ErrorCssClass&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;{&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;get&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;return&lt;/SPAN&gt; GetPropertyStringValue(&lt;SPAN style="COLOR:maroon;"&gt;"ErrorCssClass"&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;set&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; &amp;nbsp; SetPropertyStringValue(&lt;SPAN style="COLOR:maroon;"&gt;"ErrorCssClass"&lt;/SPAN&gt;, &lt;SPAN style="COLOR:blue;"&gt;value&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;}&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;Most of the&amp;nbsp;work left&amp;nbsp;in ValidatorBehavior.js client side script file. In normal case, this file is included into the extender and added to the page as a web resource, which is great but makes it hard to debug and test. We can avoid that by using ScriptPath attribute, which will add selected script file from the application directory. After compiling and adding extender to the test page, we should copy ValidatorBehavior.js from the extender project directory to the application and set extender as follows: &lt;/P&gt;
&lt;DIV class=code style="FONT-SIZE:8pt;BACKGROUND:white 0% 50%;COLOR:black;FONT-FAMILY:Consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;cc1&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;ValidatorExtender&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ID&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="ValidatorExtender1"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="server"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ScriptPath&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="ValidatorBehavior.js"&amp;gt;&lt;/SPAN&gt; &lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;cc1&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;ValidatorProperties&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;ErrorCssClass&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="error"&lt;/SPAN&gt; &lt;SPAN style="COLOR:red;"&gt;TargetControlID&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;="TestValidator"&lt;/SPAN&gt; &lt;SPAN style="COLOR:blue;"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;cc1&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;:&lt;/SPAN&gt;&lt;SPAN style="COLOR:maroon;"&gt;ValidatorExtender&lt;/SPAN&gt;&lt;SPAN style="COLOR:blue;"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;Now we can easily debug and test all Java Script. First, we should add functions to read and write the property we&amp;nbsp;created above and variable to store its value and modify getDescriptor function to add property to the descriptor. &lt;/P&gt;
&lt;DIV class=code style="FONT-SIZE:8pt;BACKGROUND:white 0% 50%;COLOR:black;FONT-FAMILY:Consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;var&lt;/SPAN&gt; _errorCssClass;&amp;nbsp; &lt;SPAN style="COLOR:green;"&gt;//error css class for fields&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;this&lt;/SPAN&gt;.get_ErrorCssClass = &lt;SPAN style="COLOR:blue;"&gt;function&lt;/SPAN&gt;() {&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;return&lt;/SPAN&gt; _errorCssClass;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;this&lt;/SPAN&gt;.set_ErrorCssClass = &lt;SPAN style="COLOR:blue;"&gt;function&lt;/SPAN&gt;(value) {&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; &amp;nbsp; _errorCssClass = value;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;this&lt;/SPAN&gt;.getDescriptor = &lt;SPAN style="COLOR:blue;"&gt;function&lt;/SPAN&gt;() {&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;var&lt;/SPAN&gt; td = Validator.ValidatorBehavior.callBaseMethod(&lt;SPAN style="COLOR:blue;"&gt;this&lt;/SPAN&gt;, &lt;SPAN style="COLOR:maroon;"&gt;'getDescriptor'&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; &amp;nbsp; td.addProperty(&lt;SPAN style="COLOR:maroon;"&gt;'ErrorCssClass'&lt;/SPAN&gt;, String);&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; &amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;return&lt;/SPAN&gt; td;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&amp;nbsp; }&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;In order to change behaviour of the validator we have to catch original validation function. After a few experiments we can find, that the validator has a function named evaluationfunction, generated by ASP.NET and depended on type of the validator but it always has the same parameters and returns true or false as a validation result. To catch this function we can store the original function in a separate property and change old one function to mockup that will call the original and then do what we want. Because we want to change the CSS class for the input associated with the validator to value stored in ErrorCssClass property, we have to store the original class to be able to restore it later when validation will be successful. Almost the same way we will deal with the error message. Therefore, first we have to modify initialize function as follows: &lt;/P&gt;
&lt;DIV class=code style="FONT-SIZE:8pt;BACKGROUND:white 0% 50%;COLOR:black;FONT-FAMILY:Consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;this&lt;/SPAN&gt;.initialize = &lt;SPAN style="COLOR:blue;"&gt;function&lt;/SPAN&gt;() {&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; Validator.ValidatorBehavior.callBaseMethod(&lt;SPAN style="COLOR:blue;"&gt;this&lt;/SPAN&gt;, &lt;SPAN style="COLOR:maroon;"&gt;'initialize'&lt;/SPAN&gt;);&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;SPAN style="COLOR:green;"&gt;//store original validation function and replace it by extender mockup&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; control.element.defaultEvaluationfunction = control.element.evaluationfunction;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; control.element.evaluationfunction = Function.createDelegate(&lt;SPAN style="COLOR:blue;"&gt;this&lt;/SPAN&gt;, evaluationfunctionMockup);&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;SPAN style="COLOR:green;"&gt;//store original error message from the validator and clean the validator content&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; control.element.defaultErrorMessage = control.element.innerText;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; control.element.innerText = &lt;SPAN style="COLOR:maroon;"&gt;""&lt;/SPAN&gt;;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;SPAN style="COLOR:green;"&gt;//store original css class from the field assigned to validator&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;var&lt;/SPAN&gt; controltovalidate = $(control.element.controltovalidate);&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; controltovalidate.defultClassName = controltovalidate.className;&amp;nbsp; &amp;nbsp; &lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;After original initialisation, we are storing the default validation function in the separate property for later use and changing it to delegate to the mockup function described below. To get control, which the extender has been assigned to, we can use extender’s control.element property. Later then we are storing the original error message and clearing it to prevent the validator from displaying the message on his own. Finally, the same way we are storing the original CSS class from the validated control. Because the extender has been limited only to use with the validator control we can assume that there always will be correct properties. Now, when the validator will be validated, the mockup function will be executed instead of the original. There it is: &lt;/P&gt;
&lt;DIV class=code style="FONT-SIZE:8pt;BACKGROUND:white 0% 50%;COLOR:black;FONT-FAMILY:Consolas;-moz-background-clip:-moz-initial;-moz-background-origin:-moz-initial;-moz-background-inline-policy:-moz-initial;"&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;1&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;this&lt;/SPAN&gt;.evaluationfunctionMockup = &lt;SPAN style="COLOR:blue;"&gt;function&lt;/SPAN&gt;(val) {&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;2&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;var&lt;/SPAN&gt; isValid = val.defaultEvaluationfunction(val); &lt;SPAN style="COLOR:green;"&gt;//call original validation function&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;3&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;var&lt;/SPAN&gt; controltovalidate = $(&lt;SPAN style="COLOR:blue;"&gt;this&lt;/SPAN&gt;.control.element.controltovalidate);&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;4&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;SPAN style="COLOR:green;"&gt;//set visual style for assigned field according to validation result&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;5&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;if&lt;/SPAN&gt; (!isValid) { &lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;6&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; controltovalidate.className = _errorCssClass;&amp;nbsp; &lt;SPAN style="COLOR:green;"&gt;//set error css class&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;7&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; controltovalidate.title = val.defaultErrorMessage;&amp;nbsp; &lt;SPAN style="COLOR:green;"&gt;//set message as a tooltip&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;8&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; } &lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;9&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;else&lt;/SPAN&gt; &lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;10&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; {&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;11&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; controltovalidate.className = controltovalidate.defultClassName; &lt;SPAN style="COLOR:green;"&gt;//restore original css class&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;12&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &amp;nbsp; controltovalidate.title = &lt;SPAN style="COLOR:maroon;"&gt;""&lt;/SPAN&gt;; &lt;SPAN style="COLOR:green;"&gt;//clear tooltip&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;13&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; }&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;14&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp; &lt;SPAN style="COLOR:blue;"&gt;return&lt;/SPAN&gt; isValid;&amp;nbsp; &lt;SPAN style="COLOR:green;"&gt;//return validation result for further processing&lt;/SPAN&gt;&lt;/P&gt;
&lt;P style="MARGIN:0px;"&gt;&lt;SPAN&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;15&lt;/SPAN&gt;&amp;nbsp;&amp;nbsp; }&lt;/P&gt;&lt;/DIV&gt;
&lt;P&gt;On the very beginning, the original validation function executes to perform validation. Depend on the validation result the CSS class for the validated control is changed and the message tooltip is set up. &lt;/P&gt;
&lt;P&gt;This easy extender shows how to change behaviour of original validator. What is important, this will not work with CustomValidator with server side validation. We will deal with this later in&amp;nbsp;the&amp;nbsp;course. &lt;/P&gt;
&lt;P&gt;Next: &lt;/P&gt;
&lt;P&gt;The above extender can be assigned to the only one validator&amp;nbsp;and&amp;nbsp;has to be repeated for each validator on the form. In the next part, I will show how to create one extender for all validators.&lt;/P&gt;&lt;img src="http://devlicio.us/aggbug.aspx?PostID=197" width="1" height="1"&gt;</description><category domain="http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/AJAX/default.aspx">AJAX</category><category domain="http://devlicio.us/blogs/ziemowit_skowronski/archive/tags/Extender+Project/default.aspx">Extender Project</category></item></channel></rss>