<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" version="2.0">
  <channel>
    <title>Manuel Abadia's ASP.NET stuff - ASP.NET</title>
    <link>http://www.manuelabadia.com/blog/</link>
    <description />
    <language>en-us</language>
    <copyright>Manuel Abadia</copyright>
    <lastBuildDate>Mon, 22 Dec 2008 23:35:20 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 1.9.6264.0</generator>
    <managingEditor>blogcomments@manuelabadia.com</managingEditor>
    <webMaster>blogcomments@manuelabadia.com</webMaster>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=0606d95f-56ae-4dd7-8458-69cd550fa356</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,0606d95f-56ae-4dd7-8458-69cd550fa356.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,0606d95f-56ae-4dd7-8458-69cd550fa356.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=0606d95f-56ae-4dd7-8458-69cd550fa356</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
All controls that inherit from ListControl (BulletedList, CheckBoxList, DropDownList,
ListBox and RadioButtonList) have some annoying behavior in common: 
</p>
        <p>
You can only bind the control to a single property using the DataTextField property.
For example, if you have a Customer class with properties Id, Name, Surname, etc and
you want to show the full name of a customer in any of the ListControls, you have
several options:
</p>
        <ol>
          <li>
When you get the data from the database, return another column with the name and surname. 
</li>
          <li>
Create a property (f.e. FullName) that returns what you want to show. 
</li>
          <li>
Use a DataSet and add a computed column. 
</li>
          <li>
Manually add ListItems with the appropriate values performing the data bind manually. 
</li>
          <li>
Create a simple class that will be bound (instead of the original one) just to fix
the problem.</li>
        </ol>
        <p>
The truth is that I don’t like any of those options, all of them are hacks. 
</p>
        <p>
For nested properties you have the similar problems. You can bind to Id or Name, but
you can’t bind to Address.City or Address.Zip.
</p>
        <p>
Today I faced this problem again and I decided to investigate a more innovative solution.
The problem itself is in the controls that inherit from ListControl that are very
strict in the binding options. So I took a look of how the controls perform the binding
to see if I could do anything to overcome those limitations. At first sight I thought
I was loosing my time but after a deeper study I found that it was amazingly easy
to fix those problems in a very sleek way.
</p>
        <p>
The data binding of the controls is performed in the PerformDataBinding method. The
code at ListControl.PerformDataBinding uses DataBinder.GetPropertyValue to retrieve
the value to show in the control if you set the DataTextField property. However, DataBinder.GetPropertyValue
doesn’t handle nested properties. DataBinder.Eval is a better choice because it does
handle nested properties. So using it we solve one problem. The other problem can
be solved easily as well. As we have two properties that control how the Text of each
ListItem will be extracted and shown from the data source, with a bit more of effort
we can handle the new functionality. I have come up with a very intuitive solution:
</p>
        <ul>
          <li>
DataTextField allows one or more properties (that can be nested if needed) separated
by commas. 
</li>
          <li>
DataTextFormatString can be used to control the formatting of the items, using {0},
{1}, {2}, {3}… as the value of the properties specified with DataTextField.</li>
        </ul>
        <p>
The code that performs the data binding is:
</p>
        <div class="csharp" style="BORDER-RIGHT: #d0d0d0 1px solid; BORDER-TOP: #d0d0d0 1px solid; BORDER-LEFT: #d0d0d0 1px solid; COLOR: #006; BORDER-BOTTOM: #d0d0d0 1px solid; FONT-FAMILY: monospace; BACKGROUND-COLOR: #f0f0f0">
          <span style="COLOR: #008080; FONT-STYLE: italic">///
&lt;summary&gt;Binds the data to the control.&lt;/summary&gt;</span>
          <br />
          <span style="COLOR: #008080; FONT-STYLE: italic">/// &lt;param name="ctrl"&gt;control
to bind.&lt;/param&gt;</span>
          <br />
          <span style="COLOR: #008080; FONT-STYLE: italic">/// &lt;param name="dataSource"&gt;data
to bind to the control.&lt;/param&gt;</span>
          <br />
          <span style="COLOR: #0600ff">public</span>
          <span style="COLOR: #0600ff">static</span>
          <span style="COLOR: #0600ff">void</span> PerformDataBinding<span style="COLOR: #000000">(</span>ListControl
ctrl, IEnumerable dataSource<span style="COLOR: #000000">)</span><br /><span style="COLOR: #000000">{</span><br />
    <span style="COLOR: #008080; FONT-STYLE: italic">// resets the selected
item</span><br />
    ctrl.<span style="COLOR: #0000ff">SelectedIndex</span><span style="COLOR: #008000">=</span><span style="COLOR: #008000">-</span><span style="COLOR: #ff0000">1</span><span style="COLOR: #008000">;</span><br />
    ctrl.<span style="COLOR: #0000ff">SelectedValue</span><span style="COLOR: #008000">=</span> null<span style="COLOR: #008000">;</span><br /><br />
    <span style="COLOR: #0600ff">if</span><span style="COLOR: #000000">(</span>dataSource <span style="COLOR: #008000">!=</span><span style="COLOR: #0600ff">null</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />
        <span style="COLOR: #ff0000">bool</span> fieldInfoSet <span style="COLOR: #008000">=</span> false<span style="COLOR: #008000">;</span><br />
        <span style="COLOR: #ff0000">bool</span> dataTextFormatStringSet <span style="COLOR: #008000">=</span> false<span style="COLOR: #008000">;</span><br /><br />
        <span style="COLOR: #008080; FONT-STYLE: italic">// checks
if we have to clear the existing items</span><br />
        <span style="COLOR: #0600ff">if</span><span style="COLOR: #000000">(</span><span style="COLOR: #008000">!</span>ctrl.<span style="COLOR: #0000ff">AppendDataBoundItems</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />
            ctrl.<span style="COLOR: #0000ff">Items</span>.<span style="COLOR: #0000ff">Clear</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span><span style="COLOR: #008000">;</span><br />
        <span style="COLOR: #000000">}</span><br /><br />
        <span style="COLOR: #008080; FONT-STYLE: italic">// if
the data source is a collection, sets the capacity</span><br />
        ICollection soureceCollection <span style="COLOR: #008000">=</span> dataSource <span style="COLOR: #0600ff">as</span> ICollection<span style="COLOR: #008000">;</span><br />
        <span style="COLOR: #0600ff">if</span><span style="COLOR: #000000">(</span>soureceCollection <span style="COLOR: #008000">!=</span><span style="COLOR: #0600ff">null</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />
            ctrl.<span style="COLOR: #0000ff">Items</span>.<span style="COLOR: #0000ff">Capacity</span><span style="COLOR: #008000">=</span> soureceCollection.<span style="COLOR: #0000ff">Count</span><span style="COLOR: #008000">+</span> ctrl.<span style="COLOR: #0000ff">Items</span>.<span style="COLOR: #0000ff">Count</span><span style="COLOR: #008000">;</span><br />
        <span style="COLOR: #000000">}</span><br /><br />
        <span style="COLOR: #008080; FONT-STYLE: italic">// save
if the data text field of data value field has been set</span><br />
        <span style="COLOR: #0600ff">if</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">(</span>ctrl.<span style="COLOR: #0000ff">DataTextField</span>.<span style="COLOR: #0000ff">Length</span><span style="COLOR: #008000">!=</span><span style="COLOR: #ff0000">0</span><span style="COLOR: #000000">)</span><span style="COLOR: #008000">||</span><span style="COLOR: #000000">(</span>ctrl.<span style="COLOR: #0000ff">DataValueField</span>.<span style="COLOR: #0000ff">Length</span><span style="COLOR: #008000">!=</span><span style="COLOR: #ff0000">0</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />
            fieldInfoSet <span style="COLOR: #008000">=</span> true<span style="COLOR: #008000">;</span><br />
        <span style="COLOR: #000000">}</span><br /><br />
        <span style="COLOR: #008080; FONT-STYLE: italic">// save
if the data text format string has been set</span><br />
        <span style="COLOR: #0600ff">if</span><span style="COLOR: #000000">(</span>ctrl.<span style="COLOR: #0000ff">DataTextFormatString</span>.<span style="COLOR: #0000ff">Length</span><span style="COLOR: #008000">!=</span><span style="COLOR: #ff0000">0</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />
            dataTextFormatStringSet <span style="COLOR: #008000">=</span> true<span style="COLOR: #008000">;</span><br />
        <span style="COLOR: #000000">}</span><br /><br />
        <span style="COLOR: #008080; FONT-STYLE: italic">// iterates
through the data source creating the ListItems</span><br />
        <span style="COLOR: #0600ff">foreach</span><span style="COLOR: #000000">(</span><span style="COLOR: #ff0000">object</span> obj <span style="COLOR: #0600ff">in</span> dataSource<span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />
            ListItem item <span style="COLOR: #008000">=</span><a style="COLOR: #000060" href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="COLOR: #008000">new</span></a> ListItem<span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span><span style="COLOR: #008000">;</span><br /><br />
            <span style="COLOR: #0600ff">if</span><span style="COLOR: #000000">(</span>fieldInfoSet<span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />
                <span style="COLOR: #0600ff">if</span><span style="COLOR: #000000">(</span>ctrl.<span style="COLOR: #0000ff">DataTextField</span>.<span style="COLOR: #0000ff">Length</span><span style="COLOR: #008000">&gt;</span><span style="COLOR: #ff0000">0</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />
                    <span style="COLOR: #0600ff">if</span><span style="COLOR: #000000">(</span>ctrl.<span style="COLOR: #0000ff">DataTextField</span>.<span style="COLOR: #0000ff">IndexOf</span><span style="COLOR: #000000">(</span><span style="COLOR: #666666">','</span><span style="COLOR: #000000">)</span><span style="COLOR: #008000">==</span><span style="COLOR: #008000">-</span><span style="COLOR: #ff0000">1</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />
                       
item.<span style="COLOR: #0000ff">Text</span><span style="COLOR: #008000">=</span> DataBinder.<span style="COLOR: #0000ff">Eval</span><span style="COLOR: #000000">(</span>obj,
ctrl.<span style="COLOR: #0000ff">DataTextField</span>, ctrl.<span style="COLOR: #0000ff">DataTextFormatString</span><span style="COLOR: #000000">)</span><span style="COLOR: #008000">;</span><br />
                    <span style="COLOR: #000000">}</span><span style="COLOR: #0600ff">else</span><span style="COLOR: #000000">{</span><br />
                        <span style="COLOR: #008080; FONT-STYLE: italic">//
if the DataTextField property has a list of fields, get them to create the text of
the item</span><br />
                        <span style="COLOR: #ff0000">string</span><span style="COLOR: #000000">[</span><span style="COLOR: #000000">]</span> fields <span style="COLOR: #008000">=</span> ctrl.<span style="COLOR: #0000ff">DataTextField</span>.<span style="COLOR: #0000ff">Split</span><span style="COLOR: #000000">(</span><a style="COLOR: #000060" href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="COLOR: #008000">new</span></a><span style="COLOR: #ff0000">string</span><span style="COLOR: #000000">[</span><span style="COLOR: #000000">]</span><span style="COLOR: #000000">{</span><span style="COLOR: #666666">","</span><span style="COLOR: #000000">}</span>,
StringSplitOptions.<span style="COLOR: #0000ff">RemoveEmptyEntries</span><span style="COLOR: #000000">)</span><span style="COLOR: #008000">;</span><br />
                        <span style="COLOR: #ff0000">object</span><span style="COLOR: #000000">[</span><span style="COLOR: #000000">]</span> values <span style="COLOR: #008000">=</span><a style="COLOR: #000060" href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="COLOR: #008000">new</span></a><span style="COLOR: #ff0000">object</span><span style="COLOR: #000000">[</span>fields.<span style="COLOR: #0000ff">Length</span><span style="COLOR: #000000">]</span><span style="COLOR: #008000">;</span><br /><br />
                        <span style="COLOR: #0600ff">for</span><span style="COLOR: #000000">(</span><span style="COLOR: #ff0000">int</span> i <span style="COLOR: #008000">=</span><span style="COLOR: #ff0000">0</span><span style="COLOR: #008000">;</span> i <span style="COLOR: #008000">&lt;</span> fields.<span style="COLOR: #0000ff">Length</span><span style="COLOR: #008000">;</span> i<span style="COLOR: #008000">++</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />
                       
    <span style="COLOR: #ff0000">string</span> field <span style="COLOR: #008000">=</span> fields<span style="COLOR: #000000">[</span>i<span style="COLOR: #000000">]</span><span style="COLOR: #008000">;</span><br />
                       
    values<span style="COLOR: #000000">[</span>i<span style="COLOR: #000000">]</span><span style="COLOR: #008000">=</span> DataBinder.<span style="COLOR: #0000ff">Eval</span><span style="COLOR: #000000">(</span>obj,
field<span style="COLOR: #000000">)</span><span style="COLOR: #008000">;</span><br />
                        <span style="COLOR: #000000">}</span><br /><br />
                       
item.<span style="COLOR: #0000ff">Text</span><span style="COLOR: #008000">=</span><span style="COLOR: #ff0000">String</span>.<span style="COLOR: #0000ff">Format</span><span style="COLOR: #000000">(</span>ctrl.<span style="COLOR: #0000ff">DataTextFormatString</span>,
values<span style="COLOR: #000000">)</span><span style="COLOR: #008000">;</span><br />
                    <span style="COLOR: #000000">}</span><br />
                <span style="COLOR: #000000">}</span><br />
                <span style="COLOR: #0600ff">if</span><span style="COLOR: #000000">(</span>ctrl.<span style="COLOR: #0000ff">DataValueField</span>.<span style="COLOR: #0000ff">Length</span><span style="COLOR: #008000">&gt;</span><span style="COLOR: #ff0000">0</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />
                    item.<span style="COLOR: #0000ff">Value</span><span style="COLOR: #008000">=</span> DataBinder.<span style="COLOR: #0000ff">Eval</span><span style="COLOR: #000000">(</span>obj,
ctrl.<span style="COLOR: #0000ff">DataValueField</span>, <span style="COLOR: #0600ff">null</span><span style="COLOR: #000000">)</span><span style="COLOR: #008000">;</span><br />
                <span style="COLOR: #000000">}</span><br />
            <span style="COLOR: #000000">}</span><span style="COLOR: #0600ff">else</span><span style="COLOR: #000000">{</span><br />
                <span style="COLOR: #0600ff">if</span><span style="COLOR: #000000">(</span>dataTextFormatStringSet<span style="COLOR: #000000">)</span><span style="COLOR: #000000">{</span><br />
                    item.<span style="COLOR: #0000ff">Text</span><span style="COLOR: #008000">=</span><span style="COLOR: #ff0000">string</span>.<span style="COLOR: #0000ff">Format</span><span style="COLOR: #000000">(</span>CultureInfo.<span style="COLOR: #0000ff">CurrentCulture</span>,
ctrl.<span style="COLOR: #0000ff">DataTextFormatString</span>, <a style="COLOR: #000060" href="http://www.google.com/search?q=new+msdn.microsoft.com"><span style="COLOR: #008000">new</span></a><span style="COLOR: #ff0000">object</span><span style="COLOR: #000000">[</span><span style="COLOR: #000000">]</span><span style="COLOR: #000000">{</span> obj <span style="COLOR: #000000">}</span><span style="COLOR: #000000">)</span><span style="COLOR: #008000">;</span><br />
                <span style="COLOR: #000000">}</span><span style="COLOR: #0600ff">else</span><span style="COLOR: #000000">{</span><br />
                    item.<span style="COLOR: #0000ff">Text</span><span style="COLOR: #008000">=</span> obj.<span style="COLOR: #0000ff">ToString</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span><span style="COLOR: #008000">;</span><br />
                <span style="COLOR: #000000">}</span><br />
                item.<span style="COLOR: #0000ff">Value</span><span style="COLOR: #008000">=</span> obj.<span style="COLOR: #0000ff">ToString</span><span style="COLOR: #000000">(</span><span style="COLOR: #000000">)</span><span style="COLOR: #008000">;</span><br />
            <span style="COLOR: #000000">}</span><br />
            
<br />
            ctrl.<span style="COLOR: #0000ff">Items</span>.<span style="COLOR: #0000ff">Add</span><span style="COLOR: #000000">(</span>item<span style="COLOR: #000000">)</span><span style="COLOR: #008000">;</span><br />
        <span style="COLOR: #000000">}</span><br />
    <span style="COLOR: #000000">}</span><br /><span style="COLOR: #000000">}</span></div>
        <p>
 
</p>
        <p>
As we need to call this data binding code instead of the one from ListControl I needed
to subclass all controls that inherit from ListControl in order to fix them. So now
I have BulletedListEx, CheckBoxListEx, DropDownListEx, ListBoxEx and RadioButtonListEx.
</p>
        <p>
I have created a simple example showing how to use them. Imagine that an Item can
be supplied by a set of suppliers, and each supplier sells the item with a different
price. The following image shows the properties of the 3 entities of the sample:
</p>
        <p>
          <img src="http://www.manuelabadia.com/blog/content/binary/listcontrolex_sample.png" border="0" />
        </p>
        <p>
I have created a web page with a DropDownList with some items, and when you select
an item in the DropDownList you will see a ListBox with the all suppliers of that
item with the associated price for the item. Notice how I show the Id and the Name
in the DropDownList and how I show the price, supplier Id and supplier name in the
ListBox:
</p>
        <p>
          <img src="http://www.manuelabadia.com/blog/content/binary/listcontrolex_sample2.png" border="0" />
        </p>
        <p>
The ASPX of the page follows:
</p>
        <div class="xml" style="BORDER-RIGHT: #d0d0d0 1px solid; BORDER-TOP: #d0d0d0 1px solid; BORDER-LEFT: #d0d0d0 1px solid; COLOR: #006; BORDER-BOTTOM: #d0d0d0 1px solid; FONT-FAMILY: monospace; BACKGROUND-COLOR: #f0f0f0">
          <span style="COLOR: #009900">
            <span style="FONT-WEIGHT: bold; COLOR: #000000">&lt;body<span style="FONT-WEIGHT: bold; COLOR: #000000">&gt;</span></span>
          </span>
          <br />
    <span style="COLOR: #009900"><span style="FONT-WEIGHT: bold; COLOR: #000000">&lt;form</span><span style="COLOR: #000066">id</span>=<span style="COLOR: #ff0000">"form1"</span><span style="COLOR: #000066">runat</span>=<span style="COLOR: #ff0000">"server"</span><span style="FONT-WEIGHT: bold; COLOR: #000000">&gt;</span></span><br />
    <span style="COLOR: #009900"><span style="FONT-WEIGHT: bold; COLOR: #000000">&lt;div<span style="FONT-WEIGHT: bold; COLOR: #000000">&gt;</span></span></span><br />
    <span style="COLOR: #009900"><span style="FONT-WEIGHT: bold; COLOR: #000000">&lt;/div<span style="FONT-WEIGHT: bold; COLOR: #000000">&gt;</span></span></span><br />
        Choose an item to see the suppliers:<span style="COLOR: #009900"><span style="FONT-WEIGHT: bold; COLOR: #000000">&lt;br</span><span style="FONT-WEIGHT: bold; COLOR: #000000">/&gt;</span></span><br />
        Items:<span style="COLOR: #009900"><span style="FONT-WEIGHT: bold; COLOR: #000000">&lt;br</span><span style="FONT-WEIGHT: bold; COLOR: #000000">/&gt;</span></span><br />
        <span style="COLOR: #009900"><span style="FONT-WEIGHT: bold; COLOR: #000000">&lt;manu:DropDownListEx</span><span style="COLOR: #000066">ID</span>=<span style="COLOR: #ff0000">"DropDownListEx1"</span><span style="COLOR: #000066">runat</span>=<span style="COLOR: #ff0000">"server"</span><span style="COLOR: #000066">AutoPostBack</span>=<span style="COLOR: #ff0000">"True"</span><span style="COLOR: #000066">Width</span>=<span style="COLOR: #ff0000">"300px"</span></span><br /><span style="COLOR: #009900">            <span style="COLOR: #000066">DataTextField</span>=<span style="COLOR: #ff0000">"Id,
Name"</span></span><br /><span style="COLOR: #009900">            <span style="COLOR: #000066">DataTextFormatString</span>=<span style="COLOR: #ff0000">"[{0}]
- {1}"</span></span><br /><span style="COLOR: #009900">            <span style="COLOR: #000066">DataValueField</span>=<span style="COLOR: #ff0000">"Id"</span></span><br /><span style="COLOR: #009900">            <span style="COLOR: #000066">OnSelectedIndexChanged</span>=<span style="COLOR: #ff0000">"DropDownListEx1_SelectedIndexChanged"</span><span style="COLOR: #000066">AppendDataBoundItems</span>=<span style="COLOR: #ff0000">"True"</span><span style="FONT-WEIGHT: bold; COLOR: #000000">&gt;</span></span><br />
            <span style="COLOR: #009900"><span style="FONT-WEIGHT: bold; COLOR: #000000">&lt;asp:ListItem</span><span style="COLOR: #000066">Selected</span>=<span style="COLOR: #ff0000">"True"</span><span style="COLOR: #000066">Value</span>=<span style="COLOR: #ff0000">"0"</span><span style="FONT-WEIGHT: bold; COLOR: #000000">&gt;</span></span>Select
an Item<span style="COLOR: #009900"><span style="FONT-WEIGHT: bold; COLOR: #000000">&lt;/asp:ListItem<span style="FONT-WEIGHT: bold; COLOR: #000000">&gt;</span></span></span><br />
        <span style="COLOR: #009900"><span style="FONT-WEIGHT: bold; COLOR: #000000">&lt;/manu:DropDownListEx<span style="FONT-WEIGHT: bold; COLOR: #000000">&gt;</span></span><span style="FONT-WEIGHT: bold; COLOR: #000000">&lt;br</span><span style="FONT-WEIGHT: bold; COLOR: #000000">/&gt;</span></span><br />
        
<br />
        Price and suppliers:<span style="COLOR: #009900"><span style="FONT-WEIGHT: bold; COLOR: #000000">&lt;br</span><span style="FONT-WEIGHT: bold; COLOR: #000000">/&gt;</span></span><br />
        
<br />
        <span style="COLOR: #009900"><span style="FONT-WEIGHT: bold; COLOR: #000000">&lt;manu:ListBoxEx</span><span style="COLOR: #000066">ID</span>=<span style="COLOR: #ff0000">"ListBoxEx1"</span><span style="COLOR: #000066">runat</span>=<span style="COLOR: #ff0000">"server"</span><span style="COLOR: #000066">Width</span>=<span style="COLOR: #ff0000">"300px"</span></span><br /><span style="COLOR: #009900">            <span style="COLOR: #000066">DataTextField</span>=<span style="COLOR: #ff0000">"Price,
Supplier.Id, Supplier.Name"</span></span><br /><span style="COLOR: #009900">            <span style="COLOR: #000066">DataTextFormatString</span>=<span style="COLOR: #ff0000">"{0}
- [{1}] {2}"</span></span><br /><span style="COLOR: #009900">            <span style="COLOR: #000066">DataValueField</span>=<span style="COLOR: #ff0000">"Supplier.Id"</span><span style="FONT-WEIGHT: bold; COLOR: #000000">&gt;</span></span><br />
        <span style="COLOR: #009900"><span style="FONT-WEIGHT: bold; COLOR: #000000">&lt;/manu:ListBoxEx<span style="FONT-WEIGHT: bold; COLOR: #000000">&gt;</span></span></span><br />
    <span style="COLOR: #009900"><span style="FONT-WEIGHT: bold; COLOR: #000000">&lt;/form<span style="FONT-WEIGHT: bold; COLOR: #000000">&gt;</span></span></span><br /><span style="COLOR: #009900"><span style="FONT-WEIGHT: bold; COLOR: #000000">&lt;/body<span style="FONT-WEIGHT: bold; COLOR: #000000">&gt;</span></span></span></div>
        <p>
 
</p>
        <p>
As you can see, the solution is really clean and elegant, and backward compatible
with the current controls that inherit from ListControl.
</p>
        <p>
That’s all for now,<br />
Merry christmas!
</p>
        <p>
          <a href="http://www.manuelabadia.com/blog/content/binary/ListControlsEx_bin.zip">ListControlsEx_bin.zip
(6.53 KB)</a>
        </p>
        <a href="http://www.manuelabadia.com/blog/content/binary/ListControlsEx_sample.zip">ListControlsEx_sample.zip
(33.75 KB)</a>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=0606d95f-56ae-4dd7-8458-69cd550fa356" />
      </body>
      <title>Binding a DropDownList to multiple properties and to nested properties</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,0606d95f-56ae-4dd7-8458-69cd550fa356.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,0606d95f-56ae-4dd7-8458-69cd550fa356.aspx</link>
      <pubDate>Mon, 22 Dec 2008 23:35:20 GMT</pubDate>
      <description>&lt;p&gt;
All controls that inherit from ListControl (BulletedList, CheckBoxList, DropDownList,
ListBox and RadioButtonList) have some annoying behavior in common: 
&lt;/p&gt;
&lt;p&gt;
You can only bind the control to a single property using the DataTextField property.
For example, if you have a Customer class with properties Id, Name, Surname, etc and
you want to show the full name of a customer in any of the ListControls, you have
several options:
&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
When you get the data from the database, return another column with the name and surname. 
&lt;li&gt;
Create a property (f.e. FullName) that returns what you want to show. 
&lt;li&gt;
Use a DataSet and add a computed column. 
&lt;li&gt;
Manually add ListItems with the appropriate values performing the data bind manually. 
&lt;li&gt;
Create a simple class that will be bound (instead of the original one) just to fix
the problem.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;
The truth is that I don’t like any of those options, all of them are hacks. 
&lt;/p&gt;
&lt;p&gt;
For nested properties you have the similar problems. You can bind to Id or Name, but
you can’t bind to Address.City or Address.Zip.
&lt;/p&gt;
&lt;p&gt;
Today I faced this problem again and I decided to investigate a more innovative solution.
The problem itself is in the controls that inherit from ListControl that are very
strict in the binding options. So I took a look of how the controls perform the binding
to see if I could do anything to overcome those limitations. At first sight I thought
I was loosing my time but after a deeper study I found that it was amazingly easy
to fix those problems in a very sleek way.
&lt;/p&gt;
&lt;p&gt;
The data binding of the controls is performed in the PerformDataBinding method. The
code at ListControl.PerformDataBinding uses DataBinder.GetPropertyValue to retrieve
the value to show in the control if you set the DataTextField property. However, DataBinder.GetPropertyValue
doesn’t handle nested properties. DataBinder.Eval is a better choice because it does
handle nested properties. So using it we solve one problem. The other problem can
be solved easily as well. As we have two properties that control how the Text of each
ListItem will be extracted and shown from the data source, with a bit more of effort
we can handle the new functionality. I have come up with a very intuitive solution:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
DataTextField allows one or more properties (that can be nested if needed) separated
by commas. 
&lt;li&gt;
DataTextFormatString can be used to control the formatting of the items, using {0},
{1}, {2}, {3}… as the value of the properties specified with DataTextField.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
The code that performs the data binding is:
&lt;/p&gt;
&lt;div class=csharp style="BORDER-RIGHT: #d0d0d0 1px solid; BORDER-TOP: #d0d0d0 1px solid; BORDER-LEFT: #d0d0d0 1px solid; COLOR: #006; BORDER-BOTTOM: #d0d0d0 1px solid; FONT-FAMILY: monospace; BACKGROUND-COLOR: #f0f0f0"&gt;&lt;span style="COLOR: #008080; FONT-STYLE: italic"&gt;///
&amp;lt;summary&amp;gt;Binds the data to the control.&amp;lt;/summary&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #008080; FONT-STYLE: italic"&gt;/// &amp;lt;param name="ctrl"&amp;gt;control
to bind.&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #008080; FONT-STYLE: italic"&gt;/// &amp;lt;param name="dataSource"&amp;gt;data
to bind to the control.&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #0600ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0600ff"&gt;static&lt;/span&gt; &lt;span style="COLOR: #0600ff"&gt;void&lt;/span&gt; PerformDataBinding&lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;ListControl
ctrl, IEnumerable dataSource&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #008080; FONT-STYLE: italic"&gt;// resets the selected
item&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; ctrl.&lt;span style="COLOR: #0000ff"&gt;SelectedIndex&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;-&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;1&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; ctrl.&lt;span style="COLOR: #0000ff"&gt;SelectedValue&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; null&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0600ff"&gt;if&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;dataSource &lt;span style="COLOR: #008000"&gt;!=&lt;/span&gt; &lt;span style="COLOR: #0600ff"&gt;null&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #ff0000"&gt;bool&lt;/span&gt; fieldInfoSet &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; false&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #ff0000"&gt;bool&lt;/span&gt; dataTextFormatStringSet &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; false&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #008080; FONT-STYLE: italic"&gt;// checks
if we have to clear the existing items&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0600ff"&gt;if&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;!&lt;/span&gt;ctrl.&lt;span style="COLOR: #0000ff"&gt;AppendDataBoundItems&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ctrl.&lt;span style="COLOR: #0000ff"&gt;Items&lt;/span&gt;.&lt;span style="COLOR: #0000ff"&gt;Clear&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #008080; FONT-STYLE: italic"&gt;// if
the data source is a collection, sets the capacity&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ICollection soureceCollection &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; dataSource &lt;span style="COLOR: #0600ff"&gt;as&lt;/span&gt; ICollection&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0600ff"&gt;if&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;soureceCollection &lt;span style="COLOR: #008000"&gt;!=&lt;/span&gt; &lt;span style="COLOR: #0600ff"&gt;null&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ctrl.&lt;span style="COLOR: #0000ff"&gt;Items&lt;/span&gt;.&lt;span style="COLOR: #0000ff"&gt;Capacity&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; soureceCollection.&lt;span style="COLOR: #0000ff"&gt;Count&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;+&lt;/span&gt; ctrl.&lt;span style="COLOR: #0000ff"&gt;Items&lt;/span&gt;.&lt;span style="COLOR: #0000ff"&gt;Count&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #008080; FONT-STYLE: italic"&gt;// save
if the data text field of data value field has been set&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0600ff"&gt;if&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;ctrl.&lt;span style="COLOR: #0000ff"&gt;DataTextField&lt;/span&gt;.&lt;span style="COLOR: #0000ff"&gt;Length&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;!=&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;0&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;||&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;ctrl.&lt;span style="COLOR: #0000ff"&gt;DataValueField&lt;/span&gt;.&lt;span style="COLOR: #0000ff"&gt;Length&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;!=&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;0&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; fieldInfoSet &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; true&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #008080; FONT-STYLE: italic"&gt;// save
if the data text format string has been set&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0600ff"&gt;if&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;ctrl.&lt;span style="COLOR: #0000ff"&gt;DataTextFormatString&lt;/span&gt;.&lt;span style="COLOR: #0000ff"&gt;Length&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;!=&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;0&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; dataTextFormatStringSet &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; true&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #008080; FONT-STYLE: italic"&gt;// iterates
through the data source creating the ListItems&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0600ff"&gt;foreach&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;object&lt;/span&gt; obj &lt;span style="COLOR: #0600ff"&gt;in&lt;/span&gt; dataSource&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ListItem item &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; &lt;a style="COLOR: #000060" href="http://www.google.com/search?q=new+msdn.microsoft.com"&gt;&lt;span style="COLOR: #008000"&gt;new&lt;/span&gt;&lt;/a&gt; ListItem&lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0600ff"&gt;if&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;fieldInfoSet&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0600ff"&gt;if&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;ctrl.&lt;span style="COLOR: #0000ff"&gt;DataTextField&lt;/span&gt;.&lt;span style="COLOR: #0000ff"&gt;Length&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;&amp;gt;&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;0&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0600ff"&gt;if&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;ctrl.&lt;span style="COLOR: #0000ff"&gt;DataTextField&lt;/span&gt;.&lt;span style="COLOR: #0000ff"&gt;IndexOf&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;&lt;span style="COLOR: #666666"&gt;','&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;==&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;-&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;1&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
item.&lt;span style="COLOR: #0000ff"&gt;Text&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; DataBinder.&lt;span style="COLOR: #0000ff"&gt;Eval&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;obj,
ctrl.&lt;span style="COLOR: #0000ff"&gt;DataTextField&lt;/span&gt;, ctrl.&lt;span style="COLOR: #0000ff"&gt;DataTextFormatString&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt; &lt;span style="COLOR: #0600ff"&gt;else&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #008080; FONT-STYLE: italic"&gt;//
if the DataTextField property has a list of fields, get them to create the text of
the item&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #ff0000"&gt;string&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;[&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;]&lt;/span&gt; fields &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; ctrl.&lt;span style="COLOR: #0000ff"&gt;DataTextField&lt;/span&gt;.&lt;span style="COLOR: #0000ff"&gt;Split&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;&lt;a style="COLOR: #000060" href="http://www.google.com/search?q=new+msdn.microsoft.com"&gt;&lt;span style="COLOR: #008000"&gt;new&lt;/span&gt;&lt;/a&gt; &lt;span style="COLOR: #ff0000"&gt;string&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;[&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;]&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt; &lt;span style="COLOR: #666666"&gt;","&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;,
StringSplitOptions.&lt;span style="COLOR: #0000ff"&gt;RemoveEmptyEntries&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #ff0000"&gt;object&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;[&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;]&lt;/span&gt; values &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; &lt;a style="COLOR: #000060" href="http://www.google.com/search?q=new+msdn.microsoft.com"&gt;&lt;span style="COLOR: #008000"&gt;new&lt;/span&gt;&lt;/a&gt; &lt;span style="COLOR: #ff0000"&gt;object&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;[&lt;/span&gt;fields.&lt;span style="COLOR: #0000ff"&gt;Length&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;]&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0600ff"&gt;for&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;int&lt;/span&gt; i &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;0&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt; i &lt;span style="COLOR: #008000"&gt;&amp;lt;&lt;/span&gt; fields.&lt;span style="COLOR: #0000ff"&gt;Length&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt; i&lt;span style="COLOR: #008000"&gt;++&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #ff0000"&gt;string&lt;/span&gt; field &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; fields&lt;span style="COLOR: #000000"&gt;[&lt;/span&gt;i&lt;span style="COLOR: #000000"&gt;]&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
&amp;nbsp; &amp;nbsp; values&lt;span style="COLOR: #000000"&gt;[&lt;/span&gt;i&lt;span style="COLOR: #000000"&gt;]&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; DataBinder.&lt;span style="COLOR: #0000ff"&gt;Eval&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;obj,
field&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
item.&lt;span style="COLOR: #0000ff"&gt;Text&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;String&lt;/span&gt;.&lt;span style="COLOR: #0000ff"&gt;Format&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;ctrl.&lt;span style="COLOR: #0000ff"&gt;DataTextFormatString&lt;/span&gt;,
values&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0600ff"&gt;if&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;ctrl.&lt;span style="COLOR: #0000ff"&gt;DataValueField&lt;/span&gt;.&lt;span style="COLOR: #0000ff"&gt;Length&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;&amp;gt;&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;0&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; item.&lt;span style="COLOR: #0000ff"&gt;Value&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; DataBinder.&lt;span style="COLOR: #0000ff"&gt;Eval&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;obj,
ctrl.&lt;span style="COLOR: #0000ff"&gt;DataValueField&lt;/span&gt;, &lt;span style="COLOR: #0600ff"&gt;null&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt; &lt;span style="COLOR: #0600ff"&gt;else&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0600ff"&gt;if&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;dataTextFormatStringSet&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; item.&lt;span style="COLOR: #0000ff"&gt;Text&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;string&lt;/span&gt;.&lt;span style="COLOR: #0000ff"&gt;Format&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;CultureInfo.&lt;span style="COLOR: #0000ff"&gt;CurrentCulture&lt;/span&gt;,
ctrl.&lt;span style="COLOR: #0000ff"&gt;DataTextFormatString&lt;/span&gt;, &lt;a style="COLOR: #000060" href="http://www.google.com/search?q=new+msdn.microsoft.com"&gt;&lt;span style="COLOR: #008000"&gt;new&lt;/span&gt;&lt;/a&gt; &lt;span style="COLOR: #ff0000"&gt;object&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;[&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;]&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt; obj &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt; &lt;span style="COLOR: #0600ff"&gt;else&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; item.&lt;span style="COLOR: #0000ff"&gt;Text&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; obj.&lt;span style="COLOR: #0000ff"&gt;ToString&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; item.&lt;span style="COLOR: #0000ff"&gt;Value&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; obj.&lt;span style="COLOR: #0000ff"&gt;ToString&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ctrl.&lt;span style="COLOR: #0000ff"&gt;Items&lt;/span&gt;.&lt;span style="COLOR: #0000ff"&gt;Add&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;item&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
As we need to call this data binding code instead of the one from ListControl I needed
to subclass all controls that inherit from ListControl in order to fix them. So now
I have BulletedListEx, CheckBoxListEx, DropDownListEx, ListBoxEx and RadioButtonListEx.
&lt;/p&gt;
&lt;p&gt;
I have created a simple example showing how to use them. Imagine that an Item can
be supplied by a set of suppliers, and each supplier sells the item with a different
price. The following image shows the properties of the 3 entities of the sample:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/listcontrolex_sample.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
I have created a web page with a DropDownList with some items, and when you select
an item in the DropDownList you will see a ListBox with the all suppliers of that
item with the associated price for the item. Notice how I show the Id and the Name
in the DropDownList and how I show the price, supplier Id and supplier name in the
ListBox:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/listcontrolex_sample2.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
The ASPX of the page follows:
&lt;/p&gt;
&lt;div class=xml style="BORDER-RIGHT: #d0d0d0 1px solid; BORDER-TOP: #d0d0d0 1px solid; BORDER-LEFT: #d0d0d0 1px solid; COLOR: #006; BORDER-BOTTOM: #d0d0d0 1px solid; FONT-FAMILY: monospace; BACKGROUND-COLOR: #f0f0f0"&gt;&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;body&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;form&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;id&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"form1"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;runat&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"server"&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;div&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/div&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Choose an item to see the suppliers:&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;br&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Items:&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;br&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;manu:DropDownListEx&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"DropDownListEx1"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;runat&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"server"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;AutoPostBack&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"True"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;Width&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"300px"&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000066"&gt;DataTextField&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"Id,
Name"&lt;/span&gt; &lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000066"&gt;DataTextFormatString&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"[{0}]
- {1}"&lt;/span&gt; &lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000066"&gt;DataValueField&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"Id"&lt;/span&gt; &lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000066"&gt;OnSelectedIndexChanged&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"DropDownListEx1_SelectedIndexChanged"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;AppendDataBoundItems&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"True"&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;asp:ListItem&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;Selected&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"True"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;Value&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"0"&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;Select
an Item&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/asp:ListItem&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/manu:DropDownListEx&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;br&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Price and suppliers:&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;br&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;manu:ListBoxEx&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"ListBoxEx1"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;runat&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"server"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;Width&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"300px"&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000066"&gt;DataTextField&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"Price,
Supplier.Id, Supplier.Name"&lt;/span&gt; &lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000066"&gt;DataTextFormatString&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"{0}
- [{1}] {2}"&lt;/span&gt; &lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000066"&gt;DataValueField&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"Supplier.Id"&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/manu:ListBoxEx&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/form&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/body&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
As you can see, the solution is really clean and elegant, and backward compatible
with the current controls that inherit from ListControl.
&lt;/p&gt;
&lt;p&gt;
That’s all for now,&lt;br&gt;
Merry christmas!
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.manuelabadia.com/blog/content/binary/ListControlsEx_bin.zip"&gt;ListControlsEx_bin.zip
(6.53 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;a href="http://www.manuelabadia.com/blog/content/binary/ListControlsEx_sample.zip"&gt;ListControlsEx_sample.zip
(33.75 KB)&lt;/a&gt;&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=0606d95f-56ae-4dd7-8458-69cd550fa356" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,0606d95f-56ae-4dd7-8458-69cd550fa356.aspx</comments>
      <category>ASP.NET;Microsoft .NET Framework</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=7924eaf8-b406-43af-9444-b816f6dfa246</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,7924eaf8-b406-43af-9444-b816f6dfa246.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,7924eaf8-b406-43af-9444-b816f6dfa246.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=7924eaf8-b406-43af-9444-b816f6dfa246</wfw:commentRss>
      <slash:comments>12</slash:comments>
      <title>Search Engine Optimization - Moving View State to the bottom of the page</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,7924eaf8-b406-43af-9444-b816f6dfa246.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,7924eaf8-b406-43af-9444-b816f6dfa246.aspx</link>
      <pubDate>Thu, 04 Dec 2008 19:26:16 GMT</pubDate>
      <description>&lt;p&gt;
One of the greatest problems when trying to optimize an ASP.NET page to be more search
engine friendly is the view state hidden field. Most search engines give more score
to the content of the firsts thousands of bytes of the document so if your first 2
KB are view state junk your pages are penalized. So the goal here is to move the view
state data as down as possible. 
&lt;/p&gt;
&lt;p&gt;
I have seen some approaches to solve this problem rewriting the final HTML code of
the response. While this approach works I think that it wastes some precious processor
cycles that can be used to do other things. So I needed a way to do the same thing
without wasting that CPU time. After some large reflector sessions I found a way to
do it. My method uses the ASP.NET Control Adapter Architecture. 
&lt;/p&gt;
&lt;p&gt;
A control adapter is a class that can be used to control the HTML generated by the
control it adapts. Since the Page class is the responsible of rendering the view state
hidden field (Page.BeginFormRender calls Page.RenderViewStateFields), an adapter for
the Page is needed. However, the view state hidden field plays a key role in the ASP.NET
infrastructure (for example, the Page.IsPostBack property checks if the view state
hidden field has been posted) and it is difficult to modify the associated HTML. 
&lt;/p&gt;
&lt;p&gt;
A PageAdapter has a method called GetStatePersister() that returns an object that
inherits from PageStatePersister. The PageStatePersister is called when it is time
to load and save the view state. There are 2 classes that inherit from PageStatePersister:
HiddenFieldPageStatePersister and SessionPageStatePersister. The first one is the
default, which stores the view state in the hidden field called __VIEWSTATE. The second
one stores the view state in the session. So, we can easily create a custom PageStatePersister
to control the view state load and save process. The big problem is how to create
the hidden view state field before the closing form tag while being a fully transparent
solution. After some tries I came up with a solution that I was happy with. 
&lt;/p&gt;
&lt;p&gt;
I realized that it was impossible to completely remove the view state hidden field
from the top of the page, because it plays a key role in the ASP.NET infrastructure.
However, with any custom page state persister the ASP.NET infrastructure renders at
least an empty view state hidden field of only 70 bytes: 
&lt;/p&gt;
&lt;div class=html4strict style="BORDER-RIGHT: #d0d0d0 1px solid; BORDER-TOP: #d0d0d0 1px solid; BORDER-LEFT: #d0d0d0 1px solid; COLOR: #006; BORDER-BOTTOM: #d0d0d0 1px solid; FONT-FAMILY: monospace; BACKGROUND-COLOR: #f0f0f0"&gt;&lt;span style="COLOR: #009900"&gt;&amp;lt;&lt;a style="COLOR: #000060" href="http://december.com/html/4/element/input.html"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;input&lt;/span&gt;&lt;/a&gt; &lt;span style="COLOR: #000066"&gt;type&lt;/span&gt;&lt;span style="COLOR: #66cc66"&gt;=&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;"hidden"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;name&lt;/span&gt;&lt;span style="COLOR: #66cc66"&gt;=&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;"__VIEWSTATE"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;id&lt;/span&gt;&lt;span style="COLOR: #66cc66"&gt;=&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;"__VIEWSTATE"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;value&lt;/span&gt;&lt;span style="COLOR: #66cc66"&gt;=&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;""&lt;/span&gt; &lt;span style="COLOR: #66cc66"&gt;/&lt;/span&gt;&amp;gt;&lt;/span&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
My page adapter adds a hidden field to the bottom of the form called __SEOVIEWSTATE
with the actual view state data, and the only limitation that it has it is that you
can not use &lt;% %&gt;expressions directly inside the asp.net form. However, this restriction
can be easily avoided putting the &lt;% %&gt;expression in a PlaceHolder control or inside
another control. For an in-depth explanation of this limitation take a look &lt;a href="http://www.west-wind.com/WebLog/posts/6148.aspx"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
Let’s see an example of the adapter in action. The following ASP.NET page: 
&lt;/p&gt;
&lt;div class=xml style="BORDER-RIGHT: #d0d0d0 1px solid; BORDER-TOP: #d0d0d0 1px solid; BORDER-LEFT: #d0d0d0 1px solid; COLOR: #006; BORDER-BOTTOM: #d0d0d0 1px solid; FONT-FAMILY: monospace; BACKGROUND-COLOR: #f0f0f0"&gt;&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;&lt;/span&gt;%@
Page &lt;span style="COLOR: #000066"&gt;Language&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"C#"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;AutoEventWireup&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"true"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;CodeBehind&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"Default.aspx.cs"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;Inherits&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"SEOViewStateAdapterTest._Default"&lt;/span&gt; %&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #00bbdd"&gt;&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;html&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;xmlns&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"http://www.w3.org/1999/xhtml"&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;head&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;runat&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"server"&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;title&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/title&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/head&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;body&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;form&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;id&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"form1"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;runat&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"server"&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;div&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Enter a message: &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;br&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;asp:TextBox&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"txtMessage"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;runat&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"server"&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/asp:TextBox&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;br&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;asp:Button&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"bSaveMessage"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;runat&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"server"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;Text&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"Save
Message"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;onclick&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"bSaveMessage_Click"&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;br&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;asp:Label&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"lMessage"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;runat&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"server"&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/asp:Label&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;br&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;p&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Page
generated at &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;asp:PlaceHolder&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;ID&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"PlaceHolder1"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;runat&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"server"&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;&lt;/span&gt;%=
DateTime.Now.ToString&lt;span style="COLOR: #66cc66"&gt;(&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;"hh:mm
dd/MM/yyy"&lt;/span&gt;&lt;span style="COLOR: #66cc66"&gt;)&lt;/span&gt; %&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/asp:PlaceHolder&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/p&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/div&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/form&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/body&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/html&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
With the associated code: 
&lt;/p&gt;
&lt;div class=csharp style="BORDER-RIGHT: #d0d0d0 1px solid; BORDER-TOP: #d0d0d0 1px solid; BORDER-LEFT: #d0d0d0 1px solid; COLOR: #006; BORDER-BOTTOM: #d0d0d0 1px solid; FONT-FAMILY: monospace; BACKGROUND-COLOR: #f0f0f0"&gt;&lt;span style="COLOR: #0600ff"&gt;using&lt;/span&gt; &lt;span style="COLOR: #008080"&gt;System&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #0600ff"&gt;using&lt;/span&gt; &lt;span style="COLOR: #008080"&gt;System.Collections.Generic&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #0600ff"&gt;using&lt;/span&gt; &lt;span style="COLOR: #008080"&gt;System.Web&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #0600ff"&gt;using&lt;/span&gt; &lt;span style="COLOR: #008080"&gt;System.Web.UI&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #0600ff"&gt;using&lt;/span&gt; &lt;span style="COLOR: #008080"&gt;System.Web.UI.WebControls&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&lt;span style="COLOR: #0600ff"&gt;namespace&lt;/span&gt; SEOViewStateAdapterTest&lt;br&gt;
&lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0600ff"&gt;public&lt;/span&gt; &lt;span style="COLOR: #0600ff"&gt;partial&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;class&lt;/span&gt; _Default &lt;span style="COLOR: #008000"&gt;:&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;System.&lt;span style="COLOR: #0000ff"&gt;Web&lt;/span&gt;.&lt;span style="COLOR: #0000ff"&gt;UI&lt;/span&gt;&lt;/span&gt;.&lt;span style="COLOR: #0000ff"&gt;Page&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0600ff"&gt;protected&lt;/span&gt; &lt;span style="COLOR: #0600ff"&gt;void&lt;/span&gt; Page_Load&lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;object&lt;/span&gt; sender,
EventArgs e&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0600ff"&gt;if&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;!&lt;/span&gt;Page.&lt;span style="COLOR: #0000ff"&gt;IsPostBack&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ViewState&lt;span style="COLOR: #000000"&gt;[&lt;/span&gt;&lt;span style="COLOR: #666666"&gt;"previousMessage"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;]&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; txtMessage.&lt;span style="COLOR: #0000ff"&gt;Text&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #0600ff"&gt;protected&lt;/span&gt; &lt;span style="COLOR: #0600ff"&gt;void&lt;/span&gt; bSaveMessage_Click&lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;object&lt;/span&gt; sender,
EventArgs e&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;{&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; lMessage.&lt;span style="COLOR: #0000ff"&gt;Text&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; &lt;span style="COLOR: #ff0000"&gt;String&lt;/span&gt;.&lt;span style="COLOR: #0000ff"&gt;Format&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;&lt;span style="COLOR: #666666"&gt;"The
current message is '{0}'. The previous message was '{1}'"&lt;/span&gt;, txtMessage.&lt;span style="COLOR: #0000ff"&gt;Text&lt;/span&gt;, &lt;span style="COLOR: #000000"&gt;(&lt;/span&gt;&lt;span style="COLOR: #ff0000"&gt;string&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt;ViewState&lt;span style="COLOR: #000000"&gt;[&lt;/span&gt;&lt;span style="COLOR: #666666"&gt;"previousMessage"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;]&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;)&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ViewState&lt;span style="COLOR: #000000"&gt;[&lt;/span&gt;&lt;span style="COLOR: #666666"&gt;"previousMessage"&lt;/span&gt;&lt;span style="COLOR: #000000"&gt;]&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;=&lt;/span&gt; txtMessage.&lt;span style="COLOR: #0000ff"&gt;Text&lt;/span&gt;&lt;span style="COLOR: #008000"&gt;;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #000000"&gt;}&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
after a couple of postbacks, without using the adapter, the HTML looks like this: 
&lt;/p&gt;
&lt;div class=xml style="BORDER-RIGHT: #d0d0d0 1px solid; BORDER-TOP: #d0d0d0 1px solid; BORDER-LEFT: #d0d0d0 1px solid; COLOR: #006; BORDER-BOTTOM: #d0d0d0 1px solid; FONT-FAMILY: monospace; BACKGROUND-COLOR: #f0f0f0"&gt;&lt;span style="COLOR: #00bbdd"&gt;&amp;lt;!DOCTYPE
html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;html&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;xmlns&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"http://www.w3.org/1999/xhtml"&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;head&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;title&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/title&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/head&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;body&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;form&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;name&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"form1"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;method&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"post"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;action&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"Default.aspx"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;id&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"form1"&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;div&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;input&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;type&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"hidden"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;name&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"__VIEWSTATE"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;id&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"__VIEWSTATE"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;value&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"/wEPDwUJc01l[...]VwP+cfdSWI6Q=="&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/div&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;div&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;input&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;type&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"hidden"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;name&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"__EVENTVALIDATION"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;id&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"__EVENTVALIDATION"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;value&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"/wEWAwKb4uenCgK/1s7/DwKf8MMPfiUvZtKPSXk//XdxkLooz8QDI0Y="&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/div&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;div&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Enter a message: &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;br&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;input&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;name&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"txtMessage"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;type&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"text"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;value&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"Message
2"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;id&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"txtMessage"&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;br&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;input&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;type&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"submit"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;name&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"bSaveMessage"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;value&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"Save
Message"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;id&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"bSaveMessage"&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;br&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;span&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;id&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"lMessage"&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;The
current message is 'Message 2'. The previous message was 'Message 1'&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/span&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;br&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;p&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Page
generated at 08:13 04/12/2008&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/p&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/div&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/form&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/body&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/html&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
and after a couple of postbacks, using the adapter, the HTML looks like this: 
&lt;/p&gt;
&lt;div class=xml style="BORDER-RIGHT: #d0d0d0 1px solid; BORDER-TOP: #d0d0d0 1px solid; BORDER-LEFT: #d0d0d0 1px solid; COLOR: #006; BORDER-BOTTOM: #d0d0d0 1px solid; FONT-FAMILY: monospace; BACKGROUND-COLOR: #f0f0f0"&gt;&lt;span style="COLOR: #00bbdd"&gt;&amp;lt;!DOCTYPE
html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;html&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;xmlns&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"http://www.w3.org/1999/xhtml"&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;head&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;title&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/title&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/head&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;body&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;form&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;name&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"form1"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;method&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"post"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;action&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"Default.aspx"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;id&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"form1"&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;div&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;input&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;type&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"hidden"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;name&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"__VIEWSTATE"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;id&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"__VIEWSTATE"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;value&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;""&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/div&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;div&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;input&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;type&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"hidden"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;name&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"__EVENTVALIDATION"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;id&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"__EVENTVALIDATION"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;value&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"/wEWAwL+raDpAgK/1s7/DwKf8MMPyF7nqN1AbwNwFBq8OAjEAQorsyo="&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/div&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;div&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; Enter a message: &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;br&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;input&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;name&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"txtMessage"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;type&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"text"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;value&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"Message
2"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;id&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"txtMessage"&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;br&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;input&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;type&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"submit"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;name&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"bSaveMessage"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;value&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"Save
Message"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;id&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"bSaveMessage"&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;br&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;span&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;id&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"lMessage"&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;The
current message is 'Message 2'. The previous message was 'Message 1'&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/span&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;br&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;p&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;Page
generated at 08:11 04/12/2008&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/p&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/div&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;input&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;type&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"hidden"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;name&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"__SEOVIEWSTATE"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;id&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"__SEOVIEWSTATE"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;value&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"/wEPc01lc3[...]CdNY6AtgigHvU="&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/form&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/body&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/html&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
In order to use the adapter, you have to add a reference to the assembly and add a
file called SEOViewStateAdapter.browser (the name of the file does not matter. The
extension needs to be the same. Or also you could merge the contents to another file
if you already have one) to the App_Browsers folder. The content of the file should
be: 
&lt;/p&gt;
&lt;div class=xml style="BORDER-RIGHT: #d0d0d0 1px solid; BORDER-TOP: #d0d0d0 1px solid; BORDER-LEFT: #d0d0d0 1px solid; COLOR: #006; BORDER-BOTTOM: #d0d0d0 1px solid; FONT-FAMILY: monospace; BACKGROUND-COLOR: #f0f0f0"&gt;&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;browsers&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #808080; FONT-STYLE: italic"&gt;&amp;lt;!-- use the adapters
for all browsers --&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;browser&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;refID&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"Default"&lt;/span&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;controlAdapters&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #808080; FONT-STYLE: italic"&gt;&amp;lt;!--
ths adapter is used to save the view and control state at the bottom of the form so
the page is more friendly to search engines --&amp;gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;adapter&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;controlType&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"System.Web.UI.Page"&lt;/span&gt; &lt;span style="COLOR: #000066"&gt;adapterType&lt;/span&gt;=&lt;span style="COLOR: #ff0000"&gt;"Manu.Web.Adapters.SEOFriendlyViewStatePageAdapter,
SEOViewStateAdapter"&lt;/span&gt; &lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;/&amp;gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/controlAdapters&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp; &amp;nbsp; &lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/browser&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&lt;span style="COLOR: #009900"&gt;&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;lt;/browsers&lt;span style="FONT-WEIGHT: bold; COLOR: #000000"&gt;&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;
&lt;br&gt;
&amp;nbsp;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
That’s all. Enjoy!
&lt;/p&gt;
&lt;a href="http://www.manuelabadia.com/blog/content/binary/SEOViewState.zip"&gt;SEOViewState.zip
(29.67 KB)&lt;/a&gt;&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=7924eaf8-b406-43af-9444-b816f6dfa246" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,7924eaf8-b406-43af-9444-b816f6dfa246.aspx</comments>
      <category>ASP.NET;Microsoft .NET Framework;SEO</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=04e66909-e2ab-4869-8a1f-ae2348bf7e47</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,04e66909-e2ab-4869-8a1f-ae2348bf7e47.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,04e66909-e2ab-4869-8a1f-ae2348bf7e47.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=04e66909-e2ab-4869-8a1f-ae2348bf7e47</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I have been using <a href="http://www.thejoyofcode.com/Validator_Module.aspx">Josh
Twist’s XHTML validation module</a> for a while and I have added a couple of small
enhancements I have found useful:
</p>
        <ul>
          <li>
It works without internet access as I included the required DTDs as embedded resources.
I usually have internet access when I’m using it, but it is a big problem if I don’t. 
</li>
          <li>
It doesn’t validate ASP.NET trace output if it is present in the page. This is checked
using the trace configuration section. I have not found a way to know if trace output
is enabled in the current request. 
</li>
          <li>
I have added an attribute called showErrorsOnly to the validatorModule element to
avoid calling the Renderer.Render method if there isn’t any error. That way, if the
page validates successfully no message is shown. 
</li>
        </ul>
        <p>
 
</p>
        <p>
          <a href="http://www.manuelabadia.com/blog/content/binary/validator_bin.zip">Download
validator_binaries (42,78 KB)</a>
        </p>
        <p>
          <a href="http://www.manuelabadia.com/blog/content/binary/validator_src.zip">Downlaod
Validator_source code (44,04 KB)</a>
        </p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=04e66909-e2ab-4869-8a1f-ae2348bf7e47" />
      </body>
      <title>XHTML Validation Module Enhancement</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,04e66909-e2ab-4869-8a1f-ae2348bf7e47.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,04e66909-e2ab-4869-8a1f-ae2348bf7e47.aspx</link>
      <pubDate>Wed, 13 Aug 2008 23:12:04 GMT</pubDate>
      <description>&lt;p&gt;
I have been using&amp;nbsp;&lt;a href="http://www.thejoyofcode.com/Validator_Module.aspx"&gt;Josh
Twist’s XHTML validation module&lt;/a&gt; for a while and I have added a couple of small
enhancements I have found useful:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
It works without internet access as I included the required DTDs as embedded resources.
I usually have internet access when I’m using it, but it is a big problem if I don’t. 
&lt;li&gt;
It doesn’t validate ASP.NET trace output if it is present in the page. This is checked
using the trace configuration section. I have not found a way to know if trace output
is enabled in the current request. 
&lt;li&gt;
I have added an attribute called showErrorsOnly to the validatorModule element to
avoid calling the Renderer.Render method if there isn’t any error. That way, if the
page validates successfully no message is shown. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.manuelabadia.com/blog/content/binary/validator_bin.zip"&gt;Download
validator_binaries (42,78 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.manuelabadia.com/blog/content/binary/validator_src.zip"&gt;Downlaod
Validator_source code (44,04 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=04e66909-e2ab-4869-8a1f-ae2348bf7e47" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,04e66909-e2ab-4869-8a1f-ae2348bf7e47.aspx</comments>
      <category>ASP.NET;XHTML</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=a93878c1-bd98-40d1-81cb-8bbfb6f0bb63</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,a93878c1-bd98-40d1-81cb-8bbfb6f0bb63.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,a93878c1-bd98-40d1-81cb-8bbfb6f0bb63.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=a93878c1-bd98-40d1-81cb-8bbfb6f0bb63</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The changes from v1.2 to the current one (v2.0) are:
</p>
        <ul>
          <li>
Now using NHibernate 2.0.0 CR1.</li>
          <li>
Fixed a bug that caused the provider to look for the configuration settings only in
the nhibernate config section. If you configured NHibernate using the hibernate-configuration
section, it didn't work.</li>
          <li>
Fixed a bug that prevented hashed passwords to work without supplying a password answer.</li>
          <li>
Some code refactoring/clean up.</li>
          <li>
Removed all FXCop warnings.</li>
          <li>
Changed the mapping generation for the NHCustomMembershipProvider. In NHiberante 2.0.0
CR1, it is not possible to create mappings programatically as before, so now a xml
document with the mapping is created.</li>
          <li>
Fixed a bug in ChangePassword and ResetPassword methods that made the stored password
answer useless if the provider was using hashed format with password salt.</li>
        </ul>
        <p>
From some questions/emails I've got, it seems that some people aren't using
the provider the way it was designed. There is no need to modify the code in the provider
to support custom fields for your Users or Roles. I have created a sample that uses
all the fields in the membership provider and adds some custom fields to
show how the provider should be used. The sample also uses the CreateUserExWizard
control in order to create an user.
</p>
        <p>
As always, feedback is welcome. It has been tested only in SQL Server 2005. Let me
know if you try it in other databases. 
</p>
        <p>
The binaries and source code can be downloaded <a href="http://www.manuelabadia.com/blog/PermaLink,guid,3b6ccb3f-2f2a-4dcb-a414-605371a00618.aspx">here</a></p>
        <p>
 
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=a93878c1-bd98-40d1-81cb-8bbfb6f0bb63" />
      </body>
      <title>Update to my NHibernate Custom Membership and Role Providers</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,a93878c1-bd98-40d1-81cb-8bbfb6f0bb63.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,a93878c1-bd98-40d1-81cb-8bbfb6f0bb63.aspx</link>
      <pubDate>Fri, 01 Aug 2008 10:10:15 GMT</pubDate>
      <description>&lt;p&gt;
The changes from v1.2 to the current one (v2.0) are:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Now using NHibernate 2.0.0 CR1.&lt;/li&gt;
&lt;li&gt;
Fixed a bug that caused the provider to look for the configuration settings only in
the nhibernate config section. If you configured NHibernate using the hibernate-configuration
section, it didn't work.&lt;/li&gt;
&lt;li&gt;
Fixed a bug that prevented hashed passwords to work without supplying a password answer.&lt;/li&gt;
&lt;li&gt;
Some code refactoring/clean up.&lt;/li&gt;
&lt;li&gt;
Removed all FXCop warnings.&lt;/li&gt;
&lt;li&gt;
Changed the mapping generation for the NHCustomMembershipProvider. In NHiberante 2.0.0
CR1, it is not possible to create mappings programatically as before, so now a xml
document with the mapping is created.&lt;/li&gt;
&lt;li&gt;
Fixed a bug in ChangePassword and ResetPassword methods that made the stored password
answer&amp;nbsp;useless if the provider was using hashed format with password salt.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
From some&amp;nbsp;questions/emails I've got,&amp;nbsp;it seems that some people aren't using
the provider the way it was designed. There is no need to modify the code in the provider
to support custom fields for your Users or Roles. I have created a sample that uses
all the fields in the&amp;nbsp;membership&amp;nbsp;provider and adds some custom fields to
show how the provider should be used. The sample also uses the CreateUserExWizard
control in order to create an user.
&lt;/p&gt;
&lt;p&gt;
As always, feedback is welcome. It has been tested only in SQL Server 2005. Let me
know if you try it in other databases. 
&lt;/p&gt;
&lt;p&gt;
The binaries and source code can be downloaded &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,3b6ccb3f-2f2a-4dcb-a414-605371a00618.aspx"&gt;here&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=a93878c1-bd98-40d1-81cb-8bbfb6f0bb63" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,a93878c1-bd98-40d1-81cb-8bbfb6f0bb63.aspx</comments>
      <category>ASP.NET;NHibernate</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=a073bf47-5324-4884-9e2f-730fb8d78f7b</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,a073bf47-5324-4884-9e2f-730fb8d78f7b.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,a073bf47-5324-4884-9e2f-730fb8d78f7b.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=a073bf47-5324-4884-9e2f-730fb8d78f7b</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
        </p>
        <p>
One of the tools I’m using is NDepend (<a href="http://www.ndepend.com/">http://www.ndepend.com/</a>).
It is a cool application that can be used for a lot of things, as will be detailed
later. 
</p>
        <p>
To use NDepend you have to feed it with a set of assemblies. After that, it will analyze
those assemblies and their reference assemblies. If the PDBs of the assemblies are
available it will use them so more data is analyzed, although the PDBs are not needed
for NDepend to work.
</p>
        <p>
After the analysis has been completed, NDepend looks like this:
</p>
        <img src="http://www.manuelabadia.com/blog/content/binary/ndepend1.png" border="0" />
        <p>
          <br />
I have used version 1.1 of Spring.NET Framework (<a href="http://www.springframework.net/">http://www.springframework.net/</a>)
for the sample. As you can see the application has a beautiful GUI. I’ll talk a bit
about the main windows of the tool:
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
• Metrics: this window gives a graphical high level view of the project. You
can see a lot of ellipses and some of them that are made of smaller ellipses. The
big ellipses are types of the project. If a big ellipse is made of several smaller
ellipses, those smaller ellipses are the methods of the type. The types of the same
namespace are distributed in the same rectangular region, separated by a small yellow
line. The assemblies are separated by a thicker yellow line. 
</p>
          <p>
By watching this window you can get an idea of which assemblies contain more code,
which types are big, which types have a lot of methods, etc. The window was in “Method
Level”. The available levels are Assembly, Namespace, Type, Method and Field.
</p>
          <p>
• Class Browser: this is where the assemblies of the project and its referenced
assemblies are shown. You can expand the assembly up to the field level. While you
hover over an item in most windows, the Metrics window gets updated highlighting the
hovered item. 
</p>
          <p>
What it’s really cool about the Class Browser is that for the referenced assemblies,
only the namespaces, types, methods and other items that are used by the project are
shown.
</p>
          <p>
• Info: When you hover over an item the information about it is displayed here,
with some metrics if applicable. There are a lot of metrics so it can take time to
interiorize them and judge their value appropriately.
</p>
          <p>
• Dependencies: this window is a bit intimidating at first but like a lot of
things, with a bit of effort you can master it. The window displays very important
information of the dependencies in a matrix form. As in other windows, the detail
level is selectable, from the assembly level to the field level. 
</p>
          <p>
A cell can have 3 colors. Blue means that the associated item in the top header uses
the associated item in the left header. Green means that the associated item in the
left header is using the associated item in the top header. Black means a cyclic dependency.
The blue and green cells express the same dependency using opposite points of view. 
</p>
          <p>
You can see a diagram of the dependencies clicking on a cell. For example, if you
click in the cell corresponding to System.Web.Extensions and System.Web you get this:
</p>
          <img src="http://www.manuelabadia.com/blog/content/binary/BoxAndArrowGraph.PNG" border="0" />
          <p>
To read more about the theory of dependencies take a look here:
</p>
          <p>
            <a href="http://www.theserverside.net/tt/articles/showarticle.tss?id=ControllingDependencies">ttp://www.theserverside.net/tt/articles/showarticle.tss?id=ControllingDependencies</a>
          </p>
          <p>
• CQL Queries: CQL stands for Code Query Language and it is a central piece of
NDepend. Being able to ask questions about the code is great. If you like using the
Analyzer window in Reflector you’ll love this. You can create new queries and modify
the existing ones.
</p>
        </blockquote>
        <p dir="ltr">
I have presented the main NDepend windows, but the main question is: what you can
do with NDepend?
</p>
        <p dir="ltr">
There are several uses that I can think of:
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p dir="ltr">
• It is an excellent tool to check differences between different builds of an
assembly. You can use it as a diff tool, as it will show in the Class Browser which
types, methods, etc have been added, removed or changed. This information is also
available for CQL Queries, with the power that it implies.
</p>
          <p>
• It can be used to understand code. When you are thrown with code that you have
no clue about how it works you have several options to accomplish that task:
</p>
          <ol dir="ltr" style="MARGIN-RIGHT: 0px">
            <li>
Look at the source code directly. 
</li>
            <li>
Make some diagrams from the source code (for example, using View Class Diagram in
Visual Studio). 
</li>
            <li>
Use NDepend.</li>
          </ol>
          <p dir="ltr">
These methods are not exclusive, and probably you’ll use a combination of them to
understand how the code works. However, the abstraction level is higher when you use
NDepend is higher than when you use a Class Diagram (and a Class Diagram is a high
level view compared to raw source code).  I’d use NDepend to have a global vision
of the main assemblies, type most used, dependencies between namespaces, more complex
methods, etc. and then focus my attention in the most important parts of the application,
going to a lower level of detail.
</p>
          <p dir="ltr">
• It can be used in the refactoring process, to see the impact of a change, and
to keep dependencies to a minimum, in order to have a project that is easier to understand
and maintain.
</p>
          <p>
• Integrating NDepend in the software development process. IMHO this is a key
point, as using NDepend regulary will certainly improve the quality of the software
that is being developed.  NDepend can generate a report of a project. A sample
report is available here:
</p>
          <p>
            <a href="http://www.ndepend.com/SampleReports/OnNUnit/NDependReport.html">http://www.ndepend.com/SampleReports/OnNUnit/NDependReport.html</a>
          </p>
          <p>
There are a lot of sections in the report, but I’ll concentrate on the section called
“CQL Queries and Constraints”. That section is really important as it shows a list
of items that can be problematic or don’t follow the standards of your company (methods
with a lot of lines of code, very complex methods, poorly commented methods, types
or methods or properties or fields with incorrect naming conventions, etc). This way
the project leader can make periodic checks of those problems and report them to the
people that are responsible for them. 
<br />
This also allows you to know more the people you’re working with. Some developers
don’t comment code, others like to make very long methods, and others tend to write
complex logic that is difficult to understand by others. With the review of the report,
they can be instructed so the resulting code and comments is better and more uniform.
</p>
          <p>
However, there are times where a method with more than 30 lines of code is necessary.
Or a method with a cyclomatic complexity of 25 is needed. So it is up to the project
leader to review the suspicious method and inform the developers of the problem or
simply acknowledge that it is necessary. 
</p>
          <p>
Unfortunately, NDepend does not provide built in support for this level of detail
of project management. I have been told that in a future version it will provide hooks
so custom scenarios like the exposed above are fully supported.
</p>
        </blockquote>
        <p dir="ltr">
So, after what I have said about NDepend, you can be thinking, is it for me? Well,
that depends on a lot of factors. I know a lot of companies that have no interest
in achieving high quality products and that they only care about having a project
done as soon as possible. If the maintenance of that project is a nightmare, well,
that is another problem for another moment. However, there are some companies that
actually spend time and effort to produce excellent products, so they may be interested
in what NDepend can add for them.
</p>
        <p dir="ltr">
I have used NDepend in several projects that are widely used when learning about it,
and I found something curious:
</p>
        <p dir="ltr">
          <img src="http://www.manuelabadia.com/blog/content/binary/nhibernate_dependencies.png" border="0" />
        </p>
        <p dir="ltr">
The image shows that almost all of the NHibernate code has a big dependency cycle.
I wish them good luck making the transition to ASTs.
</p>
        <p dir="ltr">
          <em>To finish this post, I have to say that I have received a free professional version
of NDepend. This has not conditioned my post about it. If I think it was a useless
product I will not have posted about it.<br /></em>
        </p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=a073bf47-5324-4884-9e2f-730fb8d78f7b" />
      </body>
      <title>NDepend</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,a073bf47-5324-4884-9e2f-730fb8d78f7b.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,a073bf47-5324-4884-9e2f-730fb8d78f7b.aspx</link>
      <pubDate>Fri, 08 Feb 2008 12:22:13 GMT</pubDate>
      <description>&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
One of the tools I’m using is NDepend (&lt;a href="http://www.ndepend.com/"&gt;http://www.ndepend.com/&lt;/a&gt;).
It is a cool application that can be used for a lot of things, as will be detailed
later. 
&lt;/p&gt;
&lt;p&gt;
To use NDepend you have to feed it with a set of assemblies. After that, it will analyze
those assemblies and their reference assemblies. If the PDBs of the assemblies are
available it will use them so more data is analyzed, although the PDBs are not needed
for NDepend to work.
&lt;/p&gt;
&lt;p&gt;
After the analysis has been completed, NDepend looks like this:
&lt;/p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/ndepend1.png" border=0&gt; 
&lt;p&gt;
&lt;br&gt;
I have used version 1.1 of Spring.NET Framework (&lt;a href="http://www.springframework.net/"&gt;http://www.springframework.net/&lt;/a&gt;)
for the sample. As you can see the application has a beautiful GUI. I’ll talk a bit
about the main windows of the tool:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
•&amp;nbsp;Metrics: this window gives a graphical high level view of the project. You
can see a lot of ellipses and some of them that are made of smaller ellipses. The
big ellipses are types of the project. If a big ellipse is made of several smaller
ellipses, those smaller ellipses are the methods of the type. The types of the same
namespace are distributed in the same rectangular region, separated by a small yellow
line. The assemblies are separated by a thicker yellow line. 
&lt;/p&gt;
&lt;p&gt;
By watching this window you can get an idea of which assemblies contain more code,
which types are big, which types have a lot of methods, etc. The window was in “Method
Level”. The available levels are Assembly, Namespace, Type, Method and Field.
&lt;/p&gt;
&lt;p&gt;
•&amp;nbsp;Class Browser: this is where the assemblies of the project and its referenced
assemblies are shown. You can expand the assembly up to the field level. While you
hover over an item in most windows, the Metrics window gets updated highlighting the
hovered item. 
&lt;/p&gt;
&lt;p&gt;
What it’s really cool about the Class Browser is that for the referenced assemblies,
only the namespaces, types, methods and other items that are used by the project are
shown.
&lt;/p&gt;
&lt;p&gt;
•&amp;nbsp;Info: When you hover over an item the information about it is displayed here,
with some metrics if applicable. There are a lot of metrics so it can take time to
interiorize them and judge their value appropriately.
&lt;/p&gt;
&lt;p&gt;
•&amp;nbsp;Dependencies: this window is a bit intimidating at first but like a lot of
things, with a bit of effort you can master it. The window displays very important
information of the dependencies in a matrix form. As in other windows, the detail
level is selectable, from the assembly level to the field level. 
&lt;/p&gt;
&lt;p&gt;
A cell can have 3 colors. Blue means that the associated item in the top header uses
the associated item in the left header. Green means that the associated item in the
left header is using the associated item in the top header. Black means a cyclic dependency.
The blue and green cells express the same dependency using opposite points of view. 
&lt;/p&gt;
&lt;p&gt;
You can see a diagram of the dependencies clicking on a cell. For example, if you
click in the cell corresponding to System.Web.Extensions and System.Web you get this:
&lt;/p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/BoxAndArrowGraph.PNG" border=0&gt; 
&lt;p&gt;
To read more about the theory of dependencies take a look here:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.theserverside.net/tt/articles/showarticle.tss?id=ControllingDependencies"&gt;ttp://www.theserverside.net/tt/articles/showarticle.tss?id=ControllingDependencies&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
•&amp;nbsp;CQL Queries: CQL stands for Code Query Language and it is a central piece of
NDepend. Being able to ask questions about the code is great. If you like using the
Analyzer window in Reflector you’ll love this. You can create new queries and modify
the existing ones.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p dir=ltr&gt;
I have presented the main NDepend windows, but the main question is: what you can
do with NDepend?
&lt;/p&gt;
&lt;p dir=ltr&gt;
There are several uses that I can think of:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p dir=ltr&gt;
•&amp;nbsp;It is an excellent tool to check differences between different builds of an
assembly. You can use it as a diff tool, as it will show in the Class Browser which
types, methods, etc have been added, removed or changed. This information is also
available for CQL Queries, with the power that it implies.
&lt;/p&gt;
&lt;p&gt;
•&amp;nbsp;It can be used to understand code. When you are thrown with code that you have
no clue about how it works you have several options to accomplish that task:
&lt;/p&gt;
&lt;ol dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;li&gt;
Look at the source code directly. 
&lt;li&gt;
Make some diagrams from the source code (for example, using View Class Diagram in
Visual Studio). 
&lt;li&gt;
Use NDepend.&lt;/li&gt;
&lt;/ol&gt;
&lt;p dir=ltr&gt;
These methods are not exclusive, and probably you’ll use a combination of them to
understand how the code works. However, the abstraction level is higher when you use
NDepend is higher than when you use a Class Diagram (and a Class Diagram is a high
level view compared to raw source code).&amp;nbsp; I’d use NDepend to have a global vision
of the main assemblies, type most used, dependencies between namespaces, more complex
methods, etc. and then focus my attention in the most important parts of the application,
going to a lower level of detail.
&lt;/p&gt;
&lt;p dir=ltr&gt;
•&amp;nbsp;It can be used in the refactoring process, to see the impact of a change, and
to keep dependencies to a minimum, in order to have a project that is easier to understand
and maintain.
&lt;/p&gt;
&lt;p&gt;
•&amp;nbsp;Integrating NDepend in the software development process. IMHO this is a key
point, as using NDepend regulary will certainly improve the quality of the software
that is being developed.&amp;nbsp; NDepend can generate a report of a project. A sample
report is available here:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.ndepend.com/SampleReports/OnNUnit/NDependReport.html"&gt;http://www.ndepend.com/SampleReports/OnNUnit/NDependReport.html&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
There are a lot of sections in the report, but I’ll concentrate on the section called
“CQL Queries and Constraints”. That section is really important as it shows a list
of items that can be problematic or don’t follow the standards of your company (methods
with a lot of lines of code, very complex methods, poorly commented methods, types
or methods or properties or fields with incorrect naming conventions, etc). This way
the project leader can make periodic checks of those problems and report them to the
people that are responsible for them. 
&lt;br&gt;
This also allows you to know more the people you’re working with. Some developers
don’t comment code, others like to make very long methods, and others tend to write
complex logic that is difficult to understand by others. With the review of the report,
they can be instructed so the resulting code and comments is better and more uniform.
&lt;/p&gt;
&lt;p&gt;
However, there are times where a method with more than 30 lines of code is necessary.
Or a method with a cyclomatic complexity of 25 is needed. So it is up to the project
leader to review the suspicious method and inform the developers of the problem or
simply acknowledge that it is necessary. 
&lt;/p&gt;
&lt;p&gt;
Unfortunately, NDepend does not provide built in support for this level of detail
of project management. I have been told that in a future version it will provide hooks
so custom scenarios like the exposed above are fully supported.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p dir=ltr&gt;
So, after what I have said about NDepend, you can be thinking, is it for me? Well,
that depends on a lot of factors. I know a lot of companies that have no interest
in achieving high quality products and that they only care about having a project
done as soon as possible. If the maintenance of that project is a nightmare, well,
that is another problem for another moment. However, there are some companies that
actually spend time and effort to produce excellent products, so they may be interested
in what NDepend can add for them.
&lt;/p&gt;
&lt;p dir=ltr&gt;
I have used NDepend in several projects that are widely used when learning about it,
and I found something curious:
&lt;/p&gt;
&lt;p dir=ltr&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/nhibernate_dependencies.png" border=0&gt;
&lt;/p&gt;
&lt;p dir=ltr&gt;
The image shows that almost all of the NHibernate code has a big dependency cycle.
I wish them good luck making the transition to ASTs.
&lt;/p&gt;
&lt;p dir=ltr&gt;
&lt;em&gt;To finish this post, I have to say that I have received a free professional version
of NDepend. This has not conditioned my post about it. If I think it was a useless
product I will not have posted about it.&lt;br&gt;
&lt;/em&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=a073bf47-5324-4884-9e2f-730fb8d78f7b" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,a073bf47-5324-4884-9e2f-730fb8d78f7b.aspx</comments>
      <category>ASP.NET;Microsoft .NET Framework;NHibernate</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=666afc3a-d84d-4412-af43-da0235210cfa</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,666afc3a-d84d-4412-af43-da0235210cfa.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,666afc3a-d84d-4412-af43-da0235210cfa.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=666afc3a-d84d-4412-af43-da0235210cfa</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One of the tools I have been using is <a href="http://www.openqa.org/selenium/">Selenium</a>.
Selenium is a test framework for web applications. Selenium is composed of 3 different
projects:
</p>
        <p>
• Selenium Core: A set of cross browser javascript classes that contain the test
framework.<br />
• Selenium IDE: A FireFox plugin that allows creation, recording and editing
of tests for Selenium.<br />
• Selenium RC: A web server and a set of classes to allow integrating Selenium
tests in test applications like MbUnit.
</p>
        <p>
To illustrate the concepts I’m going to use a sample. I have a control called ListControlMediator,
that is used to connect two DropDownList controls in order to move ListItems from
a DropDownList to the other. It can be used to reorder ListItems too. The following
image shows two DropDownLists with a ListControlMediator:
</p>
        <p>
          <img height="284" alt="listcontrolmediator1.png" src="http://www.manuelabadia.com/blog/content/binary/listcontrolmediator1.png" width="632" border="0" />
        </p>
        <p>
The identifier is shown near the controls on the page.
</p>
        <p>
The ListControlMediator can work in server side mode, performing a postback each time
a button is pressed. However, it also has a client side mode that uses javascript
to avoid postbacks. So I want to write some tests to check that the control works
properly in client and server side mode, using IE and FireFox.<br />
 <br />
The first thing will be to create a page to perform the tests, as the one shown above.
The only functionality of the page shown above is the action to perform when the “Send”
button is clicked.  When the “Send” button is clicked, the text of the items
of the ListBox2 is shown in the lResult label (separated with spaces).
</p>
        <p>
The second thing to do is to create a test of the web page. In this step, there are
two main options:
</p>
        <p>
• Create the test by hand.<br />
• Record the test with the Selenium IDE.
</p>
        <p>
I usually record the test with the Selenium IDE and then adjust it a bit. To use the
Selenium IDE just open FireFox and select Tools-&gt;Selenium IDE. Use the record button
to start recording actions:
</p>
        <p>
          <img height="446" alt="selenium_ide1.png" src="http://www.manuelabadia.com/blog/content/binary/selenium_ide1.png" width="647" border="0" />
        </p>
        <p>
For example, after some actions in the page I got the following actions recorded:
</p>
        <p>
          <img height="633" alt="selenium_ide2.png" src="http://www.manuelabadia.com/blog/content/binary/selenium_ide2.png" width="420" border="0" />
        </p>
        <p>
As you can see, an action can have up to 3 attributes: Command, Target and Value.
If you click on an action, you can select a command from the combo box. There are
a lot of commands available, but you can learn them when you need them. The reference
at the bottom of the Selenium IDE shows the help for the selected command, and the
arguments it takes (Target is the first argument and Value is the second argument).
</p>
        <p>
A cool thing about the Selenium IDE is that it adds an option in the FireFox context
menu called “Show All Available Commands”. When you right click in an element of the
page, it will show a list of the most common commands that can be applied to that
element. That is very helpful for newbies.
</p>
        <p>
After a test has been recorded, we can save it to replay it later (using File-&gt;Save
Test). As a test is not more than a list of actions, and an action can have up to
3 attributes, tests are saved as HTML pages with a table. Each row in the table is
an action, and has three columns, one per attribute of the action.
</p>
        <p>
Once you have some tests saved, you can use the Selenium core to test them. Several
tests are grouped in a “Test Suite”. A test suite is also an HTML file with a table,
where each row in the table has only one column, where a link to the test of the suite
is specified.
</p>
        <p>
To use the Selenium core you will have to copy the “core” directory of the selenium
core distribution to the root folder of your website. In the selenium core distribution,
there is also a directory called “tests” where there are a lot of tests of a test
suite. Create a directory called “tests” in the root folder of your website and copy
the TestSuite.html file found in the “tests” directory of the selenium core distribution.
Edit the TestSuite.html file, leaving only a row in the table that points to the test
saved with the Selenium IDE (copy the saved test to the “tests” directory of your
website). Some tests may not work in some browsers, so you can add that information
to the row. For example, if you add unless="browserVersion.isSafari" to some rows
and you try to run the tests using Safari, those tests won’t be executed.
</p>
        <p>
To run a test suite using the Selenium core you have to point the browser to the /core/TestRunner.html
page:
</p>
        <p>
          <img alt="selenium_core1.png" src="http://www.manuelabadia.com/blog/content/binary/selenium_core1.png" border="0" />
        </p>
        <p>
And select the test suite to run on the left. After the test suite has been selected,
the tests contained in the test suite are shown on the left. When you click on a test
the top center part of the browser shows the actions of the selected test. In the
right there are some controls to run the tests. The bottom part of the browser is
where the test will be run:
</p>
        <p>
          <img alt="selenium_core2.png" src="http://www.manuelabadia.com/blog/content/binary/selenium_core2.png" border="0" />
        </p>
        <p>
The TestRunner.html page accept some parameters to select the test suite, run the
test automatically, etc, but the truth is that we use Selenium RC we won’t need to
mess with the TestRunner anymore.
</p>
        <p>
To use Selenium RC for our web tests we don’t need to copy the core or tests from
the Selenium Core distribution.
</p>
        <p>
Selenium Remote Control (RC) is basically a web server and the ThoughtWorks.Selenium.Core.dll
assembly.
</p>
        <p>
The selenium server is used to open browser sessions and is also a proxy. When the
server opens a browser session it configures the browser to use the selenium server
as a proxy. The selenium server injects the test framework for the pages it uses,
capturing all requests to /selenium-server/ so they return stuff from the Selenium
Core, making the page under test to be able to use the Selenium Core transparently
without Javascript origin policy problems.
</p>
        <p>
The ThoughtWorks.Selenium.Core.dll contains types to interact with the Selenium Server,
so with .NET code we can create new sessions, and perform actions with it, testing
our web sites with real browsers, using our favorite testing framework (MbUnit in
my case).
</p>
        <p>
To start the Selenium Server you need to have JRE 1.5.0 or higher installed and type:
</p>
        <p>
java.exe -jar selenium-server.jar
</p>
        <p>
The server listens to port 4444 by default.
</p>
        <p>
However, to automate this I have added Assembly level SetUp and TearDown methods to
my web tests so the server is started before all the tests and shutdown after the
tests:
</p>
        <p>
          <img alt="selenium_rc2.png" src="http://www.manuelabadia.com/blog/content/binary/selenium_rc2.png" border="0" />
        </p>
        <p>
From .NET you have to use the DefaultSelenium class to create a browser session. In
my tests, I have a base class for web tests that has a SetUp and TearDown methods
that automatically open a close a browser session:
</p>
        <p>
          <img alt="selenium_rc1.png" src="http://www.manuelabadia.com/blog/content/binary/selenium_rc1.png" border="0" />
        </p>
        <p>
ServerUrl, ServerPort and BaseUrl are read from the application configuration file.
The Browser property is passed to the constructor of the base class for web tests.
</p>
        <p>
The actual test should use perform actions in the browser session that has been opened
in the SetUp method. The Selenium IDE has an option to save a test in C# format, that
converts an action to a call to the browser session object, so it can be used easily
from code.
</p>
        <p>
Let see some code of a test (don’t try to compare it with the example of the Selenium
IDE, it is different):
</p>
        <p>
          <img height="1295" alt="selenium_rc3.png" src="http://www.manuelabadia.com/blog/content/binary/selenium_rc3.png" width="679" border="0" />
        </p>
        <p>
As you can see, it is just another way to express the actions.<br />
 <br />
Some thing to clarify is the CheckPageError method. Unfortunately if an ASPX page
throws an exception, the assembly ThoughtWorks.Selenium.Core.dll does not throw that
exception and returns OK. This is because the Selenium Server requests a page and
receives a response, so it doesn’t see any problem. This is very unfortunate and I
hope it will be fixed in future releases. For now what I’m doing is to check if the
body of the page starts with “Server Error”. This works for me because my test website
doesn’t handle custom errors and the default error handling is displayed. You may
have to create your own custom CheckPageError method.
</p>
        <p>
Another thing that doesn’t work as I’d expect is the Selenium.GetSelectOptions method.
If the select element is empty, it returns a string array with one item that contains
an empty string instead of returning an empty string array. Hopefully this will be
also fixed in the future.
</p>
        <p>
Note that to be able to run the tests with Selenium RC you’ll probably need to use
IIS instead of the built in server of Visual Studio.
</p>
        <p>
I usually test my stuff in IE and FireFox. I inherit from the class where the test
methods are defined as shown here:
</p>
        <p>
          <img height="365" alt="selenium_rc4.png" src="http://www.manuelabadia.com/blog/content/binary/selenium_rc4.png" width="502" border="0" />
        </p>
        <p>
If you want to test with more browsers probably this will get ugly and you will have
to work out a better way to run the tests without inheritance.
</p>
        <p>
To test the Server Side mode in the ListControlMediator, the only required changes
to the test method is to place Selenium.WaitForPageToLoad instructions after each
click, so the Selenium Core waits for the postback to complete before continuing processing
the test.
</p>
        <p>
I hope this helps some people to enter in the world of real web tests.
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=666afc3a-d84d-4412-af43-da0235210cfa" />
      </body>
      <title>Web tests with Selenium</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,666afc3a-d84d-4412-af43-da0235210cfa.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,666afc3a-d84d-4412-af43-da0235210cfa.aspx</link>
      <pubDate>Thu, 03 Jan 2008 11:54:02 GMT</pubDate>
      <description>&lt;p&gt;
One of the tools I have been using is &lt;a href="http://www.openqa.org/selenium/"&gt;Selenium&lt;/a&gt;.
Selenium is a test framework for web applications. Selenium is composed of 3 different
projects:
&lt;/p&gt;
&lt;p&gt;
•&amp;nbsp;Selenium Core: A set of cross browser javascript classes that contain the test
framework.&lt;br&gt;
•&amp;nbsp;Selenium IDE: A FireFox plugin that allows creation, recording and editing
of tests for Selenium.&lt;br&gt;
•&amp;nbsp;Selenium RC: A web server and a set of classes to allow integrating Selenium
tests in test applications like MbUnit.
&lt;/p&gt;
&lt;p&gt;
To illustrate the concepts I’m going to use a sample. I have a control called ListControlMediator,
that is used to connect two DropDownList controls in order to move ListItems from
a DropDownList to the other. It can be used to reorder ListItems too. The following
image shows two DropDownLists with a ListControlMediator:
&lt;/p&gt;
&lt;p&gt;
&lt;img height=284 alt=listcontrolmediator1.png src="http://www.manuelabadia.com/blog/content/binary/listcontrolmediator1.png" width=632 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
The identifier is shown near the controls on the page.
&lt;/p&gt;
&lt;p&gt;
The ListControlMediator can work in server side mode, performing a postback each time
a button is pressed. However, it also has a client side mode that uses javascript
to avoid postbacks. So I want to write some tests to check that the control works
properly in client and server side mode, using IE and FireFox.&lt;br&gt;
&amp;nbsp;&lt;br&gt;
The first thing will be to create a page to perform the tests, as the one shown above.
The only functionality of the page shown above is the action to perform when the “Send”
button is clicked.&amp;nbsp; When the “Send” button is clicked, the text of the items
of the ListBox2 is shown in the lResult label (separated with spaces).
&lt;/p&gt;
&lt;p&gt;
The second thing to do is to create a test of the web page. In this step, there are
two main options:
&lt;/p&gt;
&lt;p&gt;
•&amp;nbsp;Create the test by hand.&lt;br&gt;
•&amp;nbsp;Record the test with the Selenium IDE.
&lt;/p&gt;
&lt;p&gt;
I usually record the test with the Selenium IDE and then adjust it a bit. To use the
Selenium IDE just open FireFox and select Tools-&amp;gt;Selenium IDE. Use the record button
to start recording actions:
&lt;/p&gt;
&lt;p&gt;
&lt;img height=446 alt=selenium_ide1.png src="http://www.manuelabadia.com/blog/content/binary/selenium_ide1.png" width=647 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
For example, after some actions in the page I got the following actions recorded:
&lt;/p&gt;
&lt;p&gt;
&lt;img height=633 alt=selenium_ide2.png src="http://www.manuelabadia.com/blog/content/binary/selenium_ide2.png" width=420 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
As you can see, an action can have up to 3 attributes: Command, Target and Value.
If you click on an action, you can select a command from the combo box. There are
a lot of commands available, but you can learn them when you need them. The reference
at the bottom of the Selenium IDE shows the help for the selected command, and the
arguments it takes (Target is the first argument and Value is the second argument).
&lt;/p&gt;
&lt;p&gt;
A cool thing about the Selenium IDE is that it adds an option in the FireFox context
menu called “Show All Available Commands”. When you right click in an element of the
page, it will show a list of the most common commands that can be applied to that
element. That is very helpful for newbies.
&lt;/p&gt;
&lt;p&gt;
After a test has been recorded, we can save it to replay it later (using File-&amp;gt;Save
Test). As a test is not more than a list of actions, and an action can have up to
3 attributes, tests are saved as HTML pages with a table. Each row in the table is
an action, and has three columns, one per attribute of the action.
&lt;/p&gt;
&lt;p&gt;
Once you have some tests saved, you can use the Selenium core to test them. Several
tests are grouped in a “Test Suite”. A test suite is also an HTML file with a table,
where each row in the table has only one column, where a link to the test of the suite
is specified.
&lt;/p&gt;
&lt;p&gt;
To use the Selenium core you will have to copy the “core” directory of the selenium
core distribution to the root folder of your website. In the selenium core distribution,
there is also a directory called “tests” where there are a lot of tests of a test
suite. Create a directory called “tests” in the root folder of your website and copy
the TestSuite.html file found in the “tests” directory of the selenium core distribution.
Edit the TestSuite.html file, leaving only a row in the table that points to the test
saved with the Selenium IDE (copy the saved test to the “tests” directory of your
website). Some tests may not work in some browsers, so you can add that information
to the row. For example, if you add unless="browserVersion.isSafari" to some rows
and you try to run the tests using Safari, those tests won’t be executed.
&lt;/p&gt;
&lt;p&gt;
To run a test suite using the Selenium core you have to point the browser to the /core/TestRunner.html
page:
&lt;/p&gt;
&lt;p&gt;
&lt;img alt=selenium_core1.png src="http://www.manuelabadia.com/blog/content/binary/selenium_core1.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
And select the test suite to run on the left. After the test suite has been selected,
the tests contained in the test suite are shown on the left. When you click on a test
the top center part of the browser shows the actions of the selected test. In the
right there are some controls to run the tests. The bottom part of the browser is
where the test will be run:
&lt;/p&gt;
&lt;p&gt;
&lt;img alt=selenium_core2.png src="http://www.manuelabadia.com/blog/content/binary/selenium_core2.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
The TestRunner.html page accept some parameters to select the test suite, run the
test automatically, etc, but the truth is that we use Selenium RC we won’t need to
mess with the TestRunner anymore.
&lt;/p&gt;
&lt;p&gt;
To use Selenium RC for our web tests we don’t need to copy the core or tests from
the Selenium Core distribution.
&lt;/p&gt;
&lt;p&gt;
Selenium Remote Control (RC) is basically a web server and the ThoughtWorks.Selenium.Core.dll
assembly.
&lt;/p&gt;
&lt;p&gt;
The selenium server is used to open browser sessions and is also a proxy. When the
server opens a browser session it configures the browser to use the selenium server
as a proxy. The selenium server injects the test framework for the pages it uses,
capturing all requests to /selenium-server/ so they return stuff from the Selenium
Core, making the page under test to be able to use the Selenium Core transparently
without Javascript origin policy problems.
&lt;/p&gt;
&lt;p&gt;
The ThoughtWorks.Selenium.Core.dll contains types to interact with the Selenium Server,
so with .NET code we can create new sessions, and perform actions with it, testing
our web sites with real browsers, using our favorite testing framework (MbUnit in
my case).
&lt;/p&gt;
&lt;p&gt;
To start the Selenium Server you need to have JRE 1.5.0 or higher installed and type:
&lt;/p&gt;
&lt;p&gt;
java.exe -jar selenium-server.jar
&lt;/p&gt;
&lt;p&gt;
The server listens to port 4444 by default.
&lt;/p&gt;
&lt;p&gt;
However, to automate this I have added Assembly level SetUp and TearDown methods to
my web tests so the server is started before all the tests and shutdown after the
tests:
&lt;/p&gt;
&lt;p&gt;
&lt;img alt=selenium_rc2.png src="http://www.manuelabadia.com/blog/content/binary/selenium_rc2.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
From .NET you have to use the DefaultSelenium class to create a browser session. In
my tests, I have a base class for web tests that has a SetUp and TearDown methods
that automatically open a close a browser session:
&lt;/p&gt;
&lt;p&gt;
&lt;img alt=selenium_rc1.png src="http://www.manuelabadia.com/blog/content/binary/selenium_rc1.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
ServerUrl, ServerPort and BaseUrl are read from the application configuration file.
The Browser property is passed to the constructor of the base class for web tests.
&lt;/p&gt;
&lt;p&gt;
The actual test should use perform actions in the browser session that has been opened
in the SetUp method. The Selenium IDE has an option to save a test in C# format, that
converts an action to a call to the browser session object, so it can be used easily
from code.
&lt;/p&gt;
&lt;p&gt;
Let see some code of a test (don’t try to compare it with the example of the Selenium
IDE, it is different):
&lt;/p&gt;
&lt;p&gt;
&lt;img height=1295 alt=selenium_rc3.png src="http://www.manuelabadia.com/blog/content/binary/selenium_rc3.png" width=679 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
As you can see, it is just another way to express the actions.&lt;br&gt;
&amp;nbsp;&lt;br&gt;
Some thing to clarify is the CheckPageError method. Unfortunately if an ASPX page
throws an exception, the assembly ThoughtWorks.Selenium.Core.dll does not throw that
exception and returns OK. This is because the Selenium Server requests a page and
receives a response, so it doesn’t see any problem. This is very unfortunate and I
hope it will be fixed in future releases. For now what I’m doing is to check if the
body of the page starts with “Server Error”. This works for me because my test website
doesn’t handle custom errors and the default error handling is displayed. You may
have to create your own custom CheckPageError method.
&lt;/p&gt;
&lt;p&gt;
Another thing that doesn’t work as I’d expect is the Selenium.GetSelectOptions method.
If the select element is empty, it returns a string array with one item that contains
an empty string instead of returning an empty string array. Hopefully this will be
also fixed in the future.
&lt;/p&gt;
&lt;p&gt;
Note that to be able to run the tests with Selenium RC you’ll probably need to use
IIS instead of the built in server of Visual Studio.
&lt;/p&gt;
&lt;p&gt;
I usually test my stuff in IE and FireFox. I inherit from the class where the test
methods are defined as shown here:
&lt;/p&gt;
&lt;p&gt;
&lt;img height=365 alt=selenium_rc4.png src="http://www.manuelabadia.com/blog/content/binary/selenium_rc4.png" width=502 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
If you want to test with more browsers probably this will get ugly and you will have
to work out a better way to run the tests without inheritance.
&lt;/p&gt;
&lt;p&gt;
To test the Server Side mode in the ListControlMediator, the only required changes
to the test method is to place Selenium.WaitForPageToLoad instructions after each
click, so the Selenium Core waits for the postback to complete before continuing processing
the test.
&lt;/p&gt;
&lt;p&gt;
I hope this helps some people to enter in the world of real web tests.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=666afc3a-d84d-4412-af43-da0235210cfa" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,666afc3a-d84d-4412-af43-da0235210cfa.aspx</comments>
      <category>ASP.NET;Java;JavaScript;MBUnit;Selenium;Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=1d9cf157-2c6c-4ec4-b45a-7dc724543c28</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,1d9cf157-2c6c-4ec4-b45a-7dc724543c28.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,1d9cf157-2c6c-4ec4-b45a-7dc724543c28.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=1d9cf157-2c6c-4ec4-b45a-7dc724543c28</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
If you have worked with the design time infrastructure you will know that there are
parts of it that are poorly documented.
</p>
        <p>
To complement MSDN help and internet searches you can try another source of information: <strong>patents</strong>.
</p>
        <p>
Most big companies like to patent a lot of stuff so I stumbled upon <a href="http://www.freepatentsonline.com/20050251380.html">this
patent</a> that has some good information about design time. The inventors of
the patent are:
</p>
        <ul>
          <li>
            <em>Andrew Cheng-Min Lin</em>
          </li>
          <li>
            <em>Bulusu Krishna Mohan</em>
          </li>
          <li>
            <em>Nikhil Kothari</em>
          </li>
          <li>
            <em>Simon Calvert</em>
          </li>
        </ul>
        <p>
Does any one sound familiar to you?<br /><br />
Anyway, nothing beats using reflector to figure out some of the more obscure interfaces.
Unfortunately, it is also the slowest method. 
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=1d9cf157-2c6c-4ec4-b45a-7dc724543c28" />
      </body>
      <title>Unexpected source of information</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,1d9cf157-2c6c-4ec4-b45a-7dc724543c28.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,1d9cf157-2c6c-4ec4-b45a-7dc724543c28.aspx</link>
      <pubDate>Sat, 24 Nov 2007 09:56:41 GMT</pubDate>
      <description>&lt;p&gt;
If you have worked with the design time infrastructure you will know that there are
parts of it that are poorly documented.
&lt;/p&gt;
&lt;p&gt;
To complement MSDN&amp;nbsp;help and internet searches you can try another source of information: &lt;strong&gt;patents&lt;/strong&gt;.
&lt;/p&gt;
&lt;p&gt;
Most big companies like to patent a lot of stuff so I stumbled upon &lt;a href="http://www.freepatentsonline.com/20050251380.html"&gt;this
patent&lt;/a&gt; that has some good information about design time. The&amp;nbsp;inventors of
the patent are:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;em&gt;Andrew Cheng-Min Lin&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Bulusu Krishna Mohan&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Nikhil Kothari&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;em&gt;Simon Calvert&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
Does any one&amp;nbsp;sound familiar to you?&lt;br&gt;
&lt;br&gt;
Anyway, nothing beats using reflector to figure out some of the more obscure interfaces.
Unfortunately, it is also the slowest method. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=1d9cf157-2c6c-4ec4-b45a-7dc724543c28" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,1d9cf157-2c6c-4ec4-b45a-7dc724543c28.aspx</comments>
      <category>ASP.NET;Microsoft .NET Framework</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=6933d7ba-0d2b-4e3f-b5f2-8e1514a2b938</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,6933d7ba-0d2b-4e3f-b5f2-8e1514a2b938.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,6933d7ba-0d2b-4e3f-b5f2-8e1514a2b938.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=6933d7ba-0d2b-4e3f-b5f2-8e1514a2b938</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
From time to time I like to evaluate the way I’m working, investigate on new alternatives,
try other approaches, etc. in order to improve the way I do things. Other times, I
have to change the way I do some things by necessity. This time was a bit of both.
The number of components I’m selling on my web page <a href="http://www.manuelabadia.com">www.manuelabadia.com</a> is
growing slowly and some things I was doing by hand were a pain to maintain and started
to take too much time, so a change was really needed. Also, in the development area,
things were also getting more complex.
</p>
        <p>
Distribution of the components by mail is a lot less reliable than I thought as some
companies have really strict firewall/attachment policies. Implementing a decent LicenseProvider
based on digital signature was more complex than I thought, has some hurdles with
ASP.NET and works a bit different between web site projects and web application projects.
However, having the LicenseProvider implemented has freed me of all component distribution
and signing, saving a lot of time and headaches.
</p>
        <p>
Maintaining and developing new components was also getting more complicated, because
components were starting to share code, and having to maintain two versions of the
same code is problematic and error prone. However, splitting the components in several
projects and then using ILMerge seems to work great. Improving my subversion merge/branch
skills was also necessary as I end with a lot of releases with a very similar codebase
but with little differences between them. Better tool integration for ordinary tasks
with Visual Studio has also helped a lot. I’ll comment about a few of these tools
in a future.
</p>
        <p>
There seem to be a lot of good tools emerging with a goal to improve the quality and
reliability of our code. Microsoft research is also trying some things with Spec#
and Pex. Maybe I’ll blog about those when Pex becomes available to the masses.
</p>
        <p>
So what about the future? Well, I have a lot of ideas for new components and new features
for the existing ones. As always, the biggest problem is time. There’s no time to
do all the stuff I have in mind or the cool things I want to try (has anybody tried <a href="http://www.codeplex.com/SharpMap">SharpMap</a>?)
I have a component in the works that has been nearly finished for a couple of months.
I hope to finish it at the end of the year or in January 2008. After that probably
I’ll concentrate on further improving the existing components and checking if something
new can be added if the version of ASP.NET shipped Visual Studio 2008 has a couple
of significant changes. After that probably I won’t release more components because
I can’t be sure to be able to provide a good service if I release more components.<br />
 <br />
As I said before, the sales are growing slowly, and the components are being used
in most of the “important” countries:
</p>
        <p>
          <img src="http://www.manuelabadia.com/blog/content/binary/products_in_the_world.png" border="0" />
        </p>
        <p>
This shows me that I’m doing things well and encourages me to work harder and keep
improving my skills.
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=6933d7ba-0d2b-4e3f-b5f2-8e1514a2b938" />
      </body>
      <title>Continuous Evolution</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,6933d7ba-0d2b-4e3f-b5f2-8e1514a2b938.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,6933d7ba-0d2b-4e3f-b5f2-8e1514a2b938.aspx</link>
      <pubDate>Thu, 01 Nov 2007 23:04:32 GMT</pubDate>
      <description>&lt;p&gt;
From time to time I like to evaluate the way I’m working, investigate on new alternatives,
try other approaches, etc. in order to improve the way I do things. Other times, I
have to change the way I do some things by necessity. This time was a bit of both.
The number of components I’m selling on my web page &lt;a href="http://www.manuelabadia.com"&gt;www.manuelabadia.com&lt;/a&gt; is
growing slowly and some things I was doing by hand were a pain to maintain and started
to take too much time, so a change was really needed. Also, in the development area,
things were also getting more complex.
&lt;/p&gt;
&lt;p&gt;
Distribution of the components by mail is a lot less reliable than I thought as some
companies have really strict firewall/attachment policies. Implementing a decent LicenseProvider
based on digital signature was more complex than I thought, has some hurdles with
ASP.NET and works a bit different between web site projects and web application projects.
However, having the LicenseProvider implemented has freed me of all component distribution
and signing, saving a lot of time and headaches.
&lt;/p&gt;
&lt;p&gt;
Maintaining and developing new components was also getting more complicated, because
components were starting to share code, and having to maintain two versions of the
same code is problematic and error prone. However, splitting the components in several
projects and then using ILMerge seems to work great. Improving my subversion merge/branch
skills was also necessary as I end with a lot of releases with a very similar codebase
but with little differences between them. Better tool integration for ordinary tasks
with Visual Studio has also helped a lot. I’ll comment about a few of these tools
in a future.
&lt;/p&gt;
&lt;p&gt;
There seem to be a lot of good tools emerging with a goal to improve the quality and
reliability of our code. Microsoft research is also trying some things with Spec#
and Pex. Maybe I’ll blog about those when Pex becomes available to the masses.
&lt;/p&gt;
&lt;p&gt;
So what about the future? Well, I have a lot of ideas for new components and new features
for the existing ones. As always, the biggest problem is time. There’s no time to
do all the stuff I have in mind or the cool things I want to try (has anybody tried &lt;a href="http://www.codeplex.com/SharpMap"&gt;SharpMap&lt;/a&gt;?)
I have a component in the works that has been nearly finished for a couple of months.
I hope to finish it at the end of the year or in January 2008. After that probably
I’ll concentrate on further improving the existing components and checking if something
new can be added if the version of ASP.NET shipped Visual Studio 2008 has a couple
of significant changes. After that probably I won’t release more components because
I can’t be sure to be able to provide a good service if I release more components.&lt;br&gt;
&amp;nbsp;&lt;br&gt;
As I said before, the sales are growing slowly, and the components are being used
in most of the “important” countries:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/products_in_the_world.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
This shows me that I’m doing things well and encourages me to work harder and keep
improving my skills.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=6933d7ba-0d2b-4e3f-b5f2-8e1514a2b938" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,6933d7ba-0d2b-4e3f-b5f2-8e1514a2b938.aspx</comments>
      <category>ASP.NET;General;Microsoft .NET Framework;Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=76d8bd97-b947-42df-8ada-f254937f15ec</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,76d8bd97-b947-42df-8ada-f254937f15ec.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,76d8bd97-b947-42df-8ada-f254937f15ec.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=76d8bd97-b947-42df-8ada-f254937f15ec</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <title>How to fix the most annoying ASP.NET 2.0 bug (TreeView XHTML compliance)</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,76d8bd97-b947-42df-8ada-f254937f15ec.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,76d8bd97-b947-42df-8ada-f254937f15ec.aspx</link>
      <pubDate>Thu, 25 Oct 2007 07:38:14 GMT</pubDate>
      <description>&lt;p&gt;
Or at least, one of them.
&lt;/p&gt;
&lt;p&gt;
If you have used the TreeView control in ASP.NET and tried to validate your page against
XHTML 1.0 transitional you’ll have the unpleasant surprise to see that the TreeView
does not produce compliant code because of this:&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red0\green0\blue0;\red0\green128\blue0;}??\fs20 \cf1 &amp;lt;\cf3 script\cf1 &amp;gt;\par ??\cf0 &amp;lt;!--\par ??    \cf1 function\cf0  TreeView_PopulateNodeDoCallBack(context,param) \{\par ??        WebForm_DoCallback(context.data.treeViewID,param,TreeView_ProcessNodeData,context,TreeView_ProcessNodeData,\cf1 false\cf0 );\par ??    \}\par ??\cf5 // --&amp;gt;\par ??\cf1 &amp;lt;/\cf3 script\cf1 &amp;gt;}
--&gt;
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;script&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;lt;!--
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;function&lt;/span&gt; TreeView_PopulateNodeDoCallBack(context,param)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; WebForm_DoCallback(context.data.treeViewID,param,TreeView_ProcessNodeData,context,TreeView_ProcessNodeData,&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;
&lt;span style="COLOR: green"&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: #a31515"&gt;script&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The generated script code does not have the required type='text/javascript' attribute.
&lt;/p&gt;
&lt;p&gt;
It is sad that Microsoft didn’t find this bug out before releasing asp.net 2.0. They
should work with something &lt;a href="http://www.thejoyofcode.com/Validator_Module.aspx"&gt;like
this xhtml validation module &lt;/a&gt;when testing their controls. The fix for this problem
is trivial, just add the type attribute to the injected script and everybody is happy.
&lt;/p&gt;
&lt;p&gt;
However, this is one of the cases that really annoy people. For some “never to be
understood” reason, Microsoft closed this bug as “Won’t fix”. I can’t give you the
link to the bug report as Microsoft Connect is not working for the last 2 days.
&lt;/p&gt;
&lt;p&gt;
You can use the CSS Control Adapter to fix this, or use a third party TreeView. However,
that is no excuse to not having this bug fixed. I can understand that they don’t fix
bugs like the poor extensibility of the ParameterCollectionEditor as there is a lot
of work (however, even if I understand that, I think that it should be fixed. If it
is a lot of work is because of bad design. If it has been designed with extensibility
in mind things like this will not happen as often) but this trivial bug to fix has
no excuse.
&lt;/p&gt;
&lt;p&gt;
Yesterday I faced against this bug again and was too angry to be able to keep working
without doing anything about it. I used reflector to see if there was any way to fix
the bug without having to recreate the full TreeView class and I was lucky.
&lt;/p&gt;
&lt;p&gt;
The TreeView uses IsClientScriptBlockRegistered and RegisterClientScriptBlock to register
the invalid script code, so registering a valid script code before has to work, and
indeed it does:
&lt;/p&gt;
&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red0\green0\blue0;\red128\green128\blue128;\red0\green128\blue0;\red43\green145\blue175;\red163\green21\blue21;}??\fs20 \cf1 using\cf0  System;\par ??\cf1 using\cf0  System.Web.UI;\par ??\cf1 using\cf0  System.Web.UI.WebControls;\par ??\par ??\cf1 namespace\cf0  Manu.Web.UI.WebControls\par ??\{\par ??    \cf4 ///\cf5  \cf4 &amp;lt;summary&amp;gt;\cf5 A TreeView that fixes the most annoying ASP.NET 2.0 bug ever!.\cf4 &amp;lt;/summary&amp;gt;\par ??\cf0     \cf1 public\cf0  \cf1 class\cf0  \cf6 FixedTreeView\cf0  : \cf6 TreeView\par ??\cf0     \{\par ??\cf1         #region\cf0  Fields\par ??\par ??        \cf1 protected\cf0  \cf1 static\cf0  \cf1 string\cf0  populateNodeScript = \cf7 "\\r\\n&amp;lt;script type='text/javascript'&amp;gt;\\r\\n&amp;lt;!--\\r\\n    function TreeView_PopulateNodeDoCallBack(context,param) \{\\r\\n        "\cf0 ;\par ??        \cf1 protected\cf0  \cf1 static\cf0  \cf1 string\cf0  populateNodeScriptEnd = \cf7 ";\\r\\n    \}\\r\\n// --&amp;gt;\\r\\n&amp;lt;/script&amp;gt;\\r\\n"\cf0 ;\par ??\par ??\cf1         #endregion\par ??\par ??        #region\cf0  Methods\par ??\par ??        \cf4 ///\cf5  \cf4 &amp;lt;summary&amp;gt;\cf5 Raises the \cf4 &amp;lt;see cref="E:System.Web.UI.Control.PreRender"&amp;gt;&amp;lt;/see&amp;gt;\cf5  event.\cf4 &amp;lt;/summary&amp;gt;\par ??\cf0         \cf4 ///\cf5  \cf4 &amp;lt;param name="e"&amp;gt;\cf5 An \cf4 &amp;lt;see cref="T:System.EventArgs"&amp;gt;&amp;lt;/see&amp;gt;\cf5  that contains event data.\cf4 &amp;lt;/param&amp;gt;\par ??\cf0         \cf1 protected\cf0  \cf1 override\cf0  \cf1 void\cf0  OnPreRender(\cf6 EventArgs\cf0  e)\par ??        \{\par ??            \cf6 ClientScriptManager\cf0  clientScript = Page.ClientScript;\par ??\par ??            \cf5 // register a correct script code before the TreeView\par ??\cf0             \cf1 if\cf0  (!clientScript.IsClientScriptBlockRegistered(\cf1 base\cf0 .GetType(), \cf7 "PopulateNode"\cf0 ))\par ??            \{\par ??                clientScript.RegisterClientScriptBlock(\cf1 base\cf0 .GetType(), \cf7 "PopulateNode"\cf0 , populateNodeScript + clientScript.GetCallbackEventReference(\cf7 "context.data.treeViewID"\cf0 , \cf7 "param"\cf0 , \cf7 "TreeView_ProcessNodeData"\cf0 , \cf7 "context"\cf0 , \cf7 "TreeView_ProcessNodeData"\cf0 , \cf1 false\cf0 ) + populateNodeScriptEnd);\par ??            \}\par ??\par ??            \cf5 // do the original processing\par ??\cf0             \cf1 base\cf0 .OnPreRender(e);\par ??        \}\par ??\par ??\cf1         #endregion\par ??\cf0     \}\par ??\}}
--&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System.Web.UI;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System.Web.UI.WebControls;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;namespace&lt;/span&gt; Manu.Web.UI.WebControls
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;span style="COLOR: green"&gt;A
TreeView that fixes the most annoying ASP.NET 2.0 bug ever!.&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;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;FixedTreeView&lt;/span&gt; : &lt;span style="COLOR: #2b91af"&gt;TreeView&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;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; #region&lt;/span&gt; Fields
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; populateNodeScript
= &lt;span style="COLOR: #a31515"&gt;"\r\n&amp;lt;script type='text/javascript'&amp;gt;\r\n&amp;lt;!--\r\n&amp;nbsp;&amp;nbsp;&amp;nbsp;
function TreeView_PopulateNodeDoCallBack(context,param) {\r\n&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
"&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; populateNodeScriptEnd
= &lt;span style="COLOR: #a31515"&gt;";\r\n&amp;nbsp;&amp;nbsp;&amp;nbsp; }\r\n// --&amp;gt;\r\n&amp;lt;/script&amp;gt;\r\n"&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; #region&lt;/span&gt; Methods
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;span style="COLOR: green"&gt;Raises
the &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&lt;font color=#008000&gt;PreRender&lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt; event.&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;&amp;nbsp; &amp;nbsp;&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;param
name="e"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;An &lt;/span&gt;&lt;span style="COLOR: gray"&gt;&lt;font color=#008000&gt;System.EventArgs&lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt; that
contains event data.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; OnPreRender(&lt;span style="COLOR: #2b91af"&gt;EventArgs&lt;/span&gt; e)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #2b91af"&gt;ClientScriptManager&lt;/span&gt; clientScript
= Page.ClientScript;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
register a correct script code before the TreeView&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (!clientScript.IsClientScriptBlockRegistered(&lt;span style="COLOR: blue"&gt;base&lt;/span&gt;.GetType(), &lt;span style="COLOR: #a31515"&gt;"PopulateNode"&lt;/span&gt;))
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; clientScript.RegisterClientScriptBlock(&lt;span style="COLOR: blue"&gt;base&lt;/span&gt;.GetType(), &lt;span style="COLOR: #a31515"&gt;"PopulateNode"&lt;/span&gt;,
populateNodeScript + clientScript.GetCallbackEventReference(&lt;span style="COLOR: #a31515"&gt;"context.data.treeViewID"&lt;/span&gt;, &lt;span style="COLOR: #a31515"&gt;"param"&lt;/span&gt;, &lt;span style="COLOR: #a31515"&gt;"TreeView_ProcessNodeData"&lt;/span&gt;, &lt;span style="COLOR: #a31515"&gt;"context"&lt;/span&gt;, &lt;span style="COLOR: #a31515"&gt;"TreeView_ProcessNodeData"&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;false&lt;/span&gt;)
+ populateNodeScriptEnd);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
do the original processing&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;base&lt;/span&gt;.OnPreRender(e);
&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;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&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;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
It is sad to have to resort to this even in the next ASP.NET version. Hopefully&amp;nbsp;a
Microsoft guy can fix this in time for the next ASP.NET version.
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=76d8bd97-b947-42df-8ada-f254937f15ec" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,76d8bd97-b947-42df-8ada-f254937f15ec.aspx</comments>
      <category>ASP.NET;XHTML</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=27e22b2c-af95-4f4c-befd-1debc5841735</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,27e22b2c-af95-4f4c-befd-1debc5841735.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,27e22b2c-af95-4f4c-befd-1debc5841735.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=27e22b2c-af95-4f4c-befd-1debc5841735</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Due to lack of time I haven’t been able to make a sample website showing a complete
usage scenario for my NHibernate custom Membership and Role providers. However, as
there are nearly 100 downloads per month and there is some people using it I’m uploading
a new version. The changes from the latest release are:
</p>
        <ul dir="ltr">
          <li>
            <div style="MARGIN-RIGHT: 0px">Fixed an important bug that didn’t prevent locked out
users from login in.
</div>
          </li>
          <li>
            <div style="MARGIN-RIGHT: 0px">Added a CreateUserWizardEx control that allows creating
a user with extra information in an easy way.
</div>
          </li>
          <li>
            <div style="MARGIN-RIGHT: 0px">Added auto unlock support.
</div>
          </li>
          <li>
            <div style="MARGIN-RIGHT: 0px">Fixed some minor bugs/typos.
</div>
          </li>
        </ul>
        <p>
I’ll detail a bit the new features. The standard CreateUserWizard control generates
an event before creating the user (CreatingUser) and one after the user has been created
(CreatedUser). Somewhere between these two events the control calls the CreateUser
method of the membership provider. The CreateUserWizardEx control extends the CreateUserWizard
that ship with ASP.NET 2.0. It is supposed to be used when you want to insert a user
in the system without using the CreateUser method of the membership provider (for
example, because you want to store more data in the database).<br />
 <br />
The CreateUserWizardEx control adds a CreateUserEx event. You should handle this event,
retrieve all the information for the new user and make the insert in your users table
manually (as the provider interface can’t handle extra data). This event will be generated
after all the password checking and generation have been made, so you only have to
insert the user in the database. When you handle this event, you’ll be passed an instance
of the CreateUserExEventArgs class. This class has 3 properties: EncodedPassword,
EncodedPasswordSalt and EncodedPasswordAnswer that are useful if you’re not storing
the sensitive data in plain text. After the CreateUserEx event is generated, the CreatedUser
event is also generated.
</p>
        <p>
There is one little problem with the CreateUserWizardEx control. Because quite a bit
ASP.NET classes (especially controls) haven’t been designed with extensibility in
mind, it is impossible to override some of the behavior of the CreateUserWizard control
to achieve the desired result. In this particular case I can’t make the control to
skip the CreateUser call to the membership provider in any way without rewriting the
full control (the CreateUserWizard is one of the lengthiest controls in ASP.NET this
is not an option). So the only solution without compromising medium trust scenarios
is to ignore the CreateUser method calls in case you plan to insert the users manually.
To do this you have to set the provider attribute ignoreCreateUserMethod to true.
If the CreateUserWizard control is ever rewritten with extensibility in mind this
hack could be removed, but I don’t think that will happen anytime. I posted about
similar lack of extensibility problems here.
</p>
        <p>
The auto unlock feature is useful if you use locking. If a user fails entering the
password several times in a predefined period of time (specified by the maxInvalidPasswordAttempts
and passwordAttemptWindow properties) his account gets locked out. However, you need
human interaction in order to unlock the user.
</p>
        <p>
If the auto unlock feature is enabled, when a locked user tries to log on the system,
if the data supplied is correct and a certain period of time has passed since the
account was locked out, the provider automatically unlocks the account. To enable
auto unlocking you have to specify enableAutoUnlock="true" in the web.config. The
provider property autoUnlockMinutes controls the minium period of time to wait since
the last failed login to be able to auto unlock an account. The default is 30 minutes.
Note that setting this value too low can make the security benefits of having a lockout
feature disappear.
</p>
        <p>
I’m thinking in adding some code to enforce single user log on for the next version
as time permits (don’t expect this to be implemented in 2007).
</p>
        <p>
As always, feedback is welcome. As the previous version, it has been tested only in
SQL Server 2005. Let me know if you try it in other databases. 
</p>
        <p>
You can <a href="http://www.manuelabadia.com/blog/PermaLink,guid,3b6ccb3f-2f2a-4dcb-a414-605371a00618.aspx">download
the providers here</a>.
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=27e22b2c-af95-4f4c-befd-1debc5841735" />
      </body>
      <title>Custom Membership and Role Providers using NHibernate Update</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,27e22b2c-af95-4f4c-befd-1debc5841735.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,27e22b2c-af95-4f4c-befd-1debc5841735.aspx</link>
      <pubDate>Fri, 12 Oct 2007 14:58:30 GMT</pubDate>
      <description>&lt;p&gt;
Due to lack of time I haven’t been able to make a sample website showing a complete
usage scenario for my NHibernate custom Membership and Role providers. However, as
there are nearly 100 downloads per month and there is some people using it I’m uploading
a new version. The changes from the latest release are:
&lt;/p&gt;
&lt;ul dir=ltr&gt;
&lt;li&gt;
&lt;div style="MARGIN-RIGHT: 0px"&gt;Fixed an important bug that didn’t prevent locked out
users from login in.
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div style="MARGIN-RIGHT: 0px"&gt;Added a CreateUserWizardEx control that allows creating
a user with extra information in an easy way.
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div style="MARGIN-RIGHT: 0px"&gt;Added auto unlock support.
&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div style="MARGIN-RIGHT: 0px"&gt;Fixed some minor bugs/typos.
&lt;/div&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
I’ll detail a bit the new features. The standard CreateUserWizard control generates
an event before creating the user (CreatingUser) and one after the user has been created
(CreatedUser). Somewhere between these two events the control calls the CreateUser
method of the membership provider. The CreateUserWizardEx control extends the CreateUserWizard
that ship with ASP.NET 2.0. It is supposed to be used when you want to insert a user
in the system without using the CreateUser method of the membership provider (for
example, because you want to store more data in the database).&lt;br&gt;
&amp;nbsp;&lt;br&gt;
The CreateUserWizardEx control adds a CreateUserEx event. You should handle this event,
retrieve all the information for the new user and make the insert in your users table
manually (as the provider interface can’t handle extra data). This event will be generated
after all the password checking and generation have been made, so you only have to
insert the user in the database. When you handle this event, you’ll be passed an instance
of the CreateUserExEventArgs class. This class has 3 properties: EncodedPassword,
EncodedPasswordSalt and EncodedPasswordAnswer that are useful if you’re not storing
the sensitive data in plain text. After the CreateUserEx event is generated, the CreatedUser
event is also generated.
&lt;/p&gt;
&lt;p&gt;
There is one little problem with the CreateUserWizardEx control. Because quite a bit
ASP.NET classes (especially controls) haven’t been designed with extensibility in
mind, it is impossible to override some of the behavior of the CreateUserWizard control
to achieve the desired result. In this particular case I can’t make the control to
skip the CreateUser call to the membership provider in any way without rewriting the
full control (the CreateUserWizard is one of the lengthiest controls in ASP.NET this
is not an option). So the only solution without compromising medium trust scenarios
is to ignore the CreateUser method calls in case you plan to insert the users manually.
To do this you have to set the provider attribute ignoreCreateUserMethod to true.
If the CreateUserWizard control is ever rewritten with extensibility in mind this
hack could be removed, but I don’t think that will happen anytime. I posted about
similar lack of extensibility problems here.
&lt;/p&gt;
&lt;p&gt;
The auto unlock feature is useful if you use locking. If a user fails entering the
password several times in a predefined period of time (specified by the maxInvalidPasswordAttempts
and passwordAttemptWindow properties) his account gets locked out. However, you need
human interaction in order to unlock the user.
&lt;/p&gt;
&lt;p&gt;
If the auto unlock feature is enabled, when a locked user tries to log on the system,
if the data supplied is correct and a certain period of time has passed since the
account was locked out, the provider automatically unlocks the account. To enable
auto unlocking you have to specify enableAutoUnlock="true" in the web.config. The
provider property autoUnlockMinutes controls the minium period of time to wait since
the last failed login to be able to auto unlock an account. The default is 30 minutes.
Note that setting this value too low can make the security benefits of having a lockout
feature disappear.
&lt;/p&gt;
&lt;p&gt;
I’m thinking in adding some code to enforce single user log on for the next version
as time permits (don’t expect this to be implemented in 2007).
&lt;/p&gt;
&lt;p&gt;
As always, feedback is welcome. As the previous version, it has been tested only in
SQL Server 2005. Let me know if you try it in other databases. 
&lt;/p&gt;
&lt;p&gt;
You can &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,3b6ccb3f-2f2a-4dcb-a414-605371a00618.aspx"&gt;download
the providers here&lt;/a&gt;.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=27e22b2c-af95-4f4c-befd-1debc5841735" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,27e22b2c-af95-4f4c-befd-1debc5841735.aspx</comments>
      <category>ASP.NET;Microsoft .NET Framework;NHibernate</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=ea42d3b6-d589-46bf-9d09-7af075e834f3</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,ea42d3b6-d589-46bf-9d09-7af075e834f3.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,ea42d3b6-d589-46bf-9d09-7af075e834f3.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=ea42d3b6-d589-46bf-9d09-7af075e834f3</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The last two books I read were excellent so I'm recommending them:
</p>
        <p>
          <strong>
            <em>Professional ASP.NET 2.0 Security, Membership, and Role Management.</em>
          </strong>
        </p>
        <iframe style="WIDTH: 120px; HEIGHT: 240px" marginwidth="0" marginheight="0" src="http://rcm.amazon.com/e/cm?t=manuelabadias-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0764596985&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" frameborder="0" scrolling="no">
        </iframe>
        <p>
          <br />
Stefan Schackow is the author of this book. He is a Program Manager on the ASP.NET
team so he really knows what he is talking about.
</p>
        <p>
The book covers the life of a request from IIS to ASP.NET, in an incredibly level
of detail, explaining what happens in some lifecycle events. It analyzes the 3 different
identities used in an asp.net request, trust levels, security in the configuration
files, forms authentication, session state, page security, the provider model, and
the membership and role provider. Also includes an understandable section about CAS,
something difficult to find.
</p>
        <p>
The explanations provided in this book are awesome. Incredibly detailed. It feels
like you're following the fully commented ASP.NET source code while reading some parts. 
</p>
        <p>
I was so hooked up when I started to read it that I didn't stop until I finished the
first 5 chapters! I wish I had read this book earlier. Definitely one of the best
ASP.NET books of all time.
</p>
        <p>
          <em>
            <strong>Microsoft SQL Server 2005 Integration Services</strong>
          </em>
        </p>
        <iframe style="WIDTH: 120px; HEIGHT: 240px" marginwidth="0" marginheight="0" src="http://rcm.amazon.com/e/cm?t=manuelabadias-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0672327813&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" frameborder="0" scrolling="no">
        </iframe>
        <p>
          <br />
This one is written by Kirk Haselden, a Development Manager on the SSIS team.
</p>
        <p>
I have read a couple of SSIS books before this one, and they have helped me to be
comfortable using SSIS. However, this book explained some things that weren't covered
by other books or if they were covered, they weren't explained very well. Thanks to
this book now I'm an advanced SSIS user. However, I'm not sure if this book will be
useful to a complete newbie to SSIS, so be warned if that's your case. 
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=ea42d3b6-d589-46bf-9d09-7af075e834f3" />
      </body>
      <title>Recommended Reading</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,ea42d3b6-d589-46bf-9d09-7af075e834f3.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,ea42d3b6-d589-46bf-9d09-7af075e834f3.aspx</link>
      <pubDate>Thu, 27 Sep 2007 10:59:52 GMT</pubDate>
      <description>&lt;p&gt;
The last two books I read were excellent so I'm recommending them:
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;em&gt;Professional ASP.NET 2.0 Security, Membership, and Role Management.&lt;/em&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;iframe style="WIDTH: 120px; HEIGHT: 240px" marginwidth=0 marginheight=0 src="http://rcm.amazon.com/e/cm?t=manuelabadias-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=0764596985&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" frameborder=0 scrolling=no&gt;
&lt;/iframe&gt;
&lt;p&gt;
&lt;br&gt;
Stefan Schackow is the author of this book. He is a Program Manager on the ASP.NET
team so he really knows what he is talking about.
&lt;/p&gt;
&lt;p&gt;
The book covers the life of a request from IIS to ASP.NET, in an incredibly level
of detail, explaining what happens in some lifecycle events. It analyzes the 3 different
identities used in an asp.net request, trust levels, security in the configuration
files, forms authentication, session state, page security, the provider model, and
the membership and role provider. Also includes an understandable section about CAS,
something difficult to find.
&lt;/p&gt;
&lt;p&gt;
The explanations provided in this book are awesome. Incredibly detailed. It feels
like you're following the fully commented ASP.NET source code while reading some parts. 
&lt;/p&gt;
&lt;p&gt;
I was so hooked up when I started to read it that I didn't stop until I finished the
first 5 chapters! I wish I had read this book earlier. Definitely one of the best
ASP.NET books of all time.
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;&lt;strong&gt;Microsoft SQL Server 2005 Integration Services&lt;/strong&gt;&lt;/em&gt;
&lt;/p&gt;
&lt;iframe style="WIDTH: 120px; HEIGHT: 240px" marginwidth=0 marginheight=0 src="http://rcm.amazon.com/e/cm?t=manuelabadias-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=0672327813&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" frameborder=0 scrolling=no&gt;
&lt;/iframe&gt;
&lt;p&gt;
&lt;br&gt;
This one is written by Kirk Haselden, a Development Manager on the SSIS team.
&lt;/p&gt;
&lt;p&gt;
I have read a couple of SSIS books before this one, and they have helped me to be
comfortable using SSIS. However, this book explained some things that weren't covered
by other books or if they were covered, they weren't explained very well. Thanks to
this book now I'm an advanced SSIS user. However, I'm not sure if this book will be
useful to a complete newbie to SSIS, so be warned if that's your case. 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=ea42d3b6-d589-46bf-9d09-7af075e834f3" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,ea42d3b6-d589-46bf-9d09-7af075e834f3.aspx</comments>
      <category>ASP.NET;Books;SQL Server;SSIS</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=9ecc2c07-9552-4cc3-a51c-f8a2b7f58ed1</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,9ecc2c07-9552-4cc3-a51c-f8a2b7f58ed1.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,9ecc2c07-9552-4cc3-a51c-f8a2b7f58ed1.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=9ecc2c07-9552-4cc3-a51c-f8a2b7f58ed1</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
One cool thing in ASP.NET 2.0 is the concept of build providers. A file extension
can be associated with a build provider that parses it and generates the associated
code.
</p>
        <p>
For example, the .XSD files have an associated build provider that generates a strongly
typed dataset.
</p>
        <p>
The bad news is that build providers only work for web site projects and not
for web application projects. I don’t know what the exact reason is for Microsoft
not having them working on web application projects but at the moment, we have to
manually generate the associated code files and add them to our project. I hope they
will fix this at least for VS 2008.
</p>
        <p>
For now, they recommend creating a custom tool in order to handle the file creation.
I don’t know very much about Visual Studio internals and I don’t have free time at
the moment so I won’t try it.<br />
 <br />
If someone has some free time and can give it a try it will be cool to create a custom
tool that reads the configured build providers from the web.config and generates code
based on the file type and build provider.
</p>
        <p>
There is a nice article that explains how to create something like the build providers
for windows forms that can be a good starting point:
</p>
        <p>
          <a href="http://msdn.microsoft.com/msdnmag/issues/06/02/CuttingEdge/">http://msdn.microsoft.com/msdnmag/issues/06/02/CuttingEdge/</a>
          <br />
        </p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=9ecc2c07-9552-4cc3-a51c-f8a2b7f58ed1" />
      </body>
      <title>Web Application Projects vs Web Site Projects - Subtle differences (Part 2)</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,9ecc2c07-9552-4cc3-a51c-f8a2b7f58ed1.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,9ecc2c07-9552-4cc3-a51c-f8a2b7f58ed1.aspx</link>
      <pubDate>Mon, 27 Aug 2007 08:44:35 GMT</pubDate>
      <description>&lt;p&gt;
One cool thing in ASP.NET 2.0 is the concept of build providers. A file extension
can be associated with a build provider that parses it and generates the associated
code.
&lt;/p&gt;
&lt;p&gt;
For example, the .XSD files have an associated build provider that generates a strongly
typed dataset.
&lt;/p&gt;
&lt;p&gt;
The bad news is that build providers only work for web site&amp;nbsp;projects and not
for web application projects. I don’t know what the exact reason is for Microsoft
not having them working on web application projects but at the moment, we have to
manually generate the associated code files and add them to our project. I hope they
will fix this at least for VS 2008.
&lt;/p&gt;
&lt;p&gt;
For now, they recommend creating a custom tool in order to handle the file creation.
I don’t know very much about Visual Studio internals and I don’t have free time at
the moment so I won’t&amp;nbsp;try it.&lt;br&gt;
&amp;nbsp;&lt;br&gt;
If someone has some free time and can give it a try it will be cool to create a custom
tool that reads the configured build providers from the web.config and generates code
based on the file type and build provider.
&lt;/p&gt;
&lt;p&gt;
There is a nice article that explains how to create something like the build providers
for windows forms that can be a good starting point:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://msdn.microsoft.com/msdnmag/issues/06/02/CuttingEdge/"&gt;http://msdn.microsoft.com/msdnmag/issues/06/02/CuttingEdge/&lt;/a&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=9ecc2c07-9552-4cc3-a51c-f8a2b7f58ed1" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,9ecc2c07-9552-4cc3-a51c-f8a2b7f58ed1.aspx</comments>
      <category>ASP.NET;Visual Studio</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=8ac87727-5cf9-40e7-9792-63e8541f3157</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,8ac87727-5cf9-40e7-9792-63e8541f3157.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,8ac87727-5cf9-40e7-9792-63e8541f3157.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=8ac87727-5cf9-40e7-9792-63e8541f3157</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Visual Studio 2005 shipped with the Web Site Project to do ASP.NET development. Later,
Microsoft realized that the previous mode used in Visual Studio 2003 was also useful,
so they added the Web Application Projects later as a download and now it is included
in SP1.
</p>
        <p>
The main differences between both approaches are that for Web Application Projects,
all code-behind class files and all the stand alone classes for the project are compiled
into a single assembly placed in the bin folder; for Web Site Projects, the source
code is deployed and when a page is requested dynamic compilation takes place, generating
an assembly for each page (this is not 100% true as there are some options to change
the default behavior, precompilation, etc, but is enough for the following discussion).
</p>
        <p>
For a more detailed comparison between the two approaches take a look here:
</p>
        <p>
          <a href="http://msdn2.microsoft.com/en-us/library/aa730880(VS.80).aspx">http://msdn2.microsoft.com/en-us/library/aa730880(VS.80).aspx</a>
        </p>
        <p>
I'll post a few entries to show some subtle problems I’ve run when working with a
Web Site Project and then converting it to a Web Application Project.
</p>
        <p>
The first difference:
</p>
        <p>
I use an HttpModule to handle NHibernate sessions and NHibernate set up. The module
captures the Init event and iterates through all loaded assemblies, creating a list
of all loaded assemblies and its dependencies, and then initializes NHibernate adding
all the assemblies to the Configuration object, so all .hbm.xml mappings embedded
in the assemblies are consumed by NHibernate.
</p>
        <p>
The code I was using was:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: green">// gets all executing assemblies</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: #2b91af">List</span>&lt;<span style="COLOR: #2b91af">Assembly</span>&gt;
assemblies = <span style="COLOR: blue">new</span><span style="COLOR: #2b91af">List</span>&lt;<span style="COLOR: #2b91af">Assembly</span>&gt;(<span style="COLOR: #2b91af">AppDomain</span>.CurrentDomain.GetAssemblies());
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">// adds the dependants to the executing assemblies, filtering
system assemblies</span>
          </p>
          <p style="MARGIN: 0px">
AddDependantAssemblies(assemblies);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: #2b91af">Configuration</span> cfig = <span style="COLOR: blue">new</span><span style="COLOR: #2b91af">Configuration</span>();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">// adds the loaded assemblies to the configuration in order
to extract all NHibernate mappings</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">foreach</span> (<span style="COLOR: #2b91af">Assembly</span> assembly <span style="COLOR: blue">in</span> assemblies)
</p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    cfig.AddAssembly(assembly);
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">// builds the session factory</span>
          </p>
          <p style="MARGIN: 0px">
_sessionFactory = cfig.BuildSessionFactory();
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: gray">///</span>
            <span style="COLOR: green">
            </span>
            <span style="COLOR: gray">&lt;summary&gt;</span>
            <span style="COLOR: green">Adds
the dependant assemblies of a list of assemblies.</span>
            <span style="COLOR: gray">&lt;/summary&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: gray">///</span>
            <span style="COLOR: green">
            </span>
            <span style="COLOR: gray">&lt;remarks&gt;</span>
            <span style="COLOR: green">The
list will be modified. Some assemblies can be removed and some will be added.</span>
            <span style="COLOR: gray">&lt;/remarks&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: gray">///</span>
            <span style="COLOR: green">
            </span>
            <span style="COLOR: gray">&lt;param
name="assemblies"&gt;</span>
            <span style="COLOR: green">The initial assemblies.</span>
            <span style="COLOR: gray">&lt;/param&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">public</span>
            <span style="COLOR: blue">static</span>
            <span style="COLOR: blue">void</span> AddDependantAssemblies(<span style="COLOR: #2b91af">List</span>&lt;<span style="COLOR: #2b91af">Assembly</span>&gt;
assemblies)
</p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: green">// saves the assemblies</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: #2b91af">Assembly</span>[] originalAssemblies
= <span style="COLOR: blue">new</span><span style="COLOR: #2b91af">Assembly</span>[assemblies.Count];
</p>
          <p style="MARGIN: 0px">
    assemblies.CopyTo(originalAssemblies);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    assemblies.Clear();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: green">// starts adding the assemblies and
its dependants on an empty list</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">foreach</span> (<span style="COLOR: #2b91af">Assembly</span> assembly <span style="COLOR: blue">in</span> originalAssemblies)
{
</p>
          <p style="MARGIN: 0px">
        AddDependantAssemblies(assembly, assemblies);
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: gray">///</span>
            <span style="COLOR: green">
            </span>
            <span style="COLOR: gray">&lt;summary&gt;</span>
            <span style="COLOR: green">Adds
the dependant assemblies of an assembly.</span>
            <span style="COLOR: gray">&lt;/summary&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: gray">///</span>
            <span style="COLOR: green">
            </span>
            <span style="COLOR: gray">&lt;param
name="baseAssembly"&gt;</span>
            <span style="COLOR: green">The base assembly.</span>
            <span style="COLOR: gray">&lt;/param&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: gray">///</span>
            <span style="COLOR: green">
            </span>
            <span style="COLOR: gray">&lt;param
name="dependants"&gt;</span>
            <span style="COLOR: green">A list with the current dependants.</span>
            <span style="COLOR: gray">&lt;/param&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">public</span>
            <span style="COLOR: blue">static</span>
            <span style="COLOR: blue">void</span> AddDependantAssemblies(<span style="COLOR: #2b91af">Assembly</span> baseAssembly, <span style="COLOR: #2b91af">List</span>&lt;<span style="COLOR: #2b91af">Assembly</span>&gt;
dependants)
</p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: green">// adds the assembly as a dependant
if it wasn't already in the list</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">if</span> (!dependants.Contains(baseAssembly))
{
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: green">// if the assembly
doesn't have to be included, exit</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">if</span> (FilterAssembly(baseAssembly.FullName))
{
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">return</span>;
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        dependants.Add(baseAssembly);
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: #2b91af">AssemblyName</span>[] assemblies =
baseAssembly.GetReferencedAssemblies();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: green">// iterate through the dependant assemblies
adding their dependant assemblies if necessary</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">foreach</span> (<span style="COLOR: #2b91af">AssemblyName</span> assembly <span style="COLOR: blue">in</span> assemblies)
{
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">if</span> (!FilterAssembly(assembly.Name))
{
</p>
          <p style="MARGIN: 0px">
            AddDependantAssemblies(<span style="COLOR: #2b91af">Assembly</span>.Load(assembly),
dependants);
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
And this worked fine until I converted the project to a Web Application Project. After
the conversion the assembly that had the NHibernate mapping was not loaded in the
Init HttpApplication event. It seems that for a Web Site Project all the assemblies
that are in the bin folder are loaded when the AppDomain starts, so with AppDomain.CurrentDomain.GetAssemblies()
I was able to retrieve the assembly with the mappings. However, for a Web Application
Project, only the assemblies that were used until that moment were loaded, and that’s
why it failed. The big problem is how to get all assemblies for the web application
even if they haven’t been used.  
</p>
        <p>
My first try was to search in the MSDN documentation for the class System.Web.Compilation.BuildManager,
as it had something similar for types (the GetType method). Unfortunately the documentation
didn’t show any related method (at least in the local Spanish documentation I installed,
I haven’t checked others). I googled for a solution to my problem but I didn’t find
it anywhere. My only chance was Reflector, so I spend quite some time investigating
when I found out the GetReferencedAssemblies public method in the BuildManager class
(a class that I have previously discarded because it wasn’t shown in the documentation!).
It was very frustrating to waste time for a missing method in the documentation, but
using that method solved my problem and works for Web Application Projects and Web
Site Projects. The method return an ICollection (to be more precise, an instance of
the internal class System.Web.Util.AssemblySet) with the referenced assemblies. 
</p>
        <p>
The working code is this:<br /></p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: green">// gets all referenced assemblies from the ASP.NET application</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: #2b91af">ICollection</span> referencedAssemblies = <span style="COLOR: #2b91af">BuildManager</span>.GetReferencedAssemblies();
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: #2b91af">List</span>&lt;<span style="COLOR: #2b91af">Assembly</span>&gt;
assemblies = <span style="COLOR: blue">new</span><span style="COLOR: #2b91af">List</span>&lt;<span style="COLOR: #2b91af">Assembly</span>&gt;();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">foreach</span> (<span style="COLOR: #2b91af">Assembly</span> assembly <span style="COLOR: blue">in</span> referencedAssemblies)
{
</p>
          <p style="MARGIN: 0px">
    assemblies.Add(assembly);
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">// adds the dependants to the executing assemblies, filtering
system assemblies</span>
          </p>
          <p style="MARGIN: 0px">
AddDependantAssemblies(assemblies);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: #2b91af">Configuration</span> cfig = <span style="COLOR: blue">new</span><span style="COLOR: #2b91af">Configuration</span>();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">// adds the loaded assemblies to the configuration in order
to extract all NHibernate mappings</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">foreach</span> (<span style="COLOR: #2b91af">Assembly</span> assembly <span style="COLOR: blue">in</span> assemblies)
{
</p>
          <p style="MARGIN: 0px">
    cfig.AddAssembly(assembly);
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">// builds the session factory</span>
          </p>
          <p style="MARGIN: 0px">
_sessionFactory = cfig.BuildSessionFactory();
</p>
        </div>
        <!--EndFragment-->
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=8ac87727-5cf9-40e7-9792-63e8541f3157" />
      </body>
      <title>Web Application Projects vs Web Site Projects - Subtle differences (Part 1)</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,8ac87727-5cf9-40e7-9792-63e8541f3157.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,8ac87727-5cf9-40e7-9792-63e8541f3157.aspx</link>
      <pubDate>Mon, 20 Aug 2007 00:02:17 GMT</pubDate>
      <description>&lt;p&gt;
Visual Studio 2005 shipped with the Web Site Project to do ASP.NET development. Later,
Microsoft realized that the previous mode used in Visual Studio 2003 was also useful,
so they added the Web Application Projects later as a download and now it is included
in SP1.
&lt;/p&gt;
&lt;p&gt;
The main differences between both approaches are that for Web Application Projects,
all code-behind class files and all the stand alone classes for the project are compiled
into a single assembly placed in the bin folder; for Web Site Projects, the source
code is deployed and when a page is requested dynamic compilation takes place, generating
an assembly for each page (this is not 100% true as there are some options to change
the default behavior, precompilation, etc, but is enough for the following discussion).
&lt;/p&gt;
&lt;p&gt;
For a more detailed comparison between the two approaches take a look here:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://msdn2.microsoft.com/en-us/library/aa730880(VS.80).aspx"&gt;http://msdn2.microsoft.com/en-us/library/aa730880(VS.80).aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
I'll post a few entries to show some subtle problems I’ve run when working with a
Web Site Project and then converting it to a Web Application Project.
&lt;/p&gt;
&lt;p&gt;
The first difference:
&lt;/p&gt;
&lt;p&gt;
I use an HttpModule to handle NHibernate sessions and NHibernate set up. The module
captures the Init event and iterates through all loaded assemblies, creating a list
of all loaded assemblies and its dependencies, and then initializes NHibernate adding
all the assemblies to the Configuration object, so all .hbm.xml mappings embedded
in the assemblies are consumed by NHibernate.
&lt;/p&gt;
&lt;p&gt;
The code I was using was:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;// gets all executing assemblies&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Assembly&lt;/span&gt;&amp;gt;
assemblies = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Assembly&lt;/span&gt;&amp;gt;(&lt;span style="COLOR: #2b91af"&gt;AppDomain&lt;/span&gt;.CurrentDomain.GetAssemblies());
&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;// adds the dependants to the executing assemblies, filtering
system assemblies&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
AddDependantAssemblies(assemblies);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;Configuration&lt;/span&gt; cfig = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Configuration&lt;/span&gt;();
&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;// adds the loaded assemblies to the configuration in order
to extract all NHibernate mappings&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: #2b91af"&gt;Assembly&lt;/span&gt; assembly &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; assemblies)
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; cfig.AddAssembly(assembly);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&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;// builds the session factory&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
_sessionFactory = cfig.BuildSessionFactory();
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&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;span style="COLOR: green"&gt;Adds
the dependant assemblies of a list of assemblies.&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;
&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;remarks&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;The
list will be modified. Some assemblies can be removed and some will be added.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/remarks&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&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;param
name="assemblies"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;The initial assemblies.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;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;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; AddDependantAssemblies(&lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Assembly&lt;/span&gt;&amp;gt;
assemblies)
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// saves the assemblies&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #2b91af"&gt;Assembly&lt;/span&gt;[] originalAssemblies
= &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Assembly&lt;/span&gt;[assemblies.Count];
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; assemblies.CopyTo(originalAssemblies);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; assemblies.Clear();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// starts adding the assemblies and
its dependants on an empty list&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: #2b91af"&gt;Assembly&lt;/span&gt; assembly &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; originalAssemblies)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; AddDependantAssemblies(assembly, assemblies);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&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;span style="COLOR: green"&gt;Adds
the dependant assemblies of an assembly.&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;
&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;param
name="baseAssembly"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;The base assembly.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&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;param
name="dependants"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;A list with the current dependants.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;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;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; AddDependantAssemblies(&lt;span style="COLOR: #2b91af"&gt;Assembly&lt;/span&gt; baseAssembly, &lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Assembly&lt;/span&gt;&amp;gt;
dependants)
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// adds the assembly as a dependant
if it wasn't already in the list&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; (!dependants.Contains(baseAssembly))
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// if the assembly
doesn't have to be included, exit&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (FilterAssembly(baseAssembly.FullName))
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&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; &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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; dependants.Add(baseAssembly);
&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;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #2b91af"&gt;AssemblyName&lt;/span&gt;[] assemblies =
baseAssembly.GetReferencedAssemblies();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// iterate through the dependant assemblies
adding their dependant assemblies if necessary&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: #2b91af"&gt;AssemblyName&lt;/span&gt; assembly &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; assemblies)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (!FilterAssembly(assembly.Name))
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; AddDependantAssemblies(&lt;span style="COLOR: #2b91af"&gt;Assembly&lt;/span&gt;.Load(assembly),
dependants);
&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;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
And this worked fine until I converted the project to a Web Application Project. After
the conversion the assembly that had the NHibernate mapping was not loaded in the
Init HttpApplication event. It seems that for a Web Site Project all the assemblies
that are in the bin folder are loaded when the AppDomain starts, so with AppDomain.CurrentDomain.GetAssemblies()
I was able to retrieve the assembly with the mappings. However, for a Web Application
Project, only the assemblies that were used until that moment were loaded, and that’s
why it failed. The big problem is how to get all assemblies for the web application
even if they haven’t been used.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
My first try was to search in the MSDN documentation for the class System.Web.Compilation.BuildManager,
as it had something similar for types (the GetType method). Unfortunately the documentation
didn’t show any related method (at least in the local Spanish documentation I installed,
I haven’t checked others). I googled for a solution to my problem but I didn’t find
it anywhere. My only chance was Reflector, so I spend quite some time investigating
when I found out the GetReferencedAssemblies public method in the BuildManager class
(a class that I have previously discarded because it wasn’t shown in the documentation!).
It was very frustrating to waste time for a missing method in the documentation, but
using that method solved my problem and works for Web Application Projects and Web
Site Projects. The method return an ICollection (to be more precise, an instance of
the internal class System.Web.Util.AssemblySet) with the referenced assemblies. 
&lt;/p&gt;
&lt;p&gt;
The working code is this:&lt;br&gt;
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;// gets all referenced assemblies from the ASP.NET application&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;ICollection&lt;/span&gt; referencedAssemblies = &lt;span style="COLOR: #2b91af"&gt;BuildManager&lt;/span&gt;.GetReferencedAssemblies();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Assembly&lt;/span&gt;&amp;gt;
assemblies = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;List&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Assembly&lt;/span&gt;&amp;gt;();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: #2b91af"&gt;Assembly&lt;/span&gt; assembly &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; referencedAssemblies)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; assemblies.Add(assembly);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&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;// adds the dependants to the executing assemblies, filtering
system assemblies&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
AddDependantAssemblies(assemblies);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;Configuration&lt;/span&gt; cfig = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Configuration&lt;/span&gt;();
&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;// adds the loaded assemblies to the configuration in order
to extract all NHibernate mappings&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: #2b91af"&gt;Assembly&lt;/span&gt; assembly &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; assemblies)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; cfig.AddAssembly(assembly);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&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;// builds the session factory&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
_sessionFactory = cfig.BuildSessionFactory();
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=8ac87727-5cf9-40e7-9792-63e8541f3157" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,8ac87727-5cf9-40e7-9792-63e8541f3157.aspx</comments>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=512a42a7-5d81-4e55-9509-ff2b38ac21ee</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,512a42a7-5d81-4e55-9509-ff2b38ac21ee.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,512a42a7-5d81-4e55-9509-ff2b38ac21ee.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=512a42a7-5d81-4e55-9509-ff2b38ac21ee</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Today is my “official rant day” so I had to post this. The Parameter class was something
introduced with the new data binding infrastructure for ASP.NET 2.0. There are some
classes that derive from the Parameter class like ControlParameter, CookieParameter,
SessionParameter, etc. providing the developer with a good set of parameters to play
with. Also, you can derive from the Parameter class in order to create your own parameters.
Everything looks cool and extensible.<br />
 <br />
What is the problem? Imagine you create a new class, MyParameter, that inherits from
the Parameter class. Probably, you will want to use that parameter in other places,
probably in a ParameterCollection. However, if you go to the designer and try to add
a parameter to a parameter collection you won’t see your parameter, only the predefined
parameter types. You can expect that, as you haven’t code anything for design time,
but you hope that it will be easy to extend the default parameter editor to support
your parameter.
</p>
        <p>
The surprise come when you try to extend the default parameter collection editor.
The ParameterCollectionEditor delegates all the functionality to the ParameterEditorCollectionForm
class, an internal class. The ParameterEditorCollectionForm uses the ParameterEditorUserControl
class (this is a public class) to edit a parameter.
</p>
        <p>
The ParameterEditorUserControl contains a UserControl for each type of parameter it
supports. The method InitializeParameterEditors and CreateParameterList are private, 
so you can’t extend it in any way. When you change the type of parameter you are editing
using the combo box, the SetActiveEditParameterItem method gets called to set the
proper editor for the current parameter. This method contains some if else statements
to select the proper editor based on the current parameter. Of course, the SetActiveEditParameterItem
method is private too, so there is no way to extend the parameter editor in design
time.
</p>
        <p>
So, as you have seen, just to add design time support to another parameter you have
to rewrite a lot of classes. With just a few tweaks to the existing classes, you would
only need to override a couple of methods to point to your editor for the new parameter
class you have created. If a class is a clear candidate to extending like the Parameter
class, the design time related classes also have to be extensible. It is so frustrating
to see this in several places... 
</p>
        <p>
It would be cool to have several ASP.NET team members to study how to redesign their
code in order to make it truly extensible.
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=512a42a7-5d81-4e55-9509-ff2b38ac21ee" />
      </body>
      <title>Lack of Extensibility in some parts of ASP.NET</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,512a42a7-5d81-4e55-9509-ff2b38ac21ee.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,512a42a7-5d81-4e55-9509-ff2b38ac21ee.aspx</link>
      <pubDate>Thu, 16 Aug 2007 14:54:23 GMT</pubDate>
      <description>&lt;p&gt;
Today is my “official rant day” so I had to post this. The Parameter class was something
introduced with the new data binding infrastructure for ASP.NET 2.0. There are some
classes that derive from the Parameter class like ControlParameter, CookieParameter,
SessionParameter, etc. providing the developer with a good set of parameters to play
with. Also, you can derive from the Parameter class in order to create your own parameters.
Everything looks cool and extensible.&lt;br&gt;
&amp;nbsp;&lt;br&gt;
What is the problem? Imagine you create a new class, MyParameter, that inherits from
the Parameter class. Probably, you will want to use that parameter in other places,
probably in a ParameterCollection. However, if you go to the designer and try to add
a parameter to a parameter collection you won’t see your parameter, only the predefined
parameter types. You can expect that, as you haven’t code anything for design time,
but you hope that it will be easy to extend the default parameter editor to support
your parameter.
&lt;/p&gt;
&lt;p&gt;
The surprise come when you try to extend the default parameter collection editor.
The ParameterCollectionEditor delegates all the functionality to the ParameterEditorCollectionForm
class, an internal class. The ParameterEditorCollectionForm uses the ParameterEditorUserControl
class (this is a public class) to edit a parameter.
&lt;/p&gt;
&lt;p&gt;
The ParameterEditorUserControl contains a UserControl for each type of parameter it
supports. The method InitializeParameterEditors and CreateParameterList are private,&amp;nbsp;
so you can’t extend it in any way. When you change the type of parameter you are editing
using the combo box, the SetActiveEditParameterItem method gets called to set the
proper editor for the current parameter. This method contains some if else statements
to select the proper editor based on the current parameter. Of course, the SetActiveEditParameterItem
method is private too, so there is no way to extend the parameter editor in design
time.
&lt;/p&gt;
&lt;p&gt;
So, as you have seen, just to add design time support to another parameter you have
to rewrite a lot of classes. With just a few tweaks to the existing classes, you would
only need to override a couple of methods to point to your editor for the new parameter
class you have created. If a class is a clear candidate to extending like the Parameter
class, the design time related classes also have to be extensible. It is so frustrating
to see this in several places... 
&lt;/p&gt;
&lt;p&gt;
It would be cool to have several ASP.NET team members to study how to redesign their
code in order to make it truly extensible.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=512a42a7-5d81-4e55-9509-ff2b38ac21ee" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,512a42a7-5d81-4e55-9509-ff2b38ac21ee.aspx</comments>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=e26e7f5b-029b-4825-9667-ed82e43796e7</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,e26e7f5b-029b-4825-9667-ed82e43796e7.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,e26e7f5b-029b-4825-9667-ed82e43796e7.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=e26e7f5b-029b-4825-9667-ed82e43796e7</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A couple of days ago a customer told me that he was using the ExtendedObjectDataSource
without problems with telerik’s RADGrid for quite some time. However, when he tried
to bind two ExtendedObjectDataSource controls using the master/detail mode of the
RADGrid, it didn’t work. He asked the Telerik guys for help on this and they send
them an example telling him that it was working with the ObjectDataSource, so it was
a problem with the ExtendedObjectDataSource.
</p>
        <p>
I found a problem in their test case so I told them that it wasn’t my fault although
I couldn’t understand why it did work for the ObjectDataSource.
</p>
        <p>
They modified their test case to overcome the problem I exposed, so the new test case
worked for the ObjectDataSource and it didn’t work for the ExtendedObjectDataSource.
Something really strange was happening. 
</p>
        <p>
          <br />
I spent some time carefully reviewing my code but I didn’t found any problem. I had
no previous experience with the RADGrid (an excellent control BTW) but I loaded the
evaluation version in reflector and I stumbled upon the following code:
</p>
        <p>
          <br />
 
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">protected</span>
            <span style="COLOR: blue">virtual</span>
            <span style="COLOR: blue">void</span> FilterDetailDataSource()
</p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>.UseDataSource = <span style="COLOR: blue">true</span>;
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: #2b91af">GridDetailTableDataBindEventArgs</span> args
= <span style="COLOR: blue">new</span><span style="COLOR: #2b91af">GridDetailTableDataBindEventArgs</span>(<span style="COLOR: blue">this</span>.OwnerGrid, <span style="COLOR: blue">this</span>);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">base</span>.RaiseBubbleEvent(<span style="COLOR: blue">this</span>,
args);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">if</span> (!args.Canceled &amp;&amp;
(<span style="COLOR: blue">this</span>.ParentTableRelation.Count &gt; 0)) {
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">if</span> (!<span style="COLOR: blue">base</span>.IsBoundUsingDataSourceID)
{
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">this</span>.SetDataSourceFilter();
</p>
          <p style="MARGIN: 0px">
        } <span style="COLOR: blue">else</span> {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: #2b91af">ParameterCollection</span> selectParameters
= <span style="COLOR: blue">null</span>;
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: #2b91af">DataSourceControl</span> control
= (<span style="COLOR: #2b91af">DataSourceControl</span>)GridDataSourceControlHelper.FindControl(<span style="COLOR: blue">this</span>, <span style="COLOR: blue">this</span>.DataSourceID);
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> (control <span style="COLOR: blue">is</span><span style="COLOR: #2b91af">SqlDataSource</span>)
{
</p>
          <p style="MARGIN: 0px">
                selectParameters
= (control <span style="COLOR: blue">as</span><span style="COLOR: #2b91af">SqlDataSource</span>).SelectParameters;
</p>
          <p style="MARGIN: 0px">
            } <span style="COLOR: blue">else</span><span style="COLOR: blue">if</span> (control <span style="COLOR: blue">is</span><span style="COLOR: #2b91af">ObjectDataSource</span>)
{
</p>
          <p style="MARGIN: 0px">
                selectParameters
= (control <span style="COLOR: blue">as</span><span style="COLOR: #2b91af">ObjectDataSource</span>).SelectParameters;
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> ((selectParameters
!= <span style="COLOR: blue">null</span>) &amp;&amp; (selectParameters.Count &gt;
0)) {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">foreach</span> (<span style="COLOR: #2b91af">Parameter</span> parameter <span style="COLOR: blue">in</span> selectParameters)
{
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: #2b91af">GridRelationFields</span> fields
= <span style="COLOR: blue">null</span>;
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">foreach</span> (<span style="COLOR: #2b91af">GridRelationFields</span> fields2 <span style="COLOR: blue">in</span><span style="COLOR: blue">this</span>.ParentTableRelation)
{
</p>
          <p style="MARGIN: 0px">
                   
    <span style="COLOR: blue">if</span> (parameter.Name.ToUpper() ==
fields2.DetailKeyField.ToUpper()) {
</p>
          <p style="MARGIN: 0px">
                   
        fields = fields2;
</p>
          <p style="MARGIN: 0px">
                   
        <span style="COLOR: blue">break</span>;
</p>
          <p style="MARGIN: 0px">
                   
    }
</p>
          <p style="MARGIN: 0px">
                   
}
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">if</span> (fields
!= <span style="COLOR: blue">null</span>) {
</p>
          <p style="MARGIN: 0px">
                   
    <span style="COLOR: #2b91af">GridDataKeyArray</span> dataKeyValues
= <span style="COLOR: blue">this</span>.ParentItem.OwnerTableView.DataKeyValues;
</p>
          <p style="MARGIN: 0px">
                   
    <span style="COLOR: blue">if</span> (dataKeyValues.Count &lt;=
0) {
</p>
          <p style="MARGIN: 0px">
                   
        <span style="COLOR: blue">continue</span>;
</p>
          <p style="MARGIN: 0px">
                   
    }
</p>
          <p style="MARGIN: 0px">
                   
    <span style="COLOR: #2b91af">DataKey</span> key = dataKeyValues[<span style="COLOR: blue">this</span>.ParentItem.ItemIndex];
</p>
          <p style="MARGIN: 0px">
                   
    <span style="COLOR: blue">object</span> obj2 = key[fields.MasterKeyField];
</p>
          <p style="MARGIN: 0px">
                   
    <span style="COLOR: blue">if</span> (obj2 == <span style="COLOR: blue">null</span>)
{
</p>
          <p style="MARGIN: 0px">
                   
        <span style="COLOR: blue">continue</span>;
</p>
          <p style="MARGIN: 0px">
                   
    }
</p>
          <p style="MARGIN: 0px">
                   
    parameter.DefaultValue = obj2.ToString();
</p>
          <p style="MARGIN: 0px">
                   
}
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
If you know about DataSource controls and their infrastructure the problem is clear.
Telerik’s RADGrid gets the control bound to the grid (using the DataSourceID property).
If it is a SqlDataSource or an ObjectDataSource, it gets the SelectParameters. After
that they try to find a parameter in the SelectParameters that matches the field used
to traverse from the master object to the detail object and if they found it, they
set the DefaultValue of the parameter to the associated key.
</p>
        <p>
However, they are ignoring ALL DataSource controls but the SqlDataSource and ObjectDataSource.
This is not a nice way to play with others!<br />
 <br />
I told them to please add more generic code to support more data sources. Something
like adding a property SelectParametersPropertyName with a default value of “SelectParameters”
and using reflection to get the property from the control will do the trick. I don’t
know how they have changed it but at least they sent a fixed private version to my
customer. With a bit of luck they'll add the modification to the next public release.
</p>
        <p>
I can’t compare with Telerik in any way as they are one of the most important component
vendors in the .NET market, they have an amazing quantity of controls and they
have a lot of people working for them… Anyway, nothing like being right against Telerik
to make my day.
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=e26e7f5b-029b-4825-9667-ed82e43796e7" />
      </body>
      <title>Manu 1 - Telerik 0</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,e26e7f5b-029b-4825-9667-ed82e43796e7.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,e26e7f5b-029b-4825-9667-ed82e43796e7.aspx</link>
      <pubDate>Thu, 26 Jul 2007 21:46:48 GMT</pubDate>
      <description>&lt;p&gt;
A couple of days ago a customer told me that he was using the ExtendedObjectDataSource
without problems with telerik’s RADGrid for quite some time. However, when he tried
to bind two ExtendedObjectDataSource controls using the master/detail mode of the
RADGrid, it didn’t work. He asked the Telerik guys for help on this and they send
them an example telling him that it was working with the ObjectDataSource, so it was
a problem with the ExtendedObjectDataSource.
&lt;/p&gt;
&lt;p&gt;
I found a problem in their test case so I told them that it wasn’t my fault although
I couldn’t understand why it did work for the ObjectDataSource.
&lt;/p&gt;
&lt;p&gt;
They modified their test case to overcome the problem I exposed, so the new test case
worked for the ObjectDataSource and it didn’t work for the ExtendedObjectDataSource.
Something really strange was happening. 
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
I spent some time carefully reviewing my code but I didn’t found any problem. I had
no previous experience with the RADGrid (an excellent control BTW) but I loaded the
evaluation version in reflector and I stumbled upon the following code:
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;virtual&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; FilterDetailDataSource()
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&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;.UseDataSource = &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; &lt;span style="COLOR: #2b91af"&gt;GridDetailTableDataBindEventArgs&lt;/span&gt; args
= &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;GridDetailTableDataBindEventArgs&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.OwnerGrid, &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;base&lt;/span&gt;.RaiseBubbleEvent(&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;,
args);
&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; (!args.Canceled &amp;amp;&amp;amp;
(&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.ParentTableRelation.Count &amp;gt; 0)) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (!&lt;span style="COLOR: blue"&gt;base&lt;/span&gt;.IsBoundUsingDataSourceID)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.SetDataSourceFilter();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #2b91af"&gt;ParameterCollection&lt;/span&gt; selectParameters
= &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #2b91af"&gt;DataSourceControl&lt;/span&gt; control
= (&lt;span style="COLOR: #2b91af"&gt;DataSourceControl&lt;/span&gt;)GridDataSourceControlHelper.FindControl(&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.DataSourceID);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (control &lt;span style="COLOR: blue"&gt;is&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;SqlDataSource&lt;/span&gt;)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; selectParameters
= (control &lt;span style="COLOR: blue"&gt;as&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;SqlDataSource&lt;/span&gt;).SelectParameters;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;span style="COLOR: blue"&gt;else&lt;/span&gt; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (control &lt;span style="COLOR: blue"&gt;is&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;ObjectDataSource&lt;/span&gt;)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; selectParameters
= (control &lt;span style="COLOR: blue"&gt;as&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;ObjectDataSource&lt;/span&gt;).SelectParameters;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; ((selectParameters
!= &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) &amp;amp;&amp;amp; (selectParameters.Count &amp;gt;
0)) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: #2b91af"&gt;Parameter&lt;/span&gt; parameter &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; selectParameters)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #2b91af"&gt;GridRelationFields&lt;/span&gt; fields
= &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: #2b91af"&gt;GridRelationFields&lt;/span&gt; fields2 &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.ParentTableRelation)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (parameter.Name.ToUpper() ==
fields2.DetailKeyField.ToUpper()) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; fields = fields2;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;break&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (fields
!= &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #2b91af"&gt;GridDataKeyArray&lt;/span&gt; dataKeyValues
= &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.ParentItem.OwnerTableView.DataKeyValues;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (dataKeyValues.Count &amp;lt;=
0) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;continue&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #2b91af"&gt;DataKey&lt;/span&gt; key = dataKeyValues[&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.ParentItem.ItemIndex];
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;object&lt;/span&gt; obj2 = key[fields.MasterKeyField];
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (obj2 == &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;continue&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; parameter.DefaultValue = obj2.ToString();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&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;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
If you know about DataSource controls and their infrastructure the problem is clear.
Telerik’s RADGrid gets the control bound to the grid (using the DataSourceID property).
If it is a SqlDataSource or an ObjectDataSource, it gets the SelectParameters. After
that they try to find a parameter in the SelectParameters that matches the field used
to traverse from the master object to the detail object and if they found it, they
set the DefaultValue of the parameter to the associated key.
&lt;/p&gt;
&lt;p&gt;
However, they are ignoring ALL DataSource controls but the SqlDataSource and ObjectDataSource.
This is not a nice way to play with others!&lt;br&gt;
&amp;nbsp;&lt;br&gt;
I told them to please add more generic code to support more data sources. Something
like adding a property SelectParametersPropertyName with a default value of “SelectParameters”
and using reflection to get the property from the control will do the trick. I don’t
know how they have changed it but at least they sent a fixed private version to my
customer. With a bit of luck they'll add the modification to the next public release.
&lt;/p&gt;
&lt;p&gt;
I can’t compare with Telerik in any way as they are one of the most important component
vendors in the .NET market, they have an amazing quantity of controls&amp;nbsp;and they
have a lot of people working for them… Anyway, nothing like being right against Telerik
to make my day.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=e26e7f5b-029b-4825-9667-ed82e43796e7" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,e26e7f5b-029b-4825-9667-ed82e43796e7.aspx</comments>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=ae3c5e36-a337-4e3e-a3c3-a8e29b801880</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,ae3c5e36-a337-4e3e-a3c3-a8e29b801880.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,ae3c5e36-a337-4e3e-a3c3-a8e29b801880.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=ae3c5e36-a337-4e3e-a3c3-a8e29b801880</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I have updated my Membership and Role provider that use NHibernate for data access.
The changes are minimal. Now I'm using NHibernate 1.2.0 GA and a minor fix. The
instructions and the code can be found <a href="http://www.manuelabadia.com/blog/PermaLink,guid,3b6ccb3f-2f2a-4dcb-a414-605371a00618.aspx">here</a></p>
        <p>
This will be my last post until I return from London. Excuse me if I'm unable to reply
to non critical emails in the next few days.
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=ae3c5e36-a337-4e3e-a3c3-a8e29b801880" />
      </body>
      <title>NHibernate Membership and Role provider updated</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,ae3c5e36-a337-4e3e-a3c3-a8e29b801880.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,ae3c5e36-a337-4e3e-a3c3-a8e29b801880.aspx</link>
      <pubDate>Thu, 21 Jun 2007 08:55:47 GMT</pubDate>
      <description>&lt;p&gt;
I have updated my Membership and Role provider that use NHibernate for data access.
The changes are minimal. Now I'm&amp;nbsp;using NHibernate 1.2.0 GA and a minor fix. The
instructions and the code can be found &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,3b6ccb3f-2f2a-4dcb-a414-605371a00618.aspx"&gt;here&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
This will be my last post until I return from London. Excuse me if I'm unable to reply
to non critical emails in the next few days.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=ae3c5e36-a337-4e3e-a3c3-a8e29b801880" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,ae3c5e36-a337-4e3e-a3c3-a8e29b801880.aspx</comments>
      <category>ASP.NET;NHibernate</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=66351da1-5860-4fe0-9654-0a2dc8b65ace</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,66351da1-5860-4fe0-9654-0a2dc8b65ace.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,66351da1-5860-4fe0-9654-0a2dc8b65ace.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=66351da1-5860-4fe0-9654-0a2dc8b65ace</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I have heard of this problem very often:
</p>
        <p>
          <em>I’m using a DataSourceControl (for example, an ObjectDataSource) and a GridView.
I have a read only property and when I try to update an item, I get an exception because
the DataSourceControl attempts to set the read only property. What is happening?</em>
        </p>
        <p>
Let see an example. In this particular example I’m showing the content of a shopping
cart. The GridView has the following columns:
</p>
        <p>
          <!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red0\green0\blue0;\red255\green0\blue0;}??\fs20 \cf1 &lt;\cf3 Columns\cf1 &gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 BoundField\cf0  \cf5 DataField\cf1 ="ProductId"\cf0  \cf5 HeaderText\cf1 ="ProductId"\cf0  \cf5 ReadOnly\cf1 ="True"\cf0  \cf5 SortExpression\cf1 ="ProductId"\cf0  \cf1 /&gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 BoundField\cf0  \cf5 DataField\cf1 ="ProductName"\cf0  \cf5 HeaderText\cf1 ="ProductName"\cf0  \cf5 ReadOnly\cf1 ="True"\cf0  \cf5 SortExpression\cf1 ="ProductName"\cf0  \cf1 /&gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 BoundField\cf0  \cf5 DataField\cf1 ="ProductUnits"\cf0  \cf5 HeaderText\cf1 ="ProductUnits"\cf0  \cf5 SortExpression\cf1 ="ProductUnits"\cf0  \cf1 /&gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 BoundField\cf0  \cf5 DataField\cf1 ="ProductPrice"\cf0  \cf5 HeaderText\cf1 ="ProductPrice"\cf0  \cf5 ReadOnly\cf1 ="True"\cf0  \cf5 SortExpression\cf1 ="ProductPrice"\cf0  \cf1 /&gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 BoundField\cf0  \cf5 DataField\cf1 ="Total"\cf0  \cf5 HeaderText\cf1 ="Total"\cf0  \cf5 ReadOnly\cf1 ="True"\cf0  \cf5 SortExpression\cf1 ="Total"\cf0  \cf1 /&gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 CommandField\cf0  \cf5 ShowDeleteButton\cf1 ="True"\cf0  \cf5 ShowEditButton\cf1 ="True"\cf0  \cf1 /&gt;\par ??&lt;/\cf3 Columns\cf1 &gt;}
-->
        </p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span>
            <span style="COLOR: #a31515">Columns</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">BoundField</span><span style="COLOR: red">DataField</span><span style="COLOR: blue">="ProductId"</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="ProductId"</span><span style="COLOR: red">ReadOnly</span><span style="COLOR: blue">="True"</span><span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="ProductId"</span><span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">BoundField</span><span style="COLOR: red">DataField</span><span style="COLOR: blue">="ProductName"</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="ProductName"</span><span style="COLOR: red">ReadOnly</span><span style="COLOR: blue">="True"</span><span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="ProductName"</span><span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">BoundField</span><span style="COLOR: red">DataField</span><span style="COLOR: blue">="ProductUnits"</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="ProductUnits"</span><span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="ProductUnits"</span><span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">BoundField</span><span style="COLOR: red">DataField</span><span style="COLOR: blue">="ProductPrice"</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="ProductPrice"</span><span style="COLOR: red">ReadOnly</span><span style="COLOR: blue">="True"</span><span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="ProductPrice"</span><span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">BoundField</span><span style="COLOR: red">DataField</span><span style="COLOR: blue">="Total"</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="Total"</span><span style="COLOR: red">ReadOnly</span><span style="COLOR: blue">="True"</span><span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="Total"</span><span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">CommandField</span><span style="COLOR: red">ShowDeleteButton</span><span style="COLOR: blue">="True"</span><span style="COLOR: red">ShowEditButton</span><span style="COLOR: blue">="True"</span><span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;/</span>
            <span style="COLOR: #a31515">Columns</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <p>
        </p>
        <p>
Note that all the columns for the GridView are read only except the ProductUnits.
The only read only property for a shopping cart item is Total.
</p>
        <p>
If we try the sample, when updating an item in the cart, an exception is thrown because
the underlying DataSourceControl tries to update a read only property (Total). 
The first reaction is to blame the DataSourceControl for the error but after some
findings the problem resides in the GridView. The DataSourceControl receives a keys
dictionary, a values dictionary and an oldValues dictionary in an Update operation.
If the data it receives is wrong, then don’t blame it if the operation does not work.
</p>
        <p>
What is the problem? Well, I thought that a BoundField was a shortcut to save time
and space to bind a property. That it generates a Label in normal mode and a TextBox
in Edit mode. The label will show the value of the DataField and the TextBox has two
way data binding for the specified DataField. If you select a BoundField column and
then click on “Convert this field on a TemplateField”, you can see that the generated
templates match what was expected. 
</p>
        <p>
If the BoundField has the property ReadOnly set to true, you expect that in Edit mode
a label will be shown instead of a TextBox. If you use select that BoundField and
then click on “Convert this field on a TemplateField” you’ll see that the generated
templates match what was expected too.
</p>
        <p>
With this configuration that only uses TemplateFields instead of BoundFields:
</p>
        <p>
          <!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red0\green0\blue0;\red255\green0\blue0;\red255\green238\blue98;}??\fs20 \cf1 &lt;\cf3 Columns\cf1 &gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="ProductId"\cf0  \cf5 SortExpression\cf1 ="ProductId"&gt;\par ??\cf0         \cf1 &lt;\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label1"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Eval("ProductId") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0         \cf1 &lt;\cf3 ItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label1"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Bind("ProductId") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 ItemTemplate\cf1 &gt;\par ??\cf0     \cf1 &lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="ProductName"\cf0  \cf5 SortExpression\cf1 ="ProductName"&gt;\par ??\cf0         \cf1 &lt;\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label2"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Eval("ProductName") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0         \cf1 &lt;\cf3 ItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label2"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Bind("ProductName") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 ItemTemplate\cf1 &gt;\par ??\cf0     \cf1 &lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="ProductUnits"\cf0  \cf5 SortExpression\cf1 ="ProductUnits"&gt;\par ??\cf0         \cf1 &lt;\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 TextBox\cf0  \cf5 ID\cf1 ="TextBox1"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Bind("ProductUnits") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 TextBox\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0         \cf1 &lt;\cf3 ItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label3"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Bind("ProductUnits") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 ItemTemplate\cf1 &gt;\par ??\cf0     \cf1 &lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="ProductPrice"\cf0  \cf5 SortExpression\cf1 ="ProductPrice"&gt;\par ??\cf0         \cf1 &lt;\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label3"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Eval("ProductPrice") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0         \cf1 &lt;\cf3 ItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label4"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Bind("ProductPrice") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 ItemTemplate\cf1 &gt;\par ??\cf0     \cf1 &lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="Total"\cf0  \cf5 SortExpression\cf1 ="Total"&gt;\par ??\cf0         \cf1 &lt;\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label4"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Eval("Total") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0         \cf1 &lt;\cf3 ItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label5"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Bind("Total") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 ItemTemplate\cf1 &gt;\par ??\cf0     \cf1 &lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 CommandField\cf0  \cf5 ShowDeleteButton\cf1 ="True"\cf0  \cf5 ShowEditButton\cf1 ="True"\cf0  \cf1 /&gt;\par ??&lt;/\cf3 Columns\cf1 &gt;}
-->
        </p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span>
            <span style="COLOR: #a31515">Columns</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="ProductId"</span><span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="ProductId"&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label1"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Eval("ProductId") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label1"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Bind("ProductId") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="ProductName"</span><span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="ProductName"&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label2"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Eval("ProductName") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label2"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Bind("ProductName") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="ProductUnits"</span><span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="ProductUnits"&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TextBox</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="TextBox1"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Bind("ProductUnits") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TextBox</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label3"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Bind("ProductUnits") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="ProductPrice"</span><span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="ProductPrice"&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label3"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Eval("ProductPrice") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label4"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Bind("ProductPrice") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="Total"</span><span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="Total"&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label4"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Eval("Total") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label5"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Bind("Total") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">CommandField</span><span style="COLOR: red">ShowDeleteButton</span><span style="COLOR: blue">="True"</span><span style="COLOR: red">ShowEditButton</span><span style="COLOR: blue">="True"</span><span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;/</span>
            <span style="COLOR: #a31515">Columns</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <p>
        </p>
        <p>
The update operation doesn’t give any problem with the read only property “Total”. 
Why?
</p>
        <p>
Imagine, I’m updating the units from 1 to 5 for a shopping cart item with the values
ProductId=1, ProductName=”Product 1”, ProductUnits=1, ProductPrice=2, and Total=2.
</p>
        <p>
When I use the above configuration for the GridView, it calls the Update method on
the DataSourceControl with the following parameters:
</p>
        <p>
Keys
</p>
        <p>
          <img height="192" alt="keys.png" src="http://www.manuelabadia.com/blog/content/binary/keys.png" width="294" border="0" />
        </p>
        <p>
Values
</p>
        <p>
          <img height="186" alt="values.png" src="http://www.manuelabadia.com/blog/content/binary/values.png" width="309" border="0" />
        </p>
        <p>
oldValues
</p>
        <p>
          <img height="189" alt="oldValues2.png" src="http://www.manuelabadia.com/blog/content/binary/oldValues2.png" width="296" border="0" />
        </p>
        <p>
If I use the initial configuration using BoundFields, the oldValues dictionary is
different:
</p>
        <p>
          <img height="193" alt="oldValues.png" src="http://www.manuelabadia.com/blog/content/binary/oldValues.png" width="699" border="0" />
        </p>
        <p>
When the GridView is in Edit mode and the data binding is performed, it fills a private
dictionary called BoundFieldValues. In the HandleUpdate method, the oldValues dictionary
that will be passed to the DataSourceControl is filled with the BoundFieldValues.
However, the BoundFieldValues dictionary is populated using a template method of the
DataControlField class called ExtractValuesFromCell. For a TemplateField, the ExtractValuesFromCell
adds the value extracted from the Bind expression (see <a href="http://www.manuelabadia.com/blog/PermaLink,guid,45f5c9da-8a03-423f-b5b6-5882c4bd67e5.aspx">this
post</a> for more information) to the dictionary. If a cell uses an Eval expression
instead of a Bind expression, the value doesn’t get added to the dictionary. However,
for a BoundField, the ExtractValuesFromCell adds the value to the dictionary even
if it is read only, because it is called with a parameter includeReadOnlyFields =
true.
</p>
        <p>
The values dictionary is filled calling ExtractValuesFromCell to the current row being
edited, but this time, the includeReadOnlyFields is false for the BoundField.
</p>
        <p>
The keys dictionary is filled with the data from the DataKeys property.
</p>
        <p>
If you use this configuration for the GridView:
</p>
        <p>
          <!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red0\green0\blue0;\red255\green0\blue0;\red255\green238\blue98;}??\fs20 \cf1 &lt;\cf3 Columns\cf1 &gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="ProductId"\cf0  \cf5 SortExpression\cf1 ="ProductId"&gt;\par ??\cf0         \cf1 &lt;\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label1"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Bind("ProductId") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0         \cf1 &lt;\cf3 ItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label1"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Bind("ProductId") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 ItemTemplate\cf1 &gt;\par ??\cf0     \cf1 &lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="ProductName"\cf0  \cf5 SortExpression\cf1 ="ProductName"&gt;\par ??\cf0         \cf1 &lt;\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label2"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Bind("ProductName") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0         \cf1 &lt;\cf3 ItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label2"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Bind("ProductName") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 ItemTemplate\cf1 &gt;\par ??\cf0     \cf1 &lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="ProductUnits"\cf0  \cf5 SortExpression\cf1 ="ProductUnits"&gt;\par ??\cf0         \cf1 &lt;\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 TextBox\cf0  \cf5 ID\cf1 ="TextBox1"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Bind("ProductUnits") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 TextBox\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0         \cf1 &lt;\cf3 ItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label3"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Bind("ProductUnits") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 ItemTemplate\cf1 &gt;\par ??\cf0     \cf1 &lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="ProductPrice"\cf0  \cf5 SortExpression\cf1 ="ProductPrice"&gt;\par ??\cf0         \cf1 &lt;\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label3"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Bind("ProductPrice") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0         \cf1 &lt;\cf3 ItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label4"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Bind("ProductPrice") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 ItemTemplate\cf1 &gt;\par ??\cf0     \cf1 &lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="Total"\cf0  \cf5 SortExpression\cf1 ="Total"&gt;\par ??\cf0         \cf1 &lt;\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label4"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Bind("Total") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0         \cf1 &lt;\cf3 ItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label5"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Bind("Total") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 ItemTemplate\cf1 &gt;\par ??\cf0     \cf1 &lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 CommandField\cf0  \cf5 ShowDeleteButton\cf1 ="True"\cf0  \cf5 ShowEditButton\cf1 ="True"\cf0  \cf1 /&gt;\par ??&lt;/\cf3 Columns\cf1 &gt;}
-->
        </p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span>
            <span style="COLOR: #a31515">Columns</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="ProductId"</span><span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="ProductId"&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label1"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Bind("ProductId") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label1"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Bind("ProductId") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="ProductName"</span><span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="ProductName"&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label2"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Bind("ProductName") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label2"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Bind("ProductName") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="ProductUnits"</span><span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="ProductUnits"&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TextBox</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="TextBox1"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Bind("ProductUnits") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TextBox</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label3"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Bind("ProductUnits") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="ProductPrice"</span><span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="ProductPrice"&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label3"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Bind("ProductPrice") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label4"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Bind("ProductPrice") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="Total"</span><span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="Total"&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label4"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Bind("Total") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label5"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Bind("Total") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">CommandField</span><span style="COLOR: red">ShowDeleteButton</span><span style="COLOR: blue">="True"</span><span style="COLOR: red">ShowEditButton</span><span style="COLOR: blue">="True"</span><span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;/</span>
            <span style="COLOR: #a31515">Columns</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <p>
        </p>
        <p>
The oldValues dictionary is the identical to the one obtained using BoundFields instead
of TemplateFields.
</p>
        <p>
A DataSourceControl usually combines the data from the keys, values and oldValues
dictionary to make an update operation, so to make the operation work as expected
you should know in advance what values you want to send to the DataSourceControl. 
</p>
        <p>
I checked some advanced grid controls and found that Telerik’s RadGrid have more control
about this extraction process. This is from the manual of the RadGrid:
</p>
        <p>
          <em>Telerik RadGrid can extract values even from columns that are set as read-only,
if the column's property ForceExtractValue is set to:</em>
        </p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <em>• "InBrowseMode" - when deleting records 
<br />
• "InEditMode" - when inserting/updating records  
<br />
• "Always" - for all modes</em>
          </p>
        </blockquote>
        <p>
          <em>The default value for this property is "None", i.e. the extraction of the default
values will not be performed only for read-only columns. </em>
        </p>
        <p>
To finally answer the question, for an ObjectDataSource, probably you want all the
values except the Total to be present in the final update operation, so this configuration
is the one you’ll use:
</p>
        <p>
          <!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red0\green0\blue0;\red255\green0\blue0;\red255\green238\blue98;}??\fs20 \cf1 &lt;\cf3 Columns\cf1 &gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 BoundField\cf0  \cf5 DataField\cf1 ="ProductId"\cf0  \cf5 HeaderText\cf1 ="ProductId"\cf0  \cf5 ReadOnly\cf1 ="True"\cf0  \cf5 SortExpression\cf1 ="ProductId"\cf0  \cf1 /&gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 BoundField\cf0  \cf5 DataField\cf1 ="ProductName"\cf0  \cf5 HeaderText\cf1 ="ProductName"\cf0  \cf5 ReadOnly\cf1 ="True"\par ??\cf0         \cf5 SortExpression\cf1 ="ProductName"\cf0  \cf1 /&gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 BoundField\cf0  \cf5 DataField\cf1 ="ProductUnits"\cf0  \cf5 HeaderText\cf1 ="ProductUnits"\cf0  \cf5 SortExpression\cf1 ="ProductUnits"\cf0  \cf1 /&gt;\par ??\cf0    \cf1 &lt;\cf3 asp\cf1 :\cf3 BoundField\cf0  \cf5 DataField\cf1 ="ProductPrice"\cf0  \cf5 HeaderText\cf1 ="ProductPrice"\cf0  \cf5 ReadOnly\cf1 ="True"\par ??\cf0         \cf5 SortExpression\cf1 ="ProductPrice"\cf0  \cf1 /&gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="Total"\cf0  \cf5 SortExpression\cf1 ="Total"&gt;\par ??\cf0         \cf1 &lt;\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label1"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Eval("Total") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 EditItemTemplate\cf1 &gt;\par ??\cf0         \cf1 &lt;\cf3 ItemTemplate\cf1 &gt;\par ??\cf0             \cf1 &lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label1"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &lt;%\cb0\highlight0 # Bind("Total") \cb6\highlight6 %&gt;\cf1\cb0\highlight0 '&gt;&lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &gt;\par ??\cf0         \cf1 &lt;/\cf3 ItemTemplate\cf1 &gt;\par ??\cf0     \cf1 &lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &gt;\par ??\cf0     \cf1 &lt;\cf3 asp\cf1 :\cf3 CommandField\cf0  \cf5 ShowDeleteButton\cf1 ="True"\cf0  \cf5 ShowEditButton\cf1 ="True"\cf0  \cf1 /&gt;\par ??&lt;/\cf3 Columns\cf1 &gt;}
-->
        </p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span>
            <span style="COLOR: #a31515">Columns</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">BoundField</span><span style="COLOR: red">DataField</span><span style="COLOR: blue">="ProductId"</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="ProductId"</span><span style="COLOR: red">ReadOnly</span><span style="COLOR: blue">="True"</span><span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="ProductId"</span><span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">BoundField</span><span style="COLOR: red">DataField</span><span style="COLOR: blue">="ProductName"</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="ProductName"</span><span style="COLOR: red">ReadOnly</span><span style="COLOR: blue">="True"</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="ProductName"</span><span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">BoundField</span><span style="COLOR: red">DataField</span><span style="COLOR: blue">="ProductUnits"</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="ProductUnits"</span><span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="ProductUnits"</span><span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
   <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">BoundField</span><span style="COLOR: red">DataField</span><span style="COLOR: blue">="ProductPrice"</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="ProductPrice"</span><span style="COLOR: red">ReadOnly</span><span style="COLOR: blue">="True"</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="ProductPrice"</span><span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: red">HeaderText</span><span style="COLOR: blue">="Total"</span><span style="COLOR: red">SortExpression</span><span style="COLOR: blue">="Total"&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label1"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Eval("Total") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">EditItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: red">ID</span><span style="COLOR: blue">="Label1"</span><span style="COLOR: red">runat</span><span style="COLOR: blue">="server"</span><span style="COLOR: red">Text</span><span style="COLOR: blue">='</span><span style="BACKGROUND: #ffee62">&lt;%</span>#
Bind("Total") <span style="BACKGROUND: #ffee62">%&gt;</span><span style="COLOR: blue">'&gt;&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Label</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">ItemTemplate</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">TemplateField</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">CommandField</span><span style="COLOR: red">ShowDeleteButton</span><span style="COLOR: blue">="True"</span><span style="COLOR: red">ShowEditButton</span><span style="COLOR: blue">="True"</span><span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;/</span>
            <span style="COLOR: #a31515">Columns</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <p>
        </p>
        <p>
Hopefully this post has clarified a bit the problem, the possible options and the
implications, when working with a GridView and a DataSourceControl.<br /></p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=66351da1-5860-4fe0-9654-0a2dc8b65ace" />
      </body>
      <title>Binding, Read Only Properties and DataSourceControls</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,66351da1-5860-4fe0-9654-0a2dc8b65ace.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,66351da1-5860-4fe0-9654-0a2dc8b65ace.aspx</link>
      <pubDate>Thu, 14 Jun 2007 08:26:00 GMT</pubDate>
      <description>&lt;p&gt;
I have heard of this problem very often:
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;I’m using a DataSourceControl (for example, an ObjectDataSource) and a GridView.
I have a read only property and when I try to update an item, I get an exception because
the DataSourceControl attempts to set the read only property. What is happening?&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Let see an example. In this particular example I’m showing the content of a shopping
cart. The GridView has the following columns:
&lt;/p&gt;
&lt;p&gt;
&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red0\green0\blue0;\red255\green0\blue0;}??\fs20 \cf1 &amp;lt;\cf3 Columns\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 BoundField\cf0  \cf5 DataField\cf1 ="ProductId"\cf0  \cf5 HeaderText\cf1 ="ProductId"\cf0  \cf5 ReadOnly\cf1 ="True"\cf0  \cf5 SortExpression\cf1 ="ProductId"\cf0  \cf1 /&amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 BoundField\cf0  \cf5 DataField\cf1 ="ProductName"\cf0  \cf5 HeaderText\cf1 ="ProductName"\cf0  \cf5 ReadOnly\cf1 ="True"\cf0  \cf5 SortExpression\cf1 ="ProductName"\cf0  \cf1 /&amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 BoundField\cf0  \cf5 DataField\cf1 ="ProductUnits"\cf0  \cf5 HeaderText\cf1 ="ProductUnits"\cf0  \cf5 SortExpression\cf1 ="ProductUnits"\cf0  \cf1 /&amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 BoundField\cf0  \cf5 DataField\cf1 ="ProductPrice"\cf0  \cf5 HeaderText\cf1 ="ProductPrice"\cf0  \cf5 ReadOnly\cf1 ="True"\cf0  \cf5 SortExpression\cf1 ="ProductPrice"\cf0  \cf1 /&amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 BoundField\cf0  \cf5 DataField\cf1 ="Total"\cf0  \cf5 HeaderText\cf1 ="Total"\cf0  \cf5 ReadOnly\cf1 ="True"\cf0  \cf5 SortExpression\cf1 ="Total"\cf0  \cf1 /&amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 CommandField\cf0  \cf5 ShowDeleteButton\cf1 ="True"\cf0  \cf5 ShowEditButton\cf1 ="True"\cf0  \cf1 /&amp;gt;\par ??&amp;lt;/\cf3 Columns\cf1 &amp;gt;}
--&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Columns&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;BoundField&lt;/span&gt; &lt;span style="COLOR: red"&gt;DataField&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductId"&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductId"&lt;/span&gt; &lt;span style="COLOR: red"&gt;ReadOnly&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="True"&lt;/span&gt; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductId"&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;BoundField&lt;/span&gt; &lt;span style="COLOR: red"&gt;DataField&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductName"&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductName"&lt;/span&gt; &lt;span style="COLOR: red"&gt;ReadOnly&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="True"&lt;/span&gt; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductName"&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;BoundField&lt;/span&gt; &lt;span style="COLOR: red"&gt;DataField&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductUnits"&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductUnits"&lt;/span&gt; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductUnits"&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;BoundField&lt;/span&gt; &lt;span style="COLOR: red"&gt;DataField&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductPrice"&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductPrice"&lt;/span&gt; &lt;span style="COLOR: red"&gt;ReadOnly&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="True"&lt;/span&gt; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductPrice"&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;BoundField&lt;/span&gt; &lt;span style="COLOR: red"&gt;DataField&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Total"&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Total"&lt;/span&gt; &lt;span style="COLOR: red"&gt;ReadOnly&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="True"&lt;/span&gt; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Total"&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;CommandField&lt;/span&gt; &lt;span style="COLOR: red"&gt;ShowDeleteButton&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="True"&lt;/span&gt; &lt;span style="COLOR: red"&gt;ShowEditButton&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="True"&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: #a31515"&gt;Columns&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Note that all the columns for the GridView are read only except the ProductUnits.
The only read only property for a shopping cart item is Total.
&lt;/p&gt;
&lt;p&gt;
If we try the sample, when updating an item in the cart, an exception is thrown because
the underlying DataSourceControl tries to update a read only property (Total).&amp;nbsp;
The first reaction is to blame the DataSourceControl for the error but after some
findings the problem resides in the GridView. The DataSourceControl receives a keys
dictionary, a values dictionary and an oldValues dictionary in an Update operation.
If the data it receives is wrong, then don’t blame it if the operation does not work.
&lt;/p&gt;
&lt;p&gt;
What is the problem? Well, I thought that a BoundField was a shortcut to save time
and space to bind a property. That it generates a Label in normal mode and a TextBox
in Edit mode. The label will show the value of the DataField and the TextBox has two
way data binding for the specified DataField. If you select a BoundField column and
then click on “Convert this field on a TemplateField”, you can see that the generated
templates match what was expected. 
&lt;/p&gt;
&lt;p&gt;
If the BoundField has the property ReadOnly set to true, you expect that in Edit mode
a label will be shown instead of a TextBox. If you use select that BoundField and
then click on “Convert this field on a TemplateField” you’ll see that the generated
templates match what was expected too.
&lt;/p&gt;
&lt;p&gt;
With this configuration that only uses TemplateFields instead of BoundFields:
&lt;/p&gt;
&lt;p&gt;
&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red0\green0\blue0;\red255\green0\blue0;\red255\green238\blue98;}??\fs20 \cf1 &amp;lt;\cf3 Columns\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="ProductId"\cf0  \cf5 SortExpression\cf1 ="ProductId"&amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label1"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Eval("ProductId") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label1"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Bind("ProductId") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="ProductName"\cf0  \cf5 SortExpression\cf1 ="ProductName"&amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label2"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Eval("ProductName") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label2"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Bind("ProductName") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="ProductUnits"\cf0  \cf5 SortExpression\cf1 ="ProductUnits"&amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 TextBox\cf0  \cf5 ID\cf1 ="TextBox1"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Bind("ProductUnits") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 TextBox\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label3"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Bind("ProductUnits") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="ProductPrice"\cf0  \cf5 SortExpression\cf1 ="ProductPrice"&amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label3"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Eval("ProductPrice") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label4"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Bind("ProductPrice") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="Total"\cf0  \cf5 SortExpression\cf1 ="Total"&amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label4"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Eval("Total") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label5"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Bind("Total") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 CommandField\cf0  \cf5 ShowDeleteButton\cf1 ="True"\cf0  \cf5 ShowEditButton\cf1 ="True"\cf0  \cf1 /&amp;gt;\par ??&amp;lt;/\cf3 Columns\cf1 &amp;gt;}
--&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Columns&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductId"&lt;/span&gt; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductId"&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label1"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Eval("ProductId") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label1"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Bind("ProductId") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductName"&lt;/span&gt; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductName"&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label2"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Eval("ProductName") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label2"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Bind("ProductName") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductUnits"&lt;/span&gt; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductUnits"&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TextBox&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="TextBox1"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Bind("ProductUnits") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TextBox&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label3"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Bind("ProductUnits") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductPrice"&lt;/span&gt; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductPrice"&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label3"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Eval("ProductPrice") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label4"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Bind("ProductPrice") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Total"&lt;/span&gt; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Total"&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label4"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Eval("Total") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label5"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Bind("Total") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;CommandField&lt;/span&gt; &lt;span style="COLOR: red"&gt;ShowDeleteButton&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="True"&lt;/span&gt; &lt;span style="COLOR: red"&gt;ShowEditButton&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="True"&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: #a31515"&gt;Columns&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
The update operation doesn’t give any problem with the read only property “Total”.&amp;nbsp;
Why?
&lt;/p&gt;
&lt;p&gt;
Imagine, I’m updating the units from 1 to 5 for a shopping cart item with the values
ProductId=1, ProductName=”Product 1”, ProductUnits=1, ProductPrice=2, and Total=2.
&lt;/p&gt;
&lt;p&gt;
When I use the above configuration for the GridView, it calls the Update method on
the DataSourceControl with the following parameters:
&lt;/p&gt;
&lt;p&gt;
Keys
&lt;/p&gt;
&lt;p&gt;
&lt;img height=192 alt=keys.png src="http://www.manuelabadia.com/blog/content/binary/keys.png" width=294 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
Values
&lt;/p&gt;
&lt;p&gt;
&lt;img height=186 alt=values.png src="http://www.manuelabadia.com/blog/content/binary/values.png" width=309 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
oldValues
&lt;/p&gt;
&lt;p&gt;
&lt;img height=189 alt=oldValues2.png src="http://www.manuelabadia.com/blog/content/binary/oldValues2.png" width=296 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
If I use the initial configuration using BoundFields, the oldValues dictionary is
different:
&lt;/p&gt;
&lt;p&gt;
&lt;img height=193 alt=oldValues.png src="http://www.manuelabadia.com/blog/content/binary/oldValues.png" width=699 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
When the GridView is in Edit mode and the data binding is performed, it fills a private
dictionary called BoundFieldValues. In the HandleUpdate method, the oldValues dictionary
that will be passed to the DataSourceControl is filled with the BoundFieldValues.
However, the BoundFieldValues dictionary is populated using a template method of the
DataControlField class called ExtractValuesFromCell. For a TemplateField, the ExtractValuesFromCell
adds the value extracted from the Bind expression (see &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,45f5c9da-8a03-423f-b5b6-5882c4bd67e5.aspx"&gt;this
post&lt;/a&gt; for more information) to the dictionary. If a cell uses an Eval expression
instead of a Bind expression, the value doesn’t get added to the dictionary. However,
for a BoundField, the ExtractValuesFromCell adds the value to the dictionary even
if it is read only, because it is called with a parameter includeReadOnlyFields =
true.
&lt;/p&gt;
&lt;p&gt;
The values dictionary is filled calling ExtractValuesFromCell to the current row being
edited, but this time, the includeReadOnlyFields is false for the BoundField.
&lt;/p&gt;
&lt;p&gt;
The keys dictionary is filled with the data from the DataKeys property.
&lt;/p&gt;
&lt;p&gt;
If you use this configuration for the GridView:
&lt;/p&gt;
&lt;p&gt;
&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red0\green0\blue0;\red255\green0\blue0;\red255\green238\blue98;}??\fs20 \cf1 &amp;lt;\cf3 Columns\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="ProductId"\cf0  \cf5 SortExpression\cf1 ="ProductId"&amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label1"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Bind("ProductId") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label1"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Bind("ProductId") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="ProductName"\cf0  \cf5 SortExpression\cf1 ="ProductName"&amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label2"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Bind("ProductName") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label2"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Bind("ProductName") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="ProductUnits"\cf0  \cf5 SortExpression\cf1 ="ProductUnits"&amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 TextBox\cf0  \cf5 ID\cf1 ="TextBox1"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Bind("ProductUnits") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 TextBox\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label3"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Bind("ProductUnits") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="ProductPrice"\cf0  \cf5 SortExpression\cf1 ="ProductPrice"&amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label3"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Bind("ProductPrice") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label4"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Bind("ProductPrice") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="Total"\cf0  \cf5 SortExpression\cf1 ="Total"&amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label4"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Bind("Total") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label5"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Bind("Total") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 CommandField\cf0  \cf5 ShowDeleteButton\cf1 ="True"\cf0  \cf5 ShowEditButton\cf1 ="True"\cf0  \cf1 /&amp;gt;\par ??&amp;lt;/\cf3 Columns\cf1 &amp;gt;}
--&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Columns&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductId"&lt;/span&gt; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductId"&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label1"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Bind("ProductId") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label1"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Bind("ProductId") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductName"&lt;/span&gt; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductName"&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label2"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Bind("ProductName") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label2"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Bind("ProductName") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductUnits"&lt;/span&gt; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductUnits"&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TextBox&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="TextBox1"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Bind("ProductUnits") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TextBox&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label3"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Bind("ProductUnits") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductPrice"&lt;/span&gt; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductPrice"&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label3"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Bind("ProductPrice") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label4"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Bind("ProductPrice") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Total"&lt;/span&gt; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Total"&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label4"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Bind("Total") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label5"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Bind("Total") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;CommandField&lt;/span&gt; &lt;span style="COLOR: red"&gt;ShowDeleteButton&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="True"&lt;/span&gt; &lt;span style="COLOR: red"&gt;ShowEditButton&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="True"&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: #a31515"&gt;Columns&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
The oldValues dictionary is the identical to the one obtained using BoundFields instead
of TemplateFields.
&lt;/p&gt;
&lt;p&gt;
A DataSourceControl usually combines the data from the keys, values and oldValues
dictionary to make an update operation, so to make the operation work as expected
you should know in advance what values you want to send to the DataSourceControl. 
&lt;/p&gt;
&lt;p&gt;
I checked some advanced grid controls and found that Telerik’s RadGrid have more control
about this extraction process. This is from the manual of the RadGrid:
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;Telerik RadGrid can extract values even from columns that are set as read-only,
if the column's property ForceExtractValue is set to:&lt;/em&gt;
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;em&gt;•&amp;nbsp;"InBrowseMode" - when deleting records 
&lt;br&gt;
•&amp;nbsp;"InEditMode" - when inserting/updating records&amp;nbsp; 
&lt;br&gt;
•&amp;nbsp;"Always" - for all modes&lt;/em&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;em&gt;The default value for this property is "None", i.e. the extraction of the default
values will not be performed only for read-only columns. &lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
To finally answer the question, for an ObjectDataSource, probably you want all the
values except the Total to be present in the final update operation, so this configuration
is the one you’ll use:
&lt;/p&gt;
&lt;p&gt;
&lt;!--
{\rtf1\ansi\ansicpg\lang1024\noproof1252\uc1 \deff0{\fonttbl{\f0\fnil\fcharset0\fprq1 Courier New;}}{\colortbl;??\red0\green0\blue255;\red255\green255\blue255;\red163\green21\blue21;\red0\green0\blue0;\red255\green0\blue0;\red255\green238\blue98;}??\fs20 \cf1 &amp;lt;\cf3 Columns\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 BoundField\cf0  \cf5 DataField\cf1 ="ProductId"\cf0  \cf5 HeaderText\cf1 ="ProductId"\cf0  \cf5 ReadOnly\cf1 ="True"\cf0  \cf5 SortExpression\cf1 ="ProductId"\cf0  \cf1 /&amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 BoundField\cf0  \cf5 DataField\cf1 ="ProductName"\cf0  \cf5 HeaderText\cf1 ="ProductName"\cf0  \cf5 ReadOnly\cf1 ="True"\par ??\cf0         \cf5 SortExpression\cf1 ="ProductName"\cf0  \cf1 /&amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 BoundField\cf0  \cf5 DataField\cf1 ="ProductUnits"\cf0  \cf5 HeaderText\cf1 ="ProductUnits"\cf0  \cf5 SortExpression\cf1 ="ProductUnits"\cf0  \cf1 /&amp;gt;\par ??\cf0    \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 BoundField\cf0  \cf5 DataField\cf1 ="ProductPrice"\cf0  \cf5 HeaderText\cf1 ="ProductPrice"\cf0  \cf5 ReadOnly\cf1 ="True"\par ??\cf0         \cf5 SortExpression\cf1 ="ProductPrice"\cf0  \cf1 /&amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 TemplateField\cf0  \cf5 HeaderText\cf1 ="Total"\cf0  \cf5 SortExpression\cf1 ="Total"&amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label1"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Eval("Total") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 EditItemTemplate\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0             \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 Label\cf0  \cf5 ID\cf1 ="Label1"\cf0  \cf5 runat\cf1 ="server"\cf0  \cf5 Text\cf1 ='\cf0\cb6\highlight6 &amp;lt;%\cb0\highlight0 # Bind("Total") \cb6\highlight6 %&amp;gt;\cf1\cb0\highlight0 '&amp;gt;&amp;lt;/\cf3 asp\cf1 :\cf3 Label\cf1 &amp;gt;\par ??\cf0         \cf1 &amp;lt;/\cf3 ItemTemplate\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;/\cf3 asp\cf1 :\cf3 TemplateField\cf1 &amp;gt;\par ??\cf0     \cf1 &amp;lt;\cf3 asp\cf1 :\cf3 CommandField\cf0  \cf5 ShowDeleteButton\cf1 ="True"\cf0  \cf5 ShowEditButton\cf1 ="True"\cf0  \cf1 /&amp;gt;\par ??&amp;lt;/\cf3 Columns\cf1 &amp;gt;}
--&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Columns&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;BoundField&lt;/span&gt; &lt;span style="COLOR: red"&gt;DataField&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductId"&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductId"&lt;/span&gt; &lt;span style="COLOR: red"&gt;ReadOnly&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="True"&lt;/span&gt; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductId"&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;BoundField&lt;/span&gt; &lt;span style="COLOR: red"&gt;DataField&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductName"&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductName"&lt;/span&gt; &lt;span style="COLOR: red"&gt;ReadOnly&lt;/span&gt;&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;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductName"&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;BoundField&lt;/span&gt; &lt;span style="COLOR: red"&gt;DataField&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductUnits"&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductUnits"&lt;/span&gt; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductUnits"&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;BoundField&lt;/span&gt; &lt;span style="COLOR: red"&gt;DataField&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductPrice"&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductPrice"&lt;/span&gt; &lt;span style="COLOR: red"&gt;ReadOnly&lt;/span&gt;&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;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ProductPrice"&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&lt;/span&gt; &lt;span style="COLOR: red"&gt;HeaderText&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Total"&lt;/span&gt; &lt;span style="COLOR: red"&gt;SortExpression&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Total"&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label1"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Eval("Total") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;EditItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Label1"&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;Text&lt;/span&gt;&lt;span style="COLOR: blue"&gt;='&lt;/span&gt;&lt;span style="BACKGROUND: #ffee62"&gt;&amp;lt;%&lt;/span&gt;#
Bind("Total") &lt;span style="BACKGROUND: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;'&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Label&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;ItemTemplate&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;TemplateField&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: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;CommandField&lt;/span&gt; &lt;span style="COLOR: red"&gt;ShowDeleteButton&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="True"&lt;/span&gt; &lt;span style="COLOR: red"&gt;ShowEditButton&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="True"&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: #a31515"&gt;Columns&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Hopefully this post has clarified a bit the problem, the possible options and the
implications, when working with a GridView and a DataSourceControl.&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=66351da1-5860-4fe0-9654-0a2dc8b65ace" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,66351da1-5860-4fe0-9654-0a2dc8b65ace.aspx</comments>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=7b1f65da-71b7-4d35-8680-6305c908c840</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,7b1f65da-71b7-4d35-8680-6305c908c840.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,7b1f65da-71b7-4d35-8680-6305c908c840.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=7b1f65da-71b7-4d35-8680-6305c908c840</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Something that is really annoying is the list of little bugs or problems that pollute
the .NET Framework and doesn’t seem to get fixed (mostly because of remotely backward
compatibility reasons). Others problems are simple solved as “won’t fix“, without
giving any explanation. 
</p>
        <p>
For example, take a look at this one:
</p>
        <p>
          <a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=94108">https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=94108</a>
        </p>
        <p>
If you use a TreeView, invalid XHTML gets generated because a script tag is added
without specifying the type. They only need to add type="text/javascript" to the generated
script. It is clearly a bug and it won’t break anything. However, it is marked as
“won’t fix”. WTF?
</p>
        <p>
Sometimes one can be lucky and they actually fix the bug (or at least they told you
that they will fix it) but this seems to be the exception rather than the rule. For
example, I submitted this bug some time ago and it seems it will be fixed:
</p>
        <p>
          <a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=265321">https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=265321</a>
        </p>
        <p>
However, the list of unresolved issues that clearly need to be fixed is big and growing,
but a lot of them aren't addressed. IMHO this should change. I prefer to have
a remote possibility of having something that works to stop working because of bug
fixes than keep going with thousand of bugs and work arounds for not solving them.
Also, I'd like to have updates more often. To wait a year for a service pack for the
framework is too much.
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=7b1f65da-71b7-4d35-8680-6305c908c840" />
      </body>
      <title>Microsoft bug fixing policies</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,7b1f65da-71b7-4d35-8680-6305c908c840.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,7b1f65da-71b7-4d35-8680-6305c908c840.aspx</link>
      <pubDate>Wed, 13 Jun 2007 14:09:57 GMT</pubDate>
      <description>&lt;p&gt;
Something that is really annoying is the list of little bugs or problems that pollute
the .NET Framework and doesn’t seem to get fixed (mostly because of remotely backward
compatibility reasons). Others problems are simple solved as “won’t fix“, without
giving any explanation. 
&lt;/p&gt;
&lt;p&gt;
For example, take a look at this one:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=94108"&gt;https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=94108&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
If you use a TreeView, invalid XHTML gets generated because a script tag is added
without specifying the type. They only need to add type="text/javascript" to the generated
script. It is clearly a bug and it won’t break anything. However, it is marked as
“won’t fix”. WTF?
&lt;/p&gt;
&lt;p&gt;
Sometimes one can be lucky and they actually fix the bug (or at least they told you
that they will fix it) but this seems to be the exception rather than the rule. For
example, I submitted this bug some time ago and it seems it will be fixed:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=265321"&gt;https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=265321&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
However, the list of unresolved issues that clearly need to be fixed is big and growing,
but a lot of them aren't addressed. IMHO this should change.&amp;nbsp;I prefer to have
a remote possibility of having something that works to stop working because of bug
fixes than keep going with thousand of bugs and work arounds for not solving them.
Also, I'd like to have updates more often. To wait a year for a service pack for the
framework is too much.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=7b1f65da-71b7-4d35-8680-6305c908c840" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,7b1f65da-71b7-4d35-8680-6305c908c840.aspx</comments>
      <category>ASP.NET;Microsoft .NET Framework</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=31a01aba-565d-46ab-b8af-bde3352905c9</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,31a01aba-565d-46ab-b8af-bde3352905c9.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,31a01aba-565d-46ab-b8af-bde3352905c9.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=31a01aba-565d-46ab-b8af-bde3352905c9</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In previous posts about MS AJAX, we have been studying the new elements introduced
in the web.config for a new project that uses Microsoft ASP.NET AJAX Extensions. The
last thing we have to study is the ScriptModule HttpModule:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;</span>
            <span style="COLOR: #a31515">httpModules</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;</span>
            <span style="COLOR: #a31515">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">ScriptModule</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Handlers.ScriptModule,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>"<span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;/</span>
            <span style="COLOR: #a31515">httpModules</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <p>
          <!--EndFragment-->
          <br />
The ScriptModule is necessary to provide 3 features needed by the MS AJAX:
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
• To allow page redirection in a partial page update.<br />
• To be able to call page methods instead of web service methods.<br />
• To serve some files to the users skipping the standard authorization mechanism.
</p>
        </blockquote>
        <p>
          <br />
Let’s see how those features are implemented. The ScriptModule handles three HttpApplication
events:
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
• PreSendRequestHeaders<br />
• PostAcquireRequestState<br />
• AuthenticateRequest
</p>
        </blockquote>
        <p>
          <br />
The PreSendRequestHeaders event is raised before the server sends the headers to the
browser, and it is the last chance to modify them. The ScriptModule handles this event,
and checks if the current response code is 302, emitted when you call to the Response.Redirect
method. 
</p>
        <p>
          <br />
As we will see when we study the UpdatePanel, it allows partial page updates, generating
XMLHttp requests. A partial page update has a request header of type "X-MicrosoftAjax"
with a value of “Delta=true”. However, as the response of this request is handled
internally by the MS AJAX runtime instead of the browser, the redirect wasn’t working.
The ScriptModule fixes this problem, because when a redirect is found for a partial
page update request, it clears the response (headers and content), maintaining the
cookie collection and returning a string as the content of the response. The content
of the response is obtained by calling the EncodeString method of an internal class
called PageRequestManager. This class plays a key role in the MS AJAX infrastructure
and will be studied in detail in future posts. For now, we’re only interested in the
EncodeString method, that has 3 main parameters (type, id and content) and generates
a string that looks like this:
</p>
        <p>
          <em>Length + ‘|’ + type + ‘|’ + id + ‘|’ + content + ‘|’</em>
        </p>
        <p>
Encoding the characters “\u0000” and “\u00ff”.
</p>
        <p>
In the client side, when the response has been received, the _onFormSubmitCompleted
method of the PageRequestManager class checks the type of command specified, and acts
accordingly.
</p>
        <p>
When a redirect is found in response for a partial page update, the ScriptModule generates
a string of type “pageRedirect”, where the redirect location is stored in the content.
The client side handles this command as shown below:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">case</span>
            <span style="COLOR: #a31515">"pageRedirect"</span>:
</p>
          <p style="MARGIN: 0px">
    window.location.href = deltaNode.content;
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">return</span>;
</p>
        </div>
        <p>
          <!--EndFragment-->
          <br />
making the redirect work as expected.<br /></p>
        <p>
One thing to point is that the ScriptModule checks if a rest call has generated a
redirect, throwing and exception in that case. This is done for security reasons.
</p>
        <p>
The PostAcquireRequestState event is raised after the session data has been obtained.
If the request is for a class that implements System.Web.UI.Page and it is a rest
method call, the WebServiceData class (that was explained in a previous post) is used
to call the requested method from the Page. After the method has been called, the
CompleteRequest method is called, bypassing all pipeline events and executing the
EndRequest method. This allows MS AJAX to be able to call a method on a page instead
of having to create a web service to call a method.
</p>
        <p>
The AuthenticateRequest event is raised after the identity of the current user has
been established. The handler for this event sets the SkipAuthorization property of
the HttpContext for the current request. This property is checked in the authorization
module to see if it has to omit authorization checking for the requested url. Usually
an HttpModule use this property to allow anonymous access to some resources (for example,
the Login Page if we’re using forms authentication). In our scenario, the ScriptModule
sets the SkipAuthorization to true if the requested url is scriptresource.axd or if
the authorization module is enabled and the request is a rest request to the authorization
web service.
</p>
        <p>
As you can see, the ScriptModule isn’t terribly complicated but it is necessary to
have the MS AJAX infrastructure working properly.
</p>
        <p>
If we check the AJAX ASP.NET Extensions server side source code, we have now studied
about a 33% of it and we haven’t done anything more than study the new infrastructure
elements provided for a MS AJAX application in the web.config. The most interesting
stuff is to come.
</p>
        <p>
In the next posts I’ll talk about the ScriptManager control.
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=31a01aba-565d-46ab-b8af-bde3352905c9" />
      </body>
      <title>ASP.NET AJAX Extensions Internals - ScriptModule</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,31a01aba-565d-46ab-b8af-bde3352905c9.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,31a01aba-565d-46ab-b8af-bde3352905c9.aspx</link>
      <pubDate>Sun, 10 Jun 2007 16:59:18 GMT</pubDate>
      <description>&lt;p&gt;
In previous posts about MS AJAX, we have been studying the new elements introduced
in the web.config for a new project that uses Microsoft ASP.NET AJAX Extensions. The
last thing we have to study is the ScriptModule HttpModule:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;httpModules&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;ScriptModule&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Handlers.ScriptModule,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&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;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;httpModules&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;br&gt;
The ScriptModule is necessary to provide 3 features needed by the MS AJAX:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
•&amp;nbsp;To allow page redirection in a partial page update.&lt;br&gt;
•&amp;nbsp;To be able to call page methods instead of web service methods.&lt;br&gt;
•&amp;nbsp;To serve some files to the users skipping the standard authorization mechanism.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;br&gt;
Let’s see how those features are implemented. The ScriptModule handles three HttpApplication
events:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
•&amp;nbsp;PreSendRequestHeaders&lt;br&gt;
•&amp;nbsp;PostAcquireRequestState&lt;br&gt;
•&amp;nbsp;AuthenticateRequest
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;br&gt;
The PreSendRequestHeaders event is raised before the server sends the headers to the
browser, and it is the last chance to modify them. The ScriptModule handles this event,
and checks if the current response code is 302, emitted when you call to the Response.Redirect
method. 
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
As we will see when we study the UpdatePanel, it allows partial page updates, generating
XMLHttp requests. A partial page update has a request header of type "X-MicrosoftAjax"
with a value of “Delta=true”. However, as the response of this request is handled
internally by the MS AJAX runtime instead of the browser, the redirect wasn’t working.
The ScriptModule fixes this problem, because when a redirect is found for a partial
page update request, it clears the response (headers and content), maintaining the
cookie collection and returning a string as the content of the response. The content
of the response is obtained by calling the EncodeString method of an internal class
called PageRequestManager. This class plays a key role in the MS AJAX infrastructure
and will be studied in detail in future posts. For now, we’re only interested in the
EncodeString method, that has 3 main parameters (type, id and content) and generates
a string that looks like this:
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;Length + ‘|’ + type + ‘|’ + id + ‘|’ + content + ‘|’&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
Encoding the characters “\u0000” and “\u00ff”.
&lt;/p&gt;
&lt;p&gt;
In the client side, when the response has been received, the _onFormSubmitCompleted
method of the PageRequestManager class checks the type of command specified, and acts
accordingly.
&lt;/p&gt;
&lt;p&gt;
When a redirect is found in response for a partial page update, the ScriptModule generates
a string of type “pageRedirect”, where the redirect location is stored in the content.
The client side handles this command as shown below:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;case&lt;/span&gt; &lt;span style="COLOR: #a31515"&gt;"pageRedirect"&lt;/span&gt;:
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; window.location.href = deltaNode.content;
&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;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;br&gt;
making the redirect work as expected.&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
One thing to point is that the ScriptModule checks if a rest call has generated a
redirect, throwing and exception in that case. This is done for security reasons.
&lt;/p&gt;
&lt;p&gt;
The PostAcquireRequestState event is raised after the session data has been obtained.
If the request is for a class that implements System.Web.UI.Page and it is a rest
method call, the WebServiceData class (that was explained in a previous post) is used
to call the requested method from the Page. After the method has been called, the
CompleteRequest method is called, bypassing all pipeline events and executing the
EndRequest method. This allows MS AJAX to be able to call a method on a page instead
of having to create a web service to call a method.
&lt;/p&gt;
&lt;p&gt;
The AuthenticateRequest event is raised after the identity of the current user has
been established. The handler for this event sets the SkipAuthorization property of
the HttpContext for the current request. This property is checked in the authorization
module to see if it has to omit authorization checking for the requested url. Usually
an HttpModule use this property to allow anonymous access to some resources (for example,
the Login Page if we’re using forms authentication). In our scenario, the ScriptModule
sets the SkipAuthorization to true if the requested url is scriptresource.axd or if
the authorization module is enabled and the request is a rest request to the authorization
web service.
&lt;/p&gt;
&lt;p&gt;
As you can see, the ScriptModule isn’t terribly complicated but it is necessary to
have the MS AJAX infrastructure working properly.
&lt;/p&gt;
&lt;p&gt;
If we check the AJAX ASP.NET Extensions server side source code, we have now studied
about a 33% of it and we haven’t done anything more than study the new infrastructure
elements provided for a MS AJAX application in the web.config. The most interesting
stuff is to come.
&lt;/p&gt;
&lt;p&gt;
In the next posts I’ll talk about the ScriptManager control.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=31a01aba-565d-46ab-b8af-bde3352905c9" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,31a01aba-565d-46ab-b8af-bde3352905c9.aspx</comments>
      <category>Ajax;ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=7d51552e-e524-48a5-a079-761c6ee24020</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,7d51552e-e524-48a5-a079-761c6ee24020.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,7d51552e-e524-48a5-a079-761c6ee24020.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=7d51552e-e524-48a5-a079-761c6ee24020</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
          <strong>Where were we?</strong>
        </p>
        <p>
In my previous posts about MS AJAX Extensions I talked about the additions to the
web.config, Serialization, proxy generation, and ScriptHandlerFactory, that is the
factory that handles *.asmx requests and *_AppService.axd requests. To refresh memory,
what the ScriptHandlerFactory does is to check if the request has application/json
ContentType (a REST method request) or the request path ends with /js or /jsdebug
(a REST client proxy request). If it is a REST method request (<u><font color="#0000ff">http://localhost/AJAXServerSide1/AjaxWebService.asmx/GetModifiedUser</font></u>),
it gets the web service data, calls the requested method and returns the result. If
it is a REST client proxy request (<font color="#0000ff"><u>http://localhost/AJAXServerSide1/AjaxWebService.asmx/js</u></font>),
it returns the generated client proxy. If it isn’t a REST method request or a REST
client proxy request, it delegates the request to the “normal” *.asmx HttpHandler.
</p>
        <p>
The  HttpHandler for *_AppService.axd exists to allow the developer to use some
application services with AJAX. The only available application services available
in v1.0 are Profile_JSON_AppService.axd and Authentication_JSON_AppService.axd. The
profile service exposes the methods: 
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
• GetAllPropertiesForCurrentUser<br />
• GetPropertiesForCurrentUser<br />
•  SetPropertiesForCurrentUser. 
</p>
        </blockquote>
        <p>
The authentication service exposes the following methods:
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
• Login<br />
• Logout
</p>
        </blockquote>
        <p>
To use the services, we have to enable them in the web.config. For the profile service,
we have to set the properties that can be read and write by MS AJAX. For the authentication
service we can specify if it requires SSL or not.
</p>
        <p>
There is a role service that exposes the method GetRolesForUser but it isn’t enabled
in the current version.<br />
The default implementation of the services can be changed, but I won’t be touching
that until we study the ScriptManager.
</p>
        <p>
The last HttpHandler that MS AJAX adds to the web.config is the ScriptResourceHandler,
for the path ScriptResource.axd. Lets study it in more detail…
</p>
        <p>
          <strong>ScriptResourceHandler in detail</strong>
        </p>
        <p>
The main function performed by the ScriptResourceHandler is to load scripts from resources
stored in the assembly and adding localized resources to the scripts.
</p>
        <p>
A request to the ScriptResource.axd must be done at the root level for the application
(~/ScriptResource.axd). The request has the information needed to process it encrypted
in the query string (the encryption and decryption process is done using the EncryptString
and DecryptString methods of the System.Web.UI.Page class). The decrypted format for
the query string is:
</p>
        <p>
          <em>“d=” + 1 character that indicates additional processing + assembly name + ‘|’
+ resource name + ‘|’ + cultureName.</em>
        </p>
        <p>
          <br />
The first character can be ‘u’, ‘U’, ‘z’ or ‘Z’. An uppercase character indicates
that the feature is enabled and the lowercase character indicates that the feature
is disabled. The ‘Z’ indicates that the resource has to be compressed (using GZip).
The ‘U’ indicates to add some code to the end of the script, to notify the MS AJAX
runtime that script has been loaded. The code that gets added to the script is:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span>(<span style="COLOR: blue">typeof</span>(Sys)!==<span style="COLOR: #a31515">'undefined'</span>)Sys.Application.notifyScriptLoaded();
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
The assembly name and the resource name must be specified. If not, an error 404 (page
not found) will be returned. The culture name is used to set the CurrentThead.CurrentUICulture
property. If no culture is specified, the invariant culture is used.
</p>
        <p>
To expose resources stored in an assembly, the assembly level attributes ScriptResourceAttribute
and WebResourceAttribute have to be used.
</p>
        <p>
The ScriptResourceAttribute has 3 important properties: ScriptName, ScriptResourceName
and TypeName. The ScriptName property will be compared to the requested resource name.
ScriptResourceName points to a resource file that contains strings. The TypeName property
specifies a script type that will be created containing the localized strings (of
the CurrentUICulture, or the default ones if no CurrentUICulture specific resources
exist) present in the resource specified by ScriptResourceName.
</p>
        <p>
The WebResourceAttribute has 3 important properties: WebResource, ContentType and
PerformSubstitution. The WebResource property will be compared to the requested resource.
ContentType specifies the type of data stored in the resource and will be used to
write the ContentType for the response. The PerformSubstitution property is used by
the ScriptResourceHandler in order to convert expressions like:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
&lt;%= WebResource(<span style="COLOR: #a31515">"MyResources.JScript2.js"</span>)
%&gt; or &lt;%= ScriptResource(<span style="COLOR: #a31515">"MyResources.JScript2.js"</span>)
%&gt;
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
To the URL of the resource. If WebResource is used, the generated URL will start with
“WebResource.axd?d=”. For ScriptResource, the generated URL will start with “ScriptResource.axd?d=”.
The substitution is performed using regular expressions.
</p>
        <p>
When a resource in an assembly is requested, the assembly is inspected for the assembly
level attributes ScriptResourceAttribute and WebResourceAttribute. Information about
the requested resource is stored in the class ScriptResourceInfo, that has the properties
of ScriptResourceAttribute and WebResourceAttribute combined. For the same resource
name, we can have a ScriptResourceAttribute and a WebResourceAttribute. If only ScriptResourceAttribute
is specified, the default content type is "application/x-javascript". The ScriptResourceInfo
is cached using the assembly and resource name as the cache key.
</p>
        <p>
When a resource that ends with .debug.js is requested, the release mode resource (resource
name that ends with .js) is also requested. At least one of those resources has to
exist.
</p>
        <p>
If we have set the property EnableCaching for the ScriptResourceHandler in the configuration
section, the response will be cached using the ASP.NET output cache by the server
for a year.
</p>
        <p>
The response will be generated in 3 steps:
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
• The requested resource will be read using the GetManifestResourceStream method
from the Assembly class.  If PerformSubstitution is enabled, the substitution
explained above is performed.<br />
• If the ScriptResourceAttribute is used, a ResourceManager for the resource
file with the localized resources is obtained, and some script is added to save the
resources (see the code below)<br />
• If the MS AJAX runtime has to be notified of the loading of the script, add
the script line shown above.
</p>
        </blockquote>
        <p>
          <strong>Example</strong>
        </p>
        <p>
If we have the following assembly level attributes:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
[assembly: <span style="COLOR: #2b91af">ScriptResource</span>(<span style="COLOR: #a31515">"MyResources.JScript1.js"</span>, <span style="COLOR: #a31515">"MyResources.MyStrings"</span>, <span style="COLOR: #a31515">"MyResources.Res"</span>)]
</p>
          <p style="MARGIN: 0px">
[assembly: <span style="COLOR: #2b91af">WebResource</span>(<span style="COLOR: #a31515">"MyResources.JScript1.js"</span>, <span style="COLOR: #a31515">"application/x-javascript"</span>,
PerformSubstitution=<span style="COLOR: blue">true</span>)]
</p>
          <p style="MARGIN: 0px">
[assembly: <span style="COLOR: #2b91af">WebResource</span>(<span style="COLOR: #a31515">"MyResources.JScript2.js"</span>, <span style="COLOR: #a31515">"application/x-javascript"</span>)]
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
The file MyResources.JScript1.js is like this:<br /></p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//jscript1</span>
          </p>
          <p style="MARGIN: 0px">
&lt;%= WebResource(<span style="COLOR: #a31515">"MyResources.JScript2.js"</span>)
%&gt;
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
The file MyStrings.resx has the string named String1 = “This is a test”, when the
resource “MyResources.JScript1.js” is requested, the response content is:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//jscript1</span>
          </p>
          <p style="MARGIN: 0px">
WebResource.axd?d=aGTLuR-3gZaSvlaJzlNqJOqXDQAwO3kOV34svo62fA708VHtJJ6R4HtCd41V1jZv0&amp;t=633164083963984167
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
Type.registerNamespace(<span style="COLOR: #a31515">'MyResources'</span>);
</p>
          <p style="MARGIN: 0px">
MyResources.Res={
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: #a31515">"String1"</span>:<span style="COLOR: #a31515">"This is
a test!"</span></p>
          <p style="MARGIN: 0px">
};
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span>(<span style="COLOR: blue">typeof</span>(Sys)!==<span style="COLOR: #a31515">'undefined'</span>)Sys.Application.notifyScriptLoaded();
</p>
        </div>
        <p>
          <!--EndFragment-->If you add another resource file to localize the resources for spanish
(MyStrings.es-ES.resx) and configure the application to use the Spanish UI culture,
the response for the resource “MyResources.JScript1.js” is:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//jscript1</span>
          </p>
          <p style="MARGIN: 0px">
WebResource.axd?d=aGTLuR-3gZaSvlaJzlNqJOqXDQAwO3kOV34svo62fA708VHtJJ6R4HtCd41V1jZv0&amp;t=633164083963984167
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
Type.registerNamespace(<span style="COLOR: #a31515">'MyResources'</span>);
</p>
          <p style="MARGIN: 0px">
MyResources.Res={
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: #a31515">"String1"</span>:<span style="COLOR: #a31515">"¡Esto
es una prueba!"</span></p>
          <p style="MARGIN: 0px">
};
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span>(<span style="COLOR: blue">typeof</span>(Sys)!==<span style="COLOR: #a31515">'undefined'</span>)Sys.Application.notifyScriptLoaded();
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
That's all for now. In a next post I'll finally finish explaining all the elements
present in the web.config for an asp.net ajax application.
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=7d51552e-e524-48a5-a079-761c6ee24020" />
      </body>
      <title>ASP.NET AJAX Extensions Internals - ScriptResourceHandler</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,7d51552e-e524-48a5-a079-761c6ee24020.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,7d51552e-e524-48a5-a079-761c6ee24020.aspx</link>
      <pubDate>Sun, 03 Jun 2007 09:48:50 GMT</pubDate>
      <description>&lt;p&gt;
&lt;strong&gt;Where were we?&lt;/strong&gt; 
&lt;/p&gt;
&lt;p&gt;
In my previous posts about MS AJAX Extensions I talked about the additions to the
web.config, Serialization, proxy generation, and ScriptHandlerFactory, that is the
factory that handles *.asmx requests and *_AppService.axd requests. To refresh memory,
what the ScriptHandlerFactory does is to check if the request has application/json
ContentType (a REST method request) or the request path ends with /js or /jsdebug
(a REST client proxy request). If it is a REST method request (&lt;u&gt;&lt;font color=#0000ff&gt;http://localhost/AJAXServerSide1/AjaxWebService.asmx/GetModifiedUser&lt;/font&gt;&lt;/u&gt;),
it gets the web service data, calls the requested method and returns the result. If
it is a REST client proxy request (&lt;font color=#0000ff&gt;&lt;u&gt;http://localhost/AJAXServerSide1/AjaxWebService.asmx/js&lt;/u&gt;&lt;/font&gt;),
it returns the generated client proxy. If it isn’t a REST method request or a REST
client proxy request, it delegates the request to the “normal” *.asmx HttpHandler.
&lt;/p&gt;
&lt;p&gt;
The&amp;nbsp; HttpHandler for *_AppService.axd exists to allow the developer to use some
application services with AJAX. The only available application services available
in v1.0 are Profile_JSON_AppService.axd and Authentication_JSON_AppService.axd. The
profile service exposes the methods: 
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
•&amp;nbsp;GetAllPropertiesForCurrentUser&lt;br&gt;
•&amp;nbsp;GetPropertiesForCurrentUser&lt;br&gt;
•&amp;nbsp; SetPropertiesForCurrentUser. 
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
The authentication service exposes the following methods:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
•&amp;nbsp;Login&lt;br&gt;
•&amp;nbsp;Logout
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
To use the services, we have to enable them in the web.config. For the profile service,
we have to set the properties that can be read and write by MS AJAX. For the authentication
service we can specify if it requires SSL or not.
&lt;/p&gt;
&lt;p&gt;
There is a role service that exposes the method GetRolesForUser but it isn’t enabled
in the current version.&lt;br&gt;
The default implementation of the services can be changed, but I won’t be touching
that until we study the ScriptManager.
&lt;/p&gt;
&lt;p&gt;
The last HttpHandler that MS AJAX adds to the web.config is the ScriptResourceHandler,
for the path ScriptResource.axd. Lets study it in more detail…
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;ScriptResourceHandler in detail&lt;/strong&gt; 
&lt;/p&gt;
&lt;p&gt;
The main function performed by the ScriptResourceHandler is to load scripts from resources
stored in the assembly and adding localized resources to the scripts.
&lt;/p&gt;
&lt;p&gt;
A request to the ScriptResource.axd must be done at the root level for the application
(~/ScriptResource.axd). The request has the information needed to process it encrypted
in the query string (the encryption and decryption process is done using the EncryptString
and DecryptString methods of the System.Web.UI.Page class). The decrypted format for
the query string is:
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;“d=” + 1 character that indicates additional processing + assembly name + ‘|’
+ resource name + ‘|’ + cultureName.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
The first character can be ‘u’, ‘U’, ‘z’ or ‘Z’. An uppercase character indicates
that the feature is enabled and the lowercase character indicates that the feature
is disabled. The ‘Z’ indicates that the resource has to be compressed (using GZip).
The ‘U’ indicates to add some code to the end of the script, to notify the MS AJAX
runtime that script has been loaded. The code that gets added to the script is:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;if&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(Sys)!==&lt;span style="COLOR: #a31515"&gt;'undefined'&lt;/span&gt;)Sys.Application.notifyScriptLoaded();
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
The assembly name and the resource name must be specified. If not, an error 404 (page
not found) will be returned. The culture name is used to set the CurrentThead.CurrentUICulture
property. If no culture is specified, the invariant culture is used.
&lt;/p&gt;
&lt;p&gt;
To expose resources stored in an assembly, the assembly level attributes ScriptResourceAttribute
and WebResourceAttribute have to be used.
&lt;/p&gt;
&lt;p&gt;
The ScriptResourceAttribute has 3 important properties: ScriptName, ScriptResourceName
and TypeName. The ScriptName property will be compared to the requested resource name.
ScriptResourceName points to a resource file that contains strings. The TypeName property
specifies a script type that will be created containing the localized strings (of
the CurrentUICulture, or the default ones if no CurrentUICulture specific resources
exist) present in the resource specified by ScriptResourceName.
&lt;/p&gt;
&lt;p&gt;
The WebResourceAttribute has 3 important properties: WebResource, ContentType and
PerformSubstitution. The WebResource property will be compared to the requested resource.
ContentType specifies the type of data stored in the resource and will be used to
write the ContentType for the response. The PerformSubstitution property is used by
the ScriptResourceHandler in order to convert expressions like:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;lt;%= WebResource(&lt;span style="COLOR: #a31515"&gt;"MyResources.JScript2.js"&lt;/span&gt;)
%&amp;gt; or &amp;lt;%= ScriptResource(&lt;span style="COLOR: #a31515"&gt;"MyResources.JScript2.js"&lt;/span&gt;)
%&amp;gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
To the URL of the resource. If WebResource is used, the generated URL will start with
“WebResource.axd?d=”. For ScriptResource, the generated URL will start with “ScriptResource.axd?d=”.
The substitution is performed using regular expressions.
&lt;/p&gt;
&lt;p&gt;
When a resource in an assembly is requested, the assembly is inspected for the assembly
level attributes ScriptResourceAttribute and WebResourceAttribute. Information about
the requested resource is stored in the class ScriptResourceInfo, that has the properties
of ScriptResourceAttribute and WebResourceAttribute combined. For the same resource
name, we can have a ScriptResourceAttribute and a WebResourceAttribute. If only ScriptResourceAttribute
is specified, the default content type is "application/x-javascript". The ScriptResourceInfo
is cached using the assembly and resource name as the cache key.
&lt;/p&gt;
&lt;p&gt;
When a resource that ends with .debug.js is requested, the release mode resource (resource
name that ends with .js) is also requested. At least one of those resources has to
exist.
&lt;/p&gt;
&lt;p&gt;
If we have set the property EnableCaching for the ScriptResourceHandler in the configuration
section, the response will be cached using the ASP.NET output cache by the server
for a year.
&lt;/p&gt;
&lt;p&gt;
The response will be generated in 3 steps:
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
•&amp;nbsp;The requested resource will be read using the GetManifestResourceStream method
from the Assembly class.&amp;nbsp; If PerformSubstitution is enabled, the substitution
explained above is performed.&lt;br&gt;
•&amp;nbsp;If the ScriptResourceAttribute is used, a ResourceManager for the resource
file with the localized resources is obtained, and some script is added to save the
resources (see the code below)&lt;br&gt;
•&amp;nbsp;If the MS AJAX runtime has to be notified of the loading of the script, add
the script line shown above.
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
&lt;strong&gt;Example&lt;/strong&gt; 
&lt;/p&gt;
&lt;p&gt;
If we have the following assembly level attributes:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
[assembly: &lt;span style="COLOR: #2b91af"&gt;ScriptResource&lt;/span&gt;(&lt;span style="COLOR: #a31515"&gt;"MyResources.JScript1.js"&lt;/span&gt;, &lt;span style="COLOR: #a31515"&gt;"MyResources.MyStrings"&lt;/span&gt;, &lt;span style="COLOR: #a31515"&gt;"MyResources.Res"&lt;/span&gt;)]
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
[assembly: &lt;span style="COLOR: #2b91af"&gt;WebResource&lt;/span&gt;(&lt;span style="COLOR: #a31515"&gt;"MyResources.JScript1.js"&lt;/span&gt;, &lt;span style="COLOR: #a31515"&gt;"application/x-javascript"&lt;/span&gt;,
PerformSubstitution=&lt;span style="COLOR: blue"&gt;true&lt;/span&gt;)]
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
[assembly: &lt;span style="COLOR: #2b91af"&gt;WebResource&lt;/span&gt;(&lt;span style="COLOR: #a31515"&gt;"MyResources.JScript2.js"&lt;/span&gt;, &lt;span style="COLOR: #a31515"&gt;"application/x-javascript"&lt;/span&gt;)]
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
The file MyResources.JScript1.js is like this:&lt;br&gt;
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;//jscript1&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;lt;%= WebResource(&lt;span style="COLOR: #a31515"&gt;"MyResources.JScript2.js"&lt;/span&gt;)
%&amp;gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The file MyStrings.resx has the string named String1 = “This is a test”, when the
resource “MyResources.JScript1.js” is requested, the response content is:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;//jscript1&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
WebResource.axd?d=aGTLuR-3gZaSvlaJzlNqJOqXDQAwO3kOV34svo62fA708VHtJJ6R4HtCd41V1jZv0&amp;amp;t=633164083963984167
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Type.registerNamespace(&lt;span style="COLOR: #a31515"&gt;'MyResources'&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
MyResources.Res={
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #a31515"&gt;"String1"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"This is
a test!"&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
};
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;if&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(Sys)!==&lt;span style="COLOR: #a31515"&gt;'undefined'&lt;/span&gt;)Sys.Application.notifyScriptLoaded();
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;If you add another resource file to localize the resources for spanish
(MyStrings.es-ES.resx) and configure the application to use the Spanish UI culture,
the response for the resource “MyResources.JScript1.js” is:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;//jscript1&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
WebResource.axd?d=aGTLuR-3gZaSvlaJzlNqJOqXDQAwO3kOV34svo62fA708VHtJJ6R4HtCd41V1jZv0&amp;amp;t=633164083963984167
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Type.registerNamespace(&lt;span style="COLOR: #a31515"&gt;'MyResources'&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
MyResources.Res={
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #a31515"&gt;"String1"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"¡Esto
es una prueba!"&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
};
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;if&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(Sys)!==&lt;span style="COLOR: #a31515"&gt;'undefined'&lt;/span&gt;)Sys.Application.notifyScriptLoaded();
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
That's all for now. In a next post I'll finally finish explaining all the elements
present in the web.config for an asp.net ajax application.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=7d51552e-e524-48a5-a079-761c6ee24020" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,7d51552e-e524-48a5-a079-761c6ee24020.aspx</comments>
      <category>Ajax;ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=3b6ccb3f-2f2a-4dcb-a414-605371a00618</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,3b6ccb3f-2f2a-4dcb-a414-605371a00618.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,3b6ccb3f-2f2a-4dcb-a414-605371a00618.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=3b6ccb3f-2f2a-4dcb-a414-605371a00618</wfw:commentRss>
      <slash:comments>26</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Usually, the built-in providers for ASP.NET do not integrate very well with existing
applications. The membership provider has a very complex structure that in most cases
is not needed at all. The following diagram shows most of the tables and relations
for the built-in ASP.NET providers:
</p>
        <p>
          <img src="http://www.manuelabadia.com/blog/content/binary/providers.png" border="0" />
        </p>
        <p>
 
</p>
        <p>
The membership related tables are selected in red and the role related tables are
selected in blue. The default membership and roles provider have support to store
data for multiple applications using the aspnet_Applications table. I think this table
was introduced because some portal frameworks like dotnetnuke needed the ability to
store membership and role data for multiple users in a single store because they support
multiple portals. If you don't need this scenario (and most applications do not need
it), this only complicate things.
</p>
        <p>
Also, the built-in providers use tables that are not part of your application tables,
and some of those tables have quite a few columns, and probably some are not needed
by your application.
</p>
        <p>
If you do not use SQL Server, you can not use the default providers, so that is a
big showstopper.
</p>
        <p>
To overcome all of this problems I have created a custom membership and role provider
that use NHibernate and can be easily integrated with existing or future applications
using your own tables.
</p>
        <p>
The reference book about providers is:
</p>
        <p>
          <strong>
            <em>Professional ASP.NET 2.0 Security, Membership, and Role Management.</em>
          </strong>
        </p>
        <iframe style="WIDTH: 120px; HEIGHT: 240px" marginwidth="0" marginheight="0" src="http://rcm.amazon.com/e/cm?t=manuelabadias-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0764596985&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" frameborder="0" scrolling="no">
        </iframe>
        <p>
I suggest you to read it if you really want to get deep into providers as it is an
excellent book.
</p>
        <p>
The NHCustomMembershipProvider uses NHibernate to do all membership related database
operations so it should work on all databases supported by NHibernate. The membership
data will be stored and retrieved from a table configured in the provider section
in the web.config so you can map it to an existing table like users. The column names
for your user table can also be configured in the provider section. The cool thing
about the provider is that it adapts its behaviour to the number of columns supported
by your data store. For example, if you use the provider and map it to your users
table where you only have the membership data for userId, userName, password and email,
it will work without any problem. If your data store supports more advanced options
of the membership provider like account lockout, password question and answer, password
salt or last activity date, that advanced functionality will be automatically available,
but it is not required. 
</p>
        <p>
The provider knows what functionality to offer based on the number of columns that
are mapped to your data store. To support account lockout when the user do not supply
a valid password after some tries in a predefined period of time you need to map the
isLockedOutColumn, failedPasswordAttemptCountColumn and failedPasswordAttemptWindowStartColumn
to columns in your data store.
</p>
        <p>
The default configuration for the provider is to use integer identities or sequences
for the user identifier, but that can be changed using the userIdType and idGeneratorClass
properties in the provider configuration section.
</p>
        <p>
If you use the provider with an existing user table, probably you will create the
users manually without using the CreateUser method from the membership provider. The
provider exposes the methods CheckPasswordPolicy, ValidatePassword, EncodePassword
and GenerateSalt to allow manual creation of the user in case you need it, without
sacrifying password strength.
</p>
        <p>
To finish with the custom membership provider lets see an example. If you want to
use the membership provider with a table like this (that has columns for all supported
functionality):
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">CREATE TABLE </span>[dbo].[Users](
</p>
          <p style="MARGIN: 0px">
 [userId] [int] <span style="COLOR: blue">IDENTITY</span>(1,1) <span style="COLOR: blue">NOT
NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [username] [nvarchar](50) <span style="COLOR: blue">NOT NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [email] [nvarchar](100) <span style="COLOR: blue">NOT NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [password] [nvarchar](256) <span style="COLOR: blue">NOT NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [passwordSalt] [nvarchar](64) <span style="COLOR: blue">NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [passwordFormat] [int] <span style="COLOR: blue">NOT NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [passwordQuestion] [nvarchar](512) <span style="COLOR: blue">NOT NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [passwordAnswer] [nvarchar](512) <span style="COLOR: blue">NOT NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [failedPasswordAttemptCount] [int] <span style="COLOR: blue">NOT NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [failedPasswordAttemptWindowStart] [smalldatetime] <span style="COLOR: blue">NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [failedPasswordAnswerAttemptCount] [int] <span style="COLOR: blue">NOT NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [failedPasswordAnswerAttemptWindowStart] [smalldatetime] <span style="COLOR: blue">NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [lastPasswordChangedDate] [smalldatetime] <span style="COLOR: blue">NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [creationDate] [smalldatetime] <span style="COLOR: blue">NOT NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [lastActivityDate] [smalldatetime] <span style="COLOR: blue">NOT NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [isApproved] [bit] <span style="COLOR: blue">NOT NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [isLockedOut] [bit] <span style="COLOR: blue">NOT NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [lastLockOutDate] [smalldatetime] <span style="COLOR: blue">NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [lastLoginDate] [smalldatetime] <span style="COLOR: blue">NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [name] [nvarchar](256) <span style="COLOR: blue">NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [surname] [nvarchar](256) <span style="COLOR: blue">NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [address] [nvarchar](256) <span style="COLOR: blue">NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [phone] [nvarchar](16) <span style="COLOR: blue">NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [postalCode] [nvarchar](50) <span style="COLOR: blue">NULL</span>,
</p>
          <p style="MARGIN: 0px">
 [comments] [nvarchar](<span style="COLOR: blue">max</span>) <span style="COLOR: blue">NULL</span>,
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">CONSTRAINT </span>[PK_Users] <span style="COLOR: blue">PRIMARY
KEY CLUSTERED </span></p>
          <p style="MARGIN: 0px">
    (
</p>
          <p style="MARGIN: 0px">
    [userId] <span style="COLOR: blue">ASC</span></p>
          <p style="MARGIN: 0px">
    )
</p>
          <p style="MARGIN: 0px">
)
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
The configuration section for the membership provider will be something like this:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span>
            <span style="COLOR: #a31515">membership</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">defaultProvider</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">NHCustomMembershipProvider</span>"<span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: #a31515">providers</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;</span>
            <span style="COLOR: #a31515">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">NHCustomMembershipProvider</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">NHCustomProviders.NHCustomMembershipProvider,
NHCustomProviders</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">enablePasswordReset</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">true</span>"<span style="COLOR: blue"></span><span style="COLOR: red">enablePasswordRetrieval</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">true</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">minRequiredNonAlphanumericCharacters</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">1</span>"<span style="COLOR: blue"></span><span style="COLOR: red">minRequiredPasswordLength</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">6</span>"<span style="COLOR: blue"></span><span style="COLOR: red">passwordFormat</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">Encrypted</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">maxInvalidPasswordAttempts</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">5</span>"<span style="COLOR: blue"></span><span style="COLOR: red">passwordAttemptWindow</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">5</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">requiresQuestionAndAnswer</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">true</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">requiresUniqueEmail</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">false</span>"
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">tableName</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">USERS</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">userIdColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">USERID</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">userIdType</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">Int32</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">idGeneratorClass</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">native</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">userNameColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">USERNAME</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">emailColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">EMAIL</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">passwordColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">PASSWORD</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">passwordSaltColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">PASSWORDSALT</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">passwordFormatColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">PASSWORDFORMAT</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">passwordQuestionColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">PASSWORDQUESTION</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">passwordAnswerColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">PASSWORDANSWER</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">failedPasswordAttemptCountColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">FAILEDPASSWORDATTEMPTCOUNT</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">failedPasswordAttemptWindowStartColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">FAILEDPASSWORDATTEMPTWINDOWSTART</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">failedPasswordAnswerAttemptCountColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">FAILEDPASSWORDANSWERATTEMPTCOUNT</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">failedPasswordAnswerAttemptWindowStartColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">FAILEDPASSWORDANSWERATTEMPTWINDOWSTART</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">lastPasswordChangedDateColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">LASTPASSWORDCHANGEDDATE</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">creationDateColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">CREATIONDATE</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">lastActivityDateColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">LASTACTIVITYDATE</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">isApprovedColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">ISAPPROVED</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">isLockedOutColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">ISLOCKEDOUT</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">lastLockOutDateColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">LASTLOCKOUTDATE</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">lastLoginDateColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">LASTLOGINDATE</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">commentsColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">COMMENTS</span>"
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">userNameColumnSize</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">50</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">emailColumnSize</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">50</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">passwordColumnSize</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">256</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">passwordSaltColumnSize</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">64</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">passwordQuestionColumnSize</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">512</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">passwordAnswerColumnSize</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">512</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">passwordSaltSize</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">16</span>"
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">raiseSystemEvents</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">true</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">dynamicUpdate</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">true</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    /&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;/</span>
            <span style="COLOR: #a31515">providers</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;/</span>
            <span style="COLOR: #a31515">membership</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <p>
          <!--EndFragment-->
          <br />
    
<br />
The column sizes are optional but it is a good practice to fill them.
</p>
        <p>
The built-in provider raises events after a succesfully or a failed login. However,
ASP.NET 2.0 does not allow to create or raise built-in health monitoring events, so
I had to use reflection in a private method in order to raise the same events. That
means that the provider will not run in medium trust if it is not installed in the
GAC if you want to raise the system events. As this can be a showstopper to some people
I have added an option to disable system events generation (raiseSystemEvents).
</p>
        <p>
The provider reads the config section and programatically generates a mapping for
the specified columns in the ConfigureNHibernate method. The provider expects that
you have configured NHibernate in the web.config to work. If you need extra configuration
for the provider you can inherit from the provider and use override the ConfigureNHibernate
method, modifying the Configuration object that the base class returns.
</p>
        <p>
The NHCustomRoleProvider is also configurable in order adapt to your own tables. It
only needs a Users table with id and user name columns, a roles table with id and
role name columns, and a join table used to store the information for the many-to-many
relationship between the users and roles.
</p>
        <p>
For example, if we the previous user table with the following tables (FKs omitted
for brevity):
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">CREATE TABLE </span>[dbo].[Roles](
</p>
          <p style="MARGIN: 0px">
    [roleId] [int] <span style="COLOR: blue">IDENTITY</span>(1,1) <span style="COLOR: blue">NOT
NULL</span>,
</p>
          <p style="MARGIN: 0px">
    [name] [nvarchar](50) <span style="COLOR: blue">NOT NULL</span>,
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">CONSTRAINT </span>[PK_Roles] <span style="COLOR: blue">PRIMARY
KEY CLUSTERED </span></p>
          <p style="MARGIN: 0px">
    (
</p>
          <p style="MARGIN: 0px">
       [roleId] <span style="COLOR: blue">ASC</span></p>
          <p style="MARGIN: 0px">
    )
</p>
          <p style="MARGIN: 0px">
)
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">CREATE TABLE </span>[dbo].[Users_In_Roles](
</p>
          <p style="MARGIN: 0px">
    [userId] [int] <span style="COLOR: blue">NOT NULL</span>,
</p>
          <p style="MARGIN: 0px">
    [roleId] [int] <span style="COLOR: blue">NOT NULL</span>,
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">CONSTRAINT </span>[PK_UsersInRoles] <span style="COLOR: blue">PRIMARY
KEY CLUSTERED </span></p>
          <p style="MARGIN: 0px">
    (
</p>
          <p style="MARGIN: 0px">
       [userId] <span style="COLOR: blue">ASC</span>,
</p>
          <p style="MARGIN: 0px">
       [roleId] <span style="COLOR: blue">ASC</span></p>
          <p style="MARGIN: 0px">
    )
</p>
          <p style="MARGIN: 0px">
)
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
The configuration section for the role provider will be something like this:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span>
            <span style="COLOR: #a31515">roleManager</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">defaultProvider</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">NHCustomRoleProvider</span>"<span style="COLOR: blue"></span><span style="COLOR: red">enabled</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">true</span>"<span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: #a31515">providers</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;</span>
            <span style="COLOR: #a31515">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">NHCustomRoleProvider</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">NHCustomProviders.NHCustomRoleProvider,
NHCustomProviders</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">userTableName</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">USERS</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">userIdColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">USERID</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">userIdType</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">Int32</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">userIdGeneratorClass</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">native</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">userNameColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">USERNAME</span>"
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">roleTableName</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">ROLES</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">roleIdColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">ROLEID</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">roleIdType</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">Int32</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">roleIdGeneratorClass</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">native</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">roleNameColumn</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">NAME</span>"
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">joinTableName</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">USERS_IN_ROLES</span>"
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">userNameColumnSize</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">50</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        </span>
            <span style="COLOR: red">roleNameColumnSize</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">50</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    /&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;/</span>
            <span style="COLOR: #a31515">providers</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;/</span>
            <span style="COLOR: #a31515">roleManager</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
          <br />
Note that the id columns in the join table need be named as in their respective tables
in order to work.<br />
    
<br />
Programatically creating the mapping using the CreateMappings for something more complex
than a single table seems to be something very tied to the NHibernate implementation
so I opted to create a XmlDocument with the mapping read from the configuration settings
as it seems to be the best thing to do in complex cases.
</p>
        <p>
One of the problems I faced with the NHCustomRoleProvider is that some times I wanted
to save or delete data from one side of the many-to-many relationship but in some
cases I wanted to use the other side. If you know a bit of NHibernate you know that
the inverse attribute controls what side of the relationship has to be used in order
to have changes persisted. As I was generating the mapping dynamically I created two
session factories, one with the inverse set to true on one side and the other with
the inverse in the other side. That way I open a connection in the session factory
that has the mapping with the inverse in the side of the relationship I want.
</p>
        <p>
I'd appreciate usage feedback, suggestions, bug reports, etc. I have only tried these
providers with NHibernate 1.2.0 GA and the MsSql2005Dialect so let me know if
it works in other configurations.
</p>
        <p>
Please do not store the providers in your server. Link to this page instead. Updates
to the providers will be posted in this page. 
</p>
        <p>
          <font size="4">
            <strong>
              <em>History</em>
            </strong>
          </font>
        </p>
        <p>
          <strong>v1.0 - 08/04/2007</strong>
        </p>
        <p>
          <strong>v1.1 - 21/06/2007</strong>
        </p>
        <ul dir="ltr" style="MARGIN-RIGHT: 0px">
          <li>
Now using NHibernate 1.2.0 GA 
</li>
          <li>
Some minor fixes</li>
        </ul>
        <p>
          <strong>v1.2 - 12/10/2007:</strong>
        </p>
        <ul>
          <li>
Fixed an important bug that didn’t prevent locked out users from login in. 
</li>
          <li>
Added a CreateUserWizardEx control that allows creating a user with extra information
in an easy way. 
</li>
          <li>
Added auto unlock support. 
</li>
          <li>
Fixed some minor bugs/typos.</li>
        </ul>
        <p>
For more details about the features introduced in version 1.2 take a look <a href="http://www.manuelabadia.com/blog/PermaLink,guid,27e22b2c-af95-4f4c-befd-1debc5841735.aspx">here</a>.
</p>
        <p>
          <strong>v2.0 - 01/08/2008:</strong>
        </p>
        <p>
For more details about the features introduced in version 2.0 and a sample of its
usage take a look <a href="http://www.manuelabadia.com/blog/PermaLink,guid,a93878c1-bd98-40d1-81cb-8bbfb6f0bb63.aspx">here</a>.
</p>
        <p>
          <a href="http://www.manuelabadia.com/blog/content/binary/NHCustomProviders_bin.zip">NHCustomProviders_bin.zip
(67 KB)</a>
          <br />
          <a href="http://www.manuelabadia.com/blog/content/binary/NHCustomProviders_source.zip">NHCustomProviders_source.zip
(122 KB)</a>
        </p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=3b6ccb3f-2f2a-4dcb-a414-605371a00618" />
      </body>
      <title>Custom Membership and Role Providers using NHibernate</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,3b6ccb3f-2f2a-4dcb-a414-605371a00618.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,3b6ccb3f-2f2a-4dcb-a414-605371a00618.aspx</link>
      <pubDate>Sun, 08 Apr 2007 16:21:02 GMT</pubDate>
      <description>&lt;p&gt;
Usually, the built-in providers for ASP.NET do not integrate very well with existing
applications. The membership provider has a very complex structure that in most cases
is not needed at all. The following diagram shows most of the tables and relations
for the built-in ASP.NET providers:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/providers.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The membership related tables are selected in red and the role related tables are
selected in blue. The default membership and roles provider have support to store
data for multiple applications using the aspnet_Applications table. I think this table
was introduced because some portal frameworks like dotnetnuke needed the ability to
store membership and role data for multiple users in a single store because they support
multiple portals. If you don't need this scenario (and most applications do not need
it), this only complicate things.
&lt;/p&gt;
&lt;p&gt;
Also, the built-in providers use tables that are not part of your application tables,
and some of those tables have quite a few columns, and probably some are not needed
by your application.
&lt;/p&gt;
&lt;p&gt;
If you do not use SQL Server, you can not use the default providers, so that is a
big showstopper.
&lt;/p&gt;
&lt;p&gt;
To overcome all of this problems I have created a custom membership and role provider
that use NHibernate and can be easily integrated with existing or future applications
using your own tables.
&lt;/p&gt;
&lt;p&gt;
The reference book about providers is:
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;&lt;em&gt;Professional ASP.NET 2.0 Security, Membership, and Role Management.&lt;/em&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;iframe style="WIDTH: 120px; HEIGHT: 240px" marginwidth=0 marginheight=0 src="http://rcm.amazon.com/e/cm?t=manuelabadias-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=0764596985&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;lc1=0000FF&amp;amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;amp;f=ifr" frameborder=0 scrolling=no&gt;
&lt;/iframe&gt;
&lt;p&gt;
I suggest you to read it if you really want to get deep into providers as it is an
excellent book.
&lt;/p&gt;
&lt;p&gt;
The NHCustomMembershipProvider uses NHibernate to do all membership related database
operations so it should work on all databases supported by NHibernate. The membership
data will be stored and retrieved from a table configured in the provider section
in the web.config so you can map it to an existing table like users. The column names
for your user table can also be configured in the provider section. The cool thing
about the provider is that it adapts its behaviour to the number of columns supported
by your data store. For example, if you use the provider and map it to your users
table where you only have the membership data for userId, userName, password and email,
it will work without any problem. If your data store supports more advanced options
of the membership provider like account lockout, password question and answer, password
salt or last activity date, that advanced functionality will be automatically available,
but it is not required. 
&lt;/p&gt;
&lt;p&gt;
The provider knows what functionality to offer based on the number of columns that
are mapped to your data store. To support account lockout when the user do not supply
a valid password after some tries in a predefined period of time you need to map the
isLockedOutColumn, failedPasswordAttemptCountColumn and failedPasswordAttemptWindowStartColumn
to columns in your data store.
&lt;/p&gt;
&lt;p&gt;
The default configuration for the provider is to use integer identities or sequences
for the user identifier, but that can be changed using the userIdType and idGeneratorClass
properties in the provider configuration section.
&lt;/p&gt;
&lt;p&gt;
If you use the provider with an existing user table, probably you will create the
users manually without using the CreateUser method from the membership provider. The
provider exposes the methods CheckPasswordPolicy, ValidatePassword, EncodePassword
and GenerateSalt to allow manual creation of the user in case you need it, without
sacrifying password strength.
&lt;/p&gt;
&lt;p&gt;
To finish with the custom membership provider lets see an example. If you want to
use the membership provider with a table like this (that has columns for all supported
functionality):
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;CREATE TABLE &lt;/span&gt;[dbo].[Users](
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[userId] [int] &lt;span style="COLOR: blue"&gt;IDENTITY&lt;/span&gt;(1,1) &lt;span style="COLOR: blue"&gt;NOT
NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[username] [nvarchar](50) &lt;span style="COLOR: blue"&gt;NOT NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[email] [nvarchar](100) &lt;span style="COLOR: blue"&gt;NOT NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[password] [nvarchar](256) &lt;span style="COLOR: blue"&gt;NOT NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[passwordSalt] [nvarchar](64) &lt;span style="COLOR: blue"&gt;NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[passwordFormat] [int] &lt;span style="COLOR: blue"&gt;NOT NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[passwordQuestion] [nvarchar](512) &lt;span style="COLOR: blue"&gt;NOT NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[passwordAnswer] [nvarchar](512) &lt;span style="COLOR: blue"&gt;NOT NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[failedPasswordAttemptCount] [int] &lt;span style="COLOR: blue"&gt;NOT NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[failedPasswordAttemptWindowStart] [smalldatetime] &lt;span style="COLOR: blue"&gt;NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[failedPasswordAnswerAttemptCount] [int] &lt;span style="COLOR: blue"&gt;NOT NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[failedPasswordAnswerAttemptWindowStart] [smalldatetime] &lt;span style="COLOR: blue"&gt;NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[lastPasswordChangedDate] [smalldatetime] &lt;span style="COLOR: blue"&gt;NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[creationDate] [smalldatetime] &lt;span style="COLOR: blue"&gt;NOT NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[lastActivityDate] [smalldatetime] &lt;span style="COLOR: blue"&gt;NOT NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[isApproved] [bit] &lt;span style="COLOR: blue"&gt;NOT NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[isLockedOut] [bit] &lt;span style="COLOR: blue"&gt;NOT NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[lastLockOutDate] [smalldatetime] &lt;span style="COLOR: blue"&gt;NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[lastLoginDate] [smalldatetime] &lt;span style="COLOR: blue"&gt;NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[name] [nvarchar](256) &lt;span style="COLOR: blue"&gt;NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[surname] [nvarchar](256) &lt;span style="COLOR: blue"&gt;NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[address] [nvarchar](256) &lt;span style="COLOR: blue"&gt;NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[phone] [nvarchar](16) &lt;span style="COLOR: blue"&gt;NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[postalCode] [nvarchar](50) &lt;span style="COLOR: blue"&gt;NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;[comments] [nvarchar](&lt;span style="COLOR: blue"&gt;max&lt;/span&gt;) &lt;span style="COLOR: blue"&gt;NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;CONSTRAINT &lt;/span&gt;[PK_Users] &lt;span style="COLOR: blue"&gt;PRIMARY
KEY CLUSTERED &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; [userId] &lt;span style="COLOR: blue"&gt;ASC&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;
)
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
The configuration section for the membership provider will be something like this:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;membership&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;defaultProvider&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;NHCustomMembershipProvider&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;providers&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;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;NHCustomMembershipProvider&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;NHCustomProviders.NHCustomMembershipProvider,
NHCustomProviders&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;enablePasswordReset&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;true&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;enablePasswordRetrieval&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;true&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;minRequiredNonAlphanumericCharacters&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;1&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;minRequiredPasswordLength&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;6&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;passwordFormat&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Encrypted&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxInvalidPasswordAttempts&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;5&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;passwordAttemptWindow&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;5&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;requiresQuestionAndAnswer&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;true&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;requiresUniqueEmail&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;false&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;tableName&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;USERS&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;userIdColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;USERID&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;userIdType&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Int32&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;idGeneratorClass&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;native&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;userNameColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;USERNAME&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;emailColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;EMAIL&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;passwordColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;PASSWORD&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;passwordSaltColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;PASSWORDSALT&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;passwordFormatColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;PASSWORDFORMAT&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;passwordQuestionColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;PASSWORDQUESTION&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;passwordAnswerColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;PASSWORDANSWER&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;failedPasswordAttemptCountColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;FAILEDPASSWORDATTEMPTCOUNT&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;failedPasswordAttemptWindowStartColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;FAILEDPASSWORDATTEMPTWINDOWSTART&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;failedPasswordAnswerAttemptCountColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;FAILEDPASSWORDANSWERATTEMPTCOUNT&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;failedPasswordAnswerAttemptWindowStartColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;FAILEDPASSWORDANSWERATTEMPTWINDOWSTART&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;lastPasswordChangedDateColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;LASTPASSWORDCHANGEDDATE&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;creationDateColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;CREATIONDATE&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;lastActivityDateColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;LASTACTIVITYDATE&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;isApprovedColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;ISAPPROVED&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;isLockedOutColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;ISLOCKEDOUT&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;lastLockOutDateColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;LASTLOCKOUTDATE&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;lastLoginDateColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;LASTLOGINDATE&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;commentsColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;COMMENTS&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;userNameColumnSize&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;50&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;emailColumnSize&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;50&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;passwordColumnSize&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;256&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;passwordSaltColumnSize&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;64&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;passwordQuestionColumnSize&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;512&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;passwordAnswerColumnSize&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;512&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;passwordSaltSize&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;16&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;raiseSystemEvents&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;true&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;dynamicUpdate&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;true&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; /&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;providers&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: #a31515"&gt;membership&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
The column sizes are optional but it is a good practice to fill them.
&lt;/p&gt;
&lt;p&gt;
The built-in provider raises events after a succesfully or a failed login. However,
ASP.NET 2.0 does not allow to create or raise built-in health monitoring events, so
I had to use reflection in a private method in order to raise the same events. That
means that the provider will not run in medium trust if it is not installed in the
GAC if you want to raise the system events. As this can be a showstopper to some people
I have added an option to disable system events generation (raiseSystemEvents).
&lt;/p&gt;
&lt;p&gt;
The provider reads the config section and programatically generates a mapping for
the specified columns in the ConfigureNHibernate method. The provider expects that
you have configured NHibernate in the web.config to work. If you need extra configuration
for the provider you can inherit from the provider and use override the ConfigureNHibernate
method, modifying the Configuration object that the base class returns.
&lt;/p&gt;
&lt;p&gt;
The NHCustomRoleProvider is also configurable in order adapt to your own tables. It
only needs a Users table with id and user name columns, a roles table with id and
role name columns, and a join table used to store the information for the many-to-many
relationship between the users and roles.
&lt;/p&gt;
&lt;p&gt;
For example, if we the previous user table with the following tables (FKs omitted
for brevity):
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;CREATE TABLE &lt;/span&gt;[dbo].[Roles](
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [roleId] [int] &lt;span style="COLOR: blue"&gt;IDENTITY&lt;/span&gt;(1,1) &lt;span style="COLOR: blue"&gt;NOT
NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [name] [nvarchar](50) &lt;span style="COLOR: blue"&gt;NOT NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;CONSTRAINT &lt;/span&gt;[PK_Roles] &lt;span style="COLOR: blue"&gt;PRIMARY
KEY CLUSTERED &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;&amp;nbsp; [roleId] &lt;span style="COLOR: blue"&gt;ASC&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;
)
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;CREATE TABLE &lt;/span&gt;[dbo].[Users_In_Roles](
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [userId] [int] &lt;span style="COLOR: blue"&gt;NOT NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [roleId] [int] &lt;span style="COLOR: blue"&gt;NOT NULL&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;CONSTRAINT &lt;/span&gt;[PK_UsersInRoles] &lt;span style="COLOR: blue"&gt;PRIMARY
KEY CLUSTERED &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;&amp;nbsp; [userId] &lt;span style="COLOR: blue"&gt;ASC&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; [roleId] &lt;span style="COLOR: blue"&gt;ASC&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;
)
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The configuration section for the role provider will be something like this:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;roleManager&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;defaultProvider&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;NHCustomRoleProvider&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;enabled&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;true&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;providers&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;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;NHCustomRoleProvider&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;NHCustomProviders.NHCustomRoleProvider,
NHCustomProviders&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;userTableName&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;USERS&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;userIdColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;USERID&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;userIdType&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Int32&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;userIdGeneratorClass&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;native&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;userNameColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;USERNAME&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;roleTableName&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;ROLES&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;roleIdColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;ROLEID&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;roleIdType&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Int32&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;roleIdGeneratorClass&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;native&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;roleNameColumn&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;NAME&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;joinTableName&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;USERS_IN_ROLES&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;userNameColumnSize&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;50&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;roleNameColumnSize&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;50&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; /&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;providers&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: #a31515"&gt;roleManager&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
Note that the id columns in the join table need be named as in their respective tables
in order to work.&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
Programatically creating the mapping using the CreateMappings for something more complex
than a single table seems to be something very tied to the NHibernate implementation
so I opted to create a XmlDocument with the mapping read from the configuration settings
as it seems to be the best thing to do in complex cases.
&lt;/p&gt;
&lt;p&gt;
One of the problems I faced with the NHCustomRoleProvider is that some times I wanted
to save or delete data from one side of the many-to-many relationship but in some
cases I wanted to use the other side. If you know a bit of NHibernate you know that
the inverse attribute controls what side of the relationship has to be used in order
to have changes persisted. As I was generating the mapping dynamically I created two
session factories, one with the inverse set to true on one side and the other with
the inverse in the other side. That way I open a connection in the session factory
that has the mapping with the inverse in the side of the relationship I want.
&lt;/p&gt;
&lt;p&gt;
I'd appreciate usage feedback, suggestions, bug reports, etc. I have only tried these
providers with NHibernate 1.2.0&amp;nbsp;GA and the MsSql2005Dialect so let me know if
it works in other configurations.
&lt;/p&gt;
&lt;p&gt;
Please do not store the providers in your server. Link to this page instead. Updates
to the providers will be posted in this page. 
&lt;/p&gt;
&lt;p&gt;
&lt;font size=4&gt;&lt;strong&gt;&lt;em&gt;History&lt;/em&gt;&lt;/strong&gt;&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;v1.0&amp;nbsp;-&amp;nbsp;08/04/2007&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;v1.1 - 21/06/2007&lt;/strong&gt;
&lt;/p&gt;
&lt;ul dir=ltr style="MARGIN-RIGHT: 0px"&gt;
&lt;li&gt;
Now using NHibernate 1.2.0 GA 
&lt;li&gt;
Some minor fixes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;strong&gt;v1.2&amp;nbsp;- 12/10/2007:&lt;/strong&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
Fixed an important bug that didn’t prevent locked out users from login in. 
&lt;li&gt;
Added a CreateUserWizardEx control that allows creating a user with extra information
in an easy way. 
&lt;li&gt;
Added auto unlock support. 
&lt;li&gt;
Fixed some minor bugs/typos.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
For more details about the features introduced in version 1.2 take a look &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,27e22b2c-af95-4f4c-befd-1debc5841735.aspx"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;v2.0&amp;nbsp;- 01/08/2008:&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
For more details about the features introduced in version 2.0 and a sample of its
usage&amp;nbsp;take a look &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,a93878c1-bd98-40d1-81cb-8bbfb6f0bb63.aspx"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.manuelabadia.com/blog/content/binary/NHCustomProviders_bin.zip"&gt;NHCustomProviders_bin.zip
(67 KB)&lt;/a&gt;
&lt;br&gt;
&lt;a href="http://www.manuelabadia.com/blog/content/binary/NHCustomProviders_source.zip"&gt;NHCustomProviders_source.zip
(122 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=3b6ccb3f-2f2a-4dcb-a414-605371a00618" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,3b6ccb3f-2f2a-4dcb-a414-605371a00618.aspx</comments>
      <category>ASP.NET;Microsoft .NET Framework;NHibernate</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=91a1d00f-197e-4148-b4e1-cea324029dc6</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,91a1d00f-197e-4148-b4e1-cea324029dc6.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,91a1d00f-197e-4148-b4e1-cea324029dc6.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=91a1d00f-197e-4148-b4e1-cea324029dc6</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In a previous <a href="http://www.manuelabadia.com/blog/PermaLink,guid,560b6980-d109-4047-a886-4c523f090522.aspx">post</a> I
said that the ObjectDataSource can handle generic types using the backtick (`) notation,
even if the ObjectDataSource doesn't have any design time support for this. 
</p>
        <p>
This works because the ObjectDataSource internally calls to Type.GetType to resolve
type names to Type objects. As the Type.GetType method handle generics transparently,
the ObjectDataSource does not have to do anything special to support it at runtime.
Supporting generic types at design time is more complex so they fiter out generic
types in the "Select Type" wizard step.
</p>
        <p>
For generic methods things change. There is some inconsistency in generics handling
in the .NET Framework. If you get the type of a class like List&lt;Customer&gt;, its
Name is List`1[Customer]. However, if you have a method like Customer Get&lt;Customer&gt;(int
id), the method name is Get. IMHO, to have an orthogonal implementation, the method
name should be Get`1[Customer]. Also, the GetMethod method should understand the backtick
notation for methods and retrieve the specified method properly but it isn't supported
for now. I have requested an improvement for the next version of the .NET framework <a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=265628">here</a>.
Probably they won't fix it but it would be nice if you vote for it.
</p>
        <p>
Returning to the ObjectDataSource... When the ObjectDataSource tries to find a method,
it call the GetMethods method and compares the method name with the expected name,
filtering out generic methods.
</p>
        <p>
So, I think Microsoft didn't bother to add support for generic types or generic methods,
and if generic types work at runtime is by luck (because of the GetType behaviour).
</p>
        <p>
As more developers are using generics, there is a need to properly support generic
methods and generic types. The next version of the ExtendedObjectDataSource (that
will be released next week), will have full generics support, at design time and at
runtime.
</p>
        <p>
It wasn't easy to add design time support for generics as several problems appeared:
</p>
        <p>
* Generic type expressions and generic method expressions can be arbitrarily complex
(like MyGraph`2[[Utilities.Set, Utilities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a7a65c534534e209],[Utilities.Graph,
Utilities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a7a65c534534e209]], MyGraphLibrary,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=2134afb4534e209), so I had to write
a parser for both kinds of expressions.<br />
 <br />
* At runtime, specifying "__code" for the assembly name gets traslated to the dynamically
generated assembly (as explained in the previous post). However, at design time this
translation has to be done manually.<br />
 <br />
* I had to rewrite the select type wizard step and select method wizard step as the
code was getting harder to maintain with generics.
</p>
        <p>
* Showing and choosing generic methods and types is half of the problem, after choosing
them you have to create the generic type or the generic method based on the generic
type definition and the generic method definition.<br />
 <br />
Lets see an example of what can be accomplished now with the CompatObjectDataSource.
</p>
        <p>
Imagine that we want to be able to register some objects at the start of the application
in order to used later using a registry.
</p>
        <p>
The registry can be implemented like this:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: gray">///</span>
            <span style="COLOR: green">
            </span>
            <span style="COLOR: gray">&lt;summary&gt;</span>
            <span style="COLOR: green">Global
Registry.</span>
            <span style="COLOR: gray">&lt;/summary&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">public</span>
            <span style="COLOR: blue">class</span>
            <span style="COLOR: #2b91af">Registry</span>
          </p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    #region</span> Fields
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">private</span><span style="COLOR: blue">static</span><span style="COLOR: #2b91af">Registry</span> _instance
= <span style="COLOR: blue">new</span><span style="COLOR: #2b91af">Registry</span>();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">private</span><span style="COLOR: #2b91af">Hashtable</span> _registryStore
= <span style="COLOR: blue">new</span><span style="COLOR: #2b91af">Hashtable</span>();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    #endregion</span>
          </p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    #region</span> Properties
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;summary&gt;</span><span style="COLOR: green">Gets
the unique instance for this class.</span><span style="COLOR: gray">&lt;/value&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">static</span><span style="COLOR: #2b91af">Registry</span> Instance
</p>
          <p style="MARGIN: 0px">
    {
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> _instance;
}
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    #endregion</span>
          </p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    #region</span> Methods
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;summary&gt;</span><span style="COLOR: green">Private
constructor to avoid creating instances of this class.</span><span style="COLOR: gray">&lt;/summary&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">private</span> Registry() { }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;summary&gt;</span><span style="COLOR: green">Registers
an object.</span><span style="COLOR: gray">&lt;/summary&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;param
name="key"&gt;</span><span style="COLOR: green">The key.</span><span style="COLOR: gray">&lt;/param&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;param
name="obj"&gt;</span><span style="COLOR: green">The object to register.</span><span style="COLOR: gray">&lt;/param&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">void</span> RegisterObject&lt;K,
T&gt;(K key, T obj)
</p>
          <p style="MARGIN: 0px">
    {
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">if</span> (_registryStore.Contains(key))
{
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">throw</span><span style="COLOR: blue">new</span><span style="COLOR: #2b91af">Exception</span>(<span style="COLOR: #2b91af">String</span>.Format(<span style="COLOR: #a31515">"Error,
there is an object stored using the '{0}' key"</span> + key.ToString()));
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        _registryStore[key] = obj;
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;summary&gt;</span><span style="COLOR: green">Registers
an object list.</span><span style="COLOR: gray">&lt;/summary&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;param
name="key"&gt;</span><span style="COLOR: green">The key.</span><span style="COLOR: gray">&lt;/param&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;param
name="objects"&gt;</span><span style="COLOR: green">The object list to register.</span><span style="COLOR: gray">&lt;/param&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">void</span> RegisterObjectList&lt;K,
T&gt;(K key, <span style="COLOR: #2b91af">IList</span>&lt;T&gt; objects)
</p>
          <p style="MARGIN: 0px">
    {
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">if</span> (_registryStore.Contains(key))
{
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">throw</span><span style="COLOR: blue">new</span><span style="COLOR: #2b91af">Exception</span>(<span style="COLOR: #2b91af">String</span>.Format(<span style="COLOR: #a31515">"Error,
there are objects stored using the '{0}' key"</span> + key.ToString()));
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        _registryStore[key] = objects;
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;summary&gt;</span><span style="COLOR: green">Gets
an object from the registry.</span><span style="COLOR: gray">&lt;/summary&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;param
name="key"&gt;</span><span style="COLOR: green">The key.</span><span style="COLOR: gray">&lt;/param&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;returns&gt;</span><span style="COLOR: green">The
object stored on the registry or null if it wasn't found.</span><span style="COLOR: gray">&lt;/returns&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span> T GetObject&lt;K, T&gt;(K
key)
</p>
          <p style="MARGIN: 0px">
    {
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">return</span> (T)_registryStore[key];
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;summary&gt;</span><span style="COLOR: green">Gets
a list of objects from the registry.</span><span style="COLOR: gray">&lt;/summary&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;param
name="key"&gt;</span><span style="COLOR: green">The key.</span><span style="COLOR: gray">&lt;/param&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;returns&gt;</span><span style="COLOR: green">The
list of objects stored on the registry or null if it wasn't found.</span><span style="COLOR: gray">&lt;/returns&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: #2b91af">IList</span>&lt;T&gt;
GetObjectList&lt;K, T&gt;(K key)
</p>
          <p style="MARGIN: 0px">
    {
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">return</span> _registryStore[key] <span style="COLOR: blue">as</span><span style="COLOR: #2b91af">IList</span>&lt;T&gt;;
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    #endregion</span>
          </p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <p>
          <!--EndFragment-->
          <br />
    
<br />
Some of the data stored in the registry when the application starts is a list of all
available countries (for example, retrieved from the database):
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: green">// register the countries</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: #2b91af">Registry</span>.Instance.RegisterObjectList&lt;<span style="COLOR: blue">string</span>, <span style="COLOR: #2b91af">Country</span>&gt;(<span style="COLOR: #a31515">"countries"</span>,
countries);
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
The Country class is very simple:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">namespace</span> Manu.GenericTests
</p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">class</span><span style="COLOR: #2b91af">Country</span></p>
          <p style="MARGIN: 0px">
    {
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">private</span><span style="COLOR: blue">int</span> _id;
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">private</span><span style="COLOR: blue">string</span> _name;
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">private</span><span style="COLOR: blue">string</span> _code;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">public</span><span style="COLOR: blue">int</span> Id
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> _id;
}
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">set</span> {
_id = <span style="COLOR: blue">value</span>; }
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">public</span><span style="COLOR: blue">string</span> Name
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> _name;
}
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">set</span> {
_name = <span style="COLOR: blue">value</span>; }
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">public</span><span style="COLOR: blue">string</span> Code
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> _code;
}
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">set</span> {
_code = <span style="COLOR: blue">value</span>; }
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">public</span> Country()
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">public</span> Country(<span style="COLOR: blue">int</span> id, <span style="COLOR: blue">string</span> name, <span style="COLOR: blue">string</span> code)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            _id = id;
</p>
          <p style="MARGIN: 0px">
            _name = name;
</p>
          <p style="MARGIN: 0px">
            _code = code;
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
If we want to show all the countries in any webform we can use an CompatObjectDataSource.
After dropping one to the toolbox we configure the type:
</p>
        <p>
          <img src="http://www.manuelabadia.com/blog/content/binary/EODS_designer1.png" border="0" />
        </p>
        <p>
And then we can see the list of methods compatible with the Select operation (GetObject
and GetObjectList):
</p>
        <p>
          <img src="http://www.manuelabadia.com/blog/content/binary/EODS_designer2.png" border="0" />
        </p>
        <p>
As both methods are generic method definitions, after selecting one of them, we have
to specify the generic parameters. In our case, we stored the countries using a string
key, and we stored a List of Country objects so the generic parameters for the method
are System.String, Manu.GenericTests.Country. After clicking in "Make Generic Method"
we have the data source configured properly:
</p>
        <p>
          <img src="http://www.manuelabadia.com/blog/content/binary/EODS_designer3.png" border="0" />
        </p>
        <p>
If we take a look to the ASPX we can see the following code:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span>
            <span style="COLOR: #a31515">manu</span>
            <span style="COLOR: blue">:</span>
            <span style="COLOR: #a31515">CompatObjectDataSource</span>
            <span style="COLOR: red">ID</span>
            <span style="COLOR: blue">="CompatObjectDataSource1"</span>
            <span style="COLOR: red">runat</span>
            <span style="COLOR: blue">="server"</span>
          </p>
          <p style="MARGIN: 0px">
    <span style="COLOR: red">SelectMethod</span><span style="COLOR: blue">="GetObjectList`2[System.String,
[Manu.GenericTests.Country, __code]]"</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: red">TypeName</span><span style="COLOR: blue">="Manu.GenericTests.Registry,
__code"</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: red">OnObjectCreating</span><span style="COLOR: blue">="ObjectDataSource1_ObjectCreating"&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">SelectParameters</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span><span style="COLOR: #a31515">asp</span><span style="COLOR: blue">:</span><span style="COLOR: #a31515">Parameter</span><span style="COLOR: red">Name</span><span style="COLOR: blue">="key"</span><span style="COLOR: red">Type</span><span style="COLOR: blue">="String"</span><span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">&lt;/</span><span style="COLOR: #a31515">SelectParameters</span><span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;/</span>
            <span style="COLOR: #a31515">manu</span>
            <span style="COLOR: blue">:</span>
            <span style="COLOR: #a31515">CompatObjectDataSource</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
The SelectMethod is saved as "GetObjectList`2[System.String, [Manu.GenericTests.Country,
__code]]" and the TypeName is saved as "Manu.GenericTests.Registry, __code".
</p>
        <p>
The only thing to do now is to set the DefaultValue property for the key parameter
to countries. Now the CompatObjectDataSource has enough information to call to GetObjectList&lt;string,
Country&gt;("countries") from the Registry class and retrieve the countries.
</p>
        <p>
The only thing I'm missing in the CompatObjectDataSource/ExtendedObjectDataSource
is support for Bind expressions for nested properties (&lt;%# Bind(Address.PostalCode)
%&gt;), but unfortunately, the framework can not understand those expressions so nothing
can be done ast the moment. I wrote an email to <a href="http://weblogs.asp.net/scottgu/">ScottGu</a> about
that and got this reply from <a href="http://www.shankun.com/">Shanku Niyogi</a>:
</p>
        <p>
          <em>
            <strong>"This is definitely a doable thing - we'll add it to our list of items
we're considering adding for an upcoming release."</strong>
          </em>
        </p>
        <p>
So keep your fingers crossed.
</p>
        <p>
I'm open to suggestions in what to functionality you would like to see in the ObjectDataSource/CompatObjectDataSource/ExtendedObjectDataSource.
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=91a1d00f-197e-4148-b4e1-cea324029dc6" />
      </body>
      <title>ObjectDataSource and Generics (part 2)</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,91a1d00f-197e-4148-b4e1-cea324029dc6.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,91a1d00f-197e-4148-b4e1-cea324029dc6.aspx</link>
      <pubDate>Tue, 27 Mar 2007 22:35:22 GMT</pubDate>
      <description>&lt;p&gt;
In a previous &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,560b6980-d109-4047-a886-4c523f090522.aspx"&gt;post&lt;/a&gt; I
said that the ObjectDataSource can handle generic types using the backtick (`) notation,
even if the ObjectDataSource doesn't have any design time support for this. 
&lt;/p&gt;
&lt;p&gt;
This works because the ObjectDataSource internally calls to Type.GetType to resolve
type names to Type objects. As the Type.GetType method handle generics transparently,
the ObjectDataSource does not have to do anything special to support it at runtime.
Supporting generic types at design time is more complex so they fiter out generic
types in the "Select Type" wizard step.
&lt;/p&gt;
&lt;p&gt;
For generic methods things change. There is some inconsistency in generics handling
in the .NET Framework. If you get the type of a class like List&amp;lt;Customer&amp;gt;, its
Name is List`1[Customer]. However, if you have a method like Customer Get&amp;lt;Customer&amp;gt;(int
id), the method name is Get. IMHO, to have an orthogonal implementation, the method
name should be Get`1[Customer]. Also, the GetMethod method should understand the backtick
notation for methods and retrieve the specified method properly but it isn't supported
for now. I have requested an improvement for the next version of the .NET framework &lt;a href="https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=265628"&gt;here&lt;/a&gt;.
Probably they won't fix it but it would be nice if you vote for it.
&lt;/p&gt;
&lt;p&gt;
Returning to the ObjectDataSource... When the ObjectDataSource tries to find a method,
it call the GetMethods method and compares the method name with the expected name,
filtering out generic methods.
&lt;/p&gt;
&lt;p&gt;
So, I think Microsoft didn't bother to add support for generic types or generic methods,
and if generic types work at runtime is by luck (because of the GetType behaviour).
&lt;/p&gt;
&lt;p&gt;
As more developers are using generics, there is a need to properly support generic
methods and generic types. The next version of the ExtendedObjectDataSource (that
will be released next week), will have full generics support, at design time and at
runtime.
&lt;/p&gt;
&lt;p&gt;
It wasn't easy to add design time support for generics as several problems appeared:
&lt;/p&gt;
&lt;p&gt;
* Generic type expressions and generic method expressions can be arbitrarily complex
(like MyGraph`2[[Utilities.Set, Utilities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a7a65c534534e209],[Utilities.Graph,
Utilities, Version=1.0.0.0, Culture=neutral, PublicKeyToken=a7a65c534534e209]], MyGraphLibrary,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=2134afb4534e209), so I had to write
a parser for both kinds of expressions.&lt;br&gt;
&amp;nbsp;&lt;br&gt;
* At runtime, specifying "__code" for the assembly name gets traslated to the dynamically
generated assembly (as explained in the previous post). However, at design time this
translation has to be done manually.&lt;br&gt;
&amp;nbsp;&lt;br&gt;
* I had to rewrite the select type wizard step and select method wizard step as the
code was getting harder to maintain with generics.
&lt;/p&gt;
&lt;p&gt;
* Showing and choosing generic methods and types is half of the problem, after choosing
them you have to create the generic type or the generic method based on the generic
type definition and the generic method definition.&lt;br&gt;
&amp;nbsp;&lt;br&gt;
Lets see an example of what can be accomplished now with the CompatObjectDataSource.
&lt;/p&gt;
&lt;p&gt;
Imagine that we want to be able to register some objects at the start of the application
in order to used later using a registry.
&lt;/p&gt;
&lt;p&gt;
The registry can be implemented like this:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&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;span style="COLOR: green"&gt;Global
Registry.&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;
&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Registry&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region&lt;/span&gt; Fields
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Registry&lt;/span&gt; _instance
= &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Registry&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;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Hashtable&lt;/span&gt; _registryStore
= &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Hashtable&lt;/span&gt;();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region&lt;/span&gt; Properties
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;span style="COLOR: green"&gt;Gets
the unique instance for this class.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/value&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;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Registry&lt;/span&gt; Instance
&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;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; _instance;
}
&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;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #region&lt;/span&gt; Methods
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;span style="COLOR: green"&gt;Private
constructor to avoid creating instances of this class.&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;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; Registry() { }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;span style="COLOR: green"&gt;Registers
an object.&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;&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;param
name="key"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;The key.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;param
name="obj"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;The object to register.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&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;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; RegisterObject&amp;lt;K,
T&amp;gt;(K key, T obj)
&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;span style="COLOR: blue"&gt;if&lt;/span&gt; (_registryStore.Contains(key))
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;throw&lt;/span&gt; &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Exception&lt;/span&gt;(&lt;span style="COLOR: #2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="COLOR: #a31515"&gt;"Error,
there is an object stored using the '{0}' key"&lt;/span&gt; + key.ToString()));
&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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; _registryStore[key] = obj;
&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;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;span style="COLOR: green"&gt;Registers
an object list.&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;&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;param
name="key"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;The key.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;param
name="objects"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;The object list to register.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&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;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; RegisterObjectList&amp;lt;K,
T&amp;gt;(K key, &lt;span style="COLOR: #2b91af"&gt;IList&lt;/span&gt;&amp;lt;T&amp;gt; objects)
&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;span style="COLOR: blue"&gt;if&lt;/span&gt; (_registryStore.Contains(key))
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;throw&lt;/span&gt; &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Exception&lt;/span&gt;(&lt;span style="COLOR: #2b91af"&gt;String&lt;/span&gt;.Format(&lt;span style="COLOR: #a31515"&gt;"Error,
there are objects stored using the '{0}' key"&lt;/span&gt; + key.ToString()));
&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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; _registryStore[key] = objects;
&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;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;span style="COLOR: green"&gt;Gets
an object from the registry.&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;&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;param
name="key"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;The key.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;returns&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;The
object stored on the registry or null if it wasn't found.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/returns&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;public&lt;/span&gt; T GetObject&amp;lt;K, T&amp;gt;(K
key)
&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;span style="COLOR: blue"&gt;return&lt;/span&gt; (T)_registryStore[key];
&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;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;span style="COLOR: green"&gt;Gets
a list of objects from the registry.&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;&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;param
name="key"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;The key.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;returns&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;The
list of objects stored on the registry or null if it wasn't found.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/returns&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;public&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IList&lt;/span&gt;&amp;lt;T&amp;gt;
GetObjectList&amp;lt;K, T&amp;gt;(K key)
&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;span style="COLOR: blue"&gt;return&lt;/span&gt; _registryStore[key] &lt;span style="COLOR: blue"&gt;as&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IList&lt;/span&gt;&amp;lt;T&amp;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;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; #endregion&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
Some of the data stored in the registry when the application starts is a list of all
available countries (for example, retrieved from the database):
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;// register the countries&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;Registry&lt;/span&gt;.Instance.RegisterObjectList&amp;lt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;, &lt;span style="COLOR: #2b91af"&gt;Country&lt;/span&gt;&amp;gt;(&lt;span style="COLOR: #a31515"&gt;"countries"&lt;/span&gt;,
countries);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
The Country class is very simple:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;namespace&lt;/span&gt; Manu.GenericTests
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Country&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;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; _id;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; _name;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; _code;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; Id
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; _id;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; {
_id = &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; &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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; Name
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; _name;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; {
_name = &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; &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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; Code
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; _code;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; {
_code = &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; &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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; Country()
&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;&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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; Country(&lt;span style="COLOR: blue"&gt;int&lt;/span&gt; id, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; name, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; code)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; _id = id;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; _name = name;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; _code = code;
&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;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
If we want to show all the countries in any webform we can use an CompatObjectDataSource.
After dropping one to the toolbox we configure the type:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/EODS_designer1.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
And then we can see the list of methods compatible with the Select operation (GetObject
and GetObjectList):
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/EODS_designer2.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
As both methods are generic method definitions, after selecting one of them, we have
to specify the generic parameters. In our case, we stored the countries using a string
key, and we stored a List of Country objects so the generic parameters for the method
are System.String, Manu.GenericTests.Country. After clicking in "Make Generic Method"
we have the data source configured properly:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/EODS_designer3.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
If we take a look to the ASPX we can see the following code:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;manu&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;CompatObjectDataSource&lt;/span&gt; &lt;span style="COLOR: red"&gt;ID&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="CompatObjectDataSource1"&lt;/span&gt; &lt;span style="COLOR: red"&gt;runat&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="server"&lt;/span&gt; 
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: red"&gt;SelectMethod&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="GetObjectList`2[System.String,
[Manu.GenericTests.Country, __code]]"&lt;/span&gt; 
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: red"&gt;TypeName&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="Manu.GenericTests.Registry,
__code"&lt;/span&gt; 
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: red"&gt;OnObjectCreating&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="ObjectDataSource1_ObjectCreating"&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;SelectParameters&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;asp&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;Parameter&lt;/span&gt; &lt;span style="COLOR: red"&gt;Name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="key"&lt;/span&gt; &lt;span style="COLOR: red"&gt;Type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;="String"&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;SelectParameters&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: #a31515"&gt;manu&lt;/span&gt;&lt;span style="COLOR: blue"&gt;:&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;CompatObjectDataSource&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The SelectMethod is saved as "GetObjectList`2[System.String, [Manu.GenericTests.Country,
__code]]" and the TypeName is saved as "Manu.GenericTests.Registry, __code".
&lt;/p&gt;
&lt;p&gt;
The only thing to do now is to set the DefaultValue property for the key parameter
to countries. Now the CompatObjectDataSource has enough information to call to GetObjectList&amp;lt;string,
Country&amp;gt;("countries")&amp;nbsp;from the Registry class and retrieve the countries.
&lt;/p&gt;
&lt;p&gt;
The only thing I'm missing in the CompatObjectDataSource/ExtendedObjectDataSource
is support for Bind expressions for nested properties (&amp;lt;%# Bind(Address.PostalCode)
%&amp;gt;), but unfortunately, the framework can not understand those expressions so nothing
can be done ast the moment. I wrote an email to &lt;a href="http://weblogs.asp.net/scottgu/"&gt;ScottGu&lt;/a&gt; about
that and got this reply from &lt;a href="http://www.shankun.com/"&gt;Shanku Niyogi&lt;/a&gt;:
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;&lt;strong&gt;"This is definitely a doable thing - we'll add it to our list of items
we're considering adding for an upcoming release."&lt;/strong&gt;&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
So keep your fingers crossed.
&lt;/p&gt;
&lt;p&gt;
I'm open to suggestions in what to functionality you would like to see in the ObjectDataSource/CompatObjectDataSource/ExtendedObjectDataSource.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=91a1d00f-197e-4148-b4e1-cea324029dc6" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,91a1d00f-197e-4148-b4e1-cea324029dc6.aspx</comments>
      <category>ASP.NET;Microsoft .NET Framework</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=50bc4c5a-3e40-4f81-8137-f7843d4a486d</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,50bc4c5a-3e40-4f81-8137-f7843d4a486d.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,50bc4c5a-3e40-4f81-8137-f7843d4a486d.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=50bc4c5a-3e40-4f81-8137-f7843d4a486d</wfw:commentRss>
      <slash:comments>4</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
In <a href="http://www.manuelabadia.com/blog/PermaLink,guid,22a125d3-1ed3-422b-ba2b-89ed63febce3.aspx">my
last post about MS AJAX</a> I gave a brief explanation about the web.config changes
needed and explained the serialization process. 
</p>
        <p>
Now, I'm going to explain how a client proxy is generated. As I told in the last post,
the WebServiceClientProxyGenerator.GetClientProxyScript method was were all the job
was done.
</p>
        <p>
There are a few classes involved in the client proxy generation:
</p>
        <ul>
          <li>
WebServiceTypeData, that is used to store type information about the web service to
call.</li>
          <li>
WebServiceMethodData, that is used to store information about a web service method
(parameters, return type, caching, etc), and it has the functionality to invoke the
method.</li>
          <li>
WebServiceParameterData, used to store information about a parameter of a web service
method.</li>
          <li>
WebServiceData. This class uses the previous classes and has a lot of logic. Basically
a WebServiceData instance is created for each web service to call (for each instance
there is an associated WebServiceTypeData instance). When the web service methods
are required, the EnsureMethods method uses reflection to obtain all WebMethods from
the type (and its ancestors).</li>
        </ul>
        <p>
By default, a web service can't be called from client script. To change this, the
web service needs the ScriptServiceAttribute applied to it.
</p>
        <p>
To be able to call a web method from client script, the parameters and return types
of the web method have to be available in client script, and the web service needs
to have the WebMethodAttribute (the ScriptMethodAttribute should be used only to override
the default invocation method and respone format, that is HTTP POST and JSON). If
a web service method needs a parameter of a custom type, we have to use the GenerateScriptTypeAttribute
attribute in the method or in the web service so MS AJAX will automatically generate
a client side class for that type.
</p>
        <p>
So when the methods are processed, the ClientTypes property will be filled in the
ProcessClientTypes method with a list of the types that need to be available in client
script.
</p>
        <p>
However, the automatic type generation has some limitations, as the GenerateScriptTypeAttribute
can not be applied to types implementing IEnumerable or IDictionary, interfaces, abstract
classes, types without a public parameterless constructor, and generic types with
more than one parameter.
</p>
        <p>
The WebServiceData class also inherits from the JavaScriptTypeResolver class to provide
string to type conversion (and viceversa) for the serialization/deserialization process.
You may be wondering why the SimpleTypeResolver isn't used, but as the GenerateScriptTypeAttribute
has a property called ScriptTypeId that modifies the __type field stored in the JSON,
another type resolver was needed.
</p>
        <p>
As you can see, the WebServiceData class does a lot of work, so to get WebServiceData
instances the static method GetWebServiceData is used because it caches instances
by URL.
</p>
        <p>
If you don't want to create a new class for a few methods, you can add them to your
ASPX page and call them directly. For this to work, the methods should be static and
have the WebMethodAttribute attribute applied.
</p>
        <p>
The ClientProxyGenerator class uses a WebServiceData instance and generates the client
proxy code, although the code calls to the static method GetClientProxyScript of the
WebServiceClientProxyGenerator class to get the generated client proxy code, because
it performs caching based on the web service type and the modified time of the associated
assembly. 
</p>
        <p>
For the following web service:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
[<span style="COLOR: #2b91af">WebService</span>(Namespace = <span style="COLOR: #a31515">"http://tempuri.org/"</span>)]
</p>
          <p style="MARGIN: 0px">
[<span style="COLOR: #2b91af">WebServiceBinding</span>(ConformsTo = <span style="COLOR: #2b91af">WsiProfiles</span>.BasicProfile1_1)]
</p>
          <p style="MARGIN: 0px">
[<span style="COLOR: #2b91af">ScriptService</span>]
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">public</span>
            <span style="COLOR: blue">class</span>
            <span style="COLOR: #2b91af">AjaxWebService</span> {
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    [<span style="COLOR: #2b91af">WebMethod</span>]
</p>
          <p style="MARGIN: 0px">
    [<span style="COLOR: #2b91af">GenerateScriptType</span>(<span style="COLOR: blue">typeof</span>(<span style="COLOR: #2b91af">User</span>))]
</p>
          <p style="MARGIN: 0px">
    [<span style="COLOR: #2b91af">GenerateScriptType</span>(<span style="COLOR: blue">typeof</span>(<span style="COLOR: #2b91af">Address</span>))]
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: #2b91af">User</span> GetModifiedUser(<span style="COLOR: #2b91af">User</span> usr)
{
</p>
          <p style="MARGIN: 0px">
        usr.ID = usr.ID * 2;
</p>
          <p style="MARGIN: 0px">
        usr.Name = <span style="COLOR: #a31515">"Manu"</span>;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">return</span> usr;
</p>
          <p style="MARGIN: 0px">
    }   
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <p>
the User and Address classes were introduced in the previous post.<!--EndFragment--></p>
        <p>
the generated proxy is:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">var</span> AjaxWebService=<span style="COLOR: blue">function</span>()
{
</p>
          <p style="MARGIN: 0px">
    AjaxWebService.initializeBase(<span style="COLOR: blue">this</span>);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>._timeout = 0;
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>._userContext = <span style="COLOR: blue">null</span>;
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>._succeeded = <span style="COLOR: blue">null</span>;
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>._failed = <span style="COLOR: blue">null</span>;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
AjaxWebService.prototype={
</p>
          <p style="MARGIN: 0px">
    GetModifiedUser:<span style="COLOR: blue">function</span>(usr,succeededCallback,
failedCallback, userContext) {
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">return</span><span style="COLOR: blue">this</span>._invoke(AjaxWebService.get_path(), <span style="COLOR: #a31515">'GetModifiedUser'</span>,<span style="COLOR: blue">false</span>,{
</p>
          <p style="MARGIN: 0px">
            usr:usr
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
        ,succeededCallback,failedCallback,userContext);
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
AjaxWebService.registerClass(<span style="COLOR: #a31515">'AjaxWebService'</span>,Sys.Net.WebServiceProxy);
</p>
          <p style="MARGIN: 0px">
AjaxWebService._staticInstance = <span style="COLOR: blue">new</span> AjaxWebService();
</p>
          <p style="MARGIN: 0px">
AjaxWebService.set_path = <span style="COLOR: blue">function</span>(value) {
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">var</span> e = Function._validateParams(arguments,
[{
</p>
          <p style="MARGIN: 0px">
        name: <span style="COLOR: #a31515">'path'</span>,
type: String
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
    ]); <span style="COLOR: blue">if</span> (e) <span style="COLOR: blue">throw</span> e;
AjaxWebService._staticInstance._path = value;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
AjaxWebService.get_path = <span style="COLOR: blue">function</span>() {
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">return</span> AjaxWebService._staticInstance._path;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
AjaxWebService.set_timeout = <span style="COLOR: blue">function</span>(value) {
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">var</span> e = Function._validateParams(arguments,
[{
</p>
          <p style="MARGIN: 0px">
        name: <span style="COLOR: #a31515">'timeout'</span>,
type: Number
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
    ]); <span style="COLOR: blue">if</span> (e) <span style="COLOR: blue">throw</span> e; <span style="COLOR: blue">if</span> (value
&amp;lt; 0) {
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">throw</span> Error.argumentOutOfRange(<span style="COLOR: #a31515">'value'</span>,
value, Sys.Res.invalidTimeout);
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
    AjaxWebService._staticInstance._timeout = value;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
AjaxWebService.get_timeout = <span style="COLOR: blue">function</span>() {
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">return</span> AjaxWebService._staticInstance._timeout;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
AjaxWebService.set_defaultUserContext = <span style="COLOR: blue">function</span>(value)
{
</p>
          <p style="MARGIN: 0px">
    AjaxWebService._staticInstance._userContext = value;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
AjaxWebService.get_defaultUserContext = <span style="COLOR: blue">function</span>()
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">return</span> AjaxWebService._staticInstance._userContext;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
AjaxWebService.set_defaultSucceededCallback = <span style="COLOR: blue">function</span>(value)
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">var</span> e = Function._validateParams(arguments,
[{
</p>
          <p style="MARGIN: 0px">
        name: <span style="COLOR: #a31515">'defaultSucceededCallback'</span>,
type: Function
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
    ]); <span style="COLOR: blue">if</span> (e) <span style="COLOR: blue">throw</span> e;
AjaxWebService._staticInstance._succeeded = value;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
AjaxWebService.get_defaultSucceededCallback = <span style="COLOR: blue">function</span>()
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">return</span> AjaxWebService._staticInstance._succeeded;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
AjaxWebService.set_defaultFailedCallback = <span style="COLOR: blue">function</span>(value)
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">var</span> e = Function._validateParams(arguments,
[{
</p>
          <p style="MARGIN: 0px">
        name: <span style="COLOR: #a31515">'defaultFailedCallback'</span>,
type: Function
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
    ]); <span style="COLOR: blue">if</span> (e) <span style="COLOR: blue">throw</span> e;
AjaxWebService._staticInstance._failed = value;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
AjaxWebService.get_defaultFailedCallback = <span style="COLOR: blue">function</span>()
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">return</span> AjaxWebService._staticInstance._failed;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
AjaxWebService.set_path(<span style="COLOR: #a31515">"/AJAXServerSide1/AjaxWebService.asmx"</span>);
</p>
          <p style="MARGIN: 0px">
AjaxWebService.GetModifiedUser= <span style="COLOR: blue">function</span>(usr,onSuccess,onFailed,userContext)
{
</p>
          <p style="MARGIN: 0px">
    AjaxWebService._staticInstance.GetModifiedUser(usr,onSuccess,onFailed,userContext);
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">var</span> gtc = Sys.Net.WebServiceProxy._generateTypedConstructor;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> (<span style="COLOR: blue">typeof</span>(Address)
=== <span style="COLOR: #a31515">'undefined'</span>) {
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">var</span> Address=gtc(<span style="COLOR: #a31515">"Address"</span>);
</p>
          <p style="MARGIN: 0px">
    Address.registerClass(<span style="COLOR: #a31515">'Address'</span>);
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> (<span style="COLOR: blue">typeof</span>(User)
=== <span style="COLOR: #a31515">'undefined'</span>) {
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">var</span> User=gtc(<span style="COLOR: #a31515">"User"</span>);
</p>
          <p style="MARGIN: 0px">
    User.registerClass(<span style="COLOR: #a31515">'User'</span>);
</p>
          <p style="MARGIN: 0px">
} 
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
The generated proxy class is called like the web service, and inherits from the Sys.Net.WebServiceProxy
class, which has the functionality to invoke a web service. The class have some properties
set in order call the specific web service that it is proxying, and the web methods
exposed (GetModifiedUser in our case).
</p>
        <p>
After the class to call the web service, the User and Address classes are created
and registered to be used by client code (thanks to the GenerateScriptTypeAttribute).
However, no property of the original classes is generated in client script. The core
of this client classes is the call to the Sys.Net.WebServiceProxy._generateTypedConstructor
method. This method creates a new class that accepts an object as a parameter for
the constructor. The constructor of the class will iterate through the members of
the object passed as the parameter and copy them to the current instance.
</p>
        <p>
So you can create an instance of the Address class that has 2 fields (propertyOne
and propertyTwo) like this:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">new</span> Address({<span style="COLOR: #a31515">"firstField"</span>:<span style="COLOR: #a31515">"firstValue"</span>,<span style="COLOR: #a31515">"secondField"</span>:<span style="COLOR: #a31515">"secondValue"</span>}).
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
and accessing to Address.firstField will return "firstValue".
</p>
        <p>
So if you want to call the previous web service from client script you can do something
like this:
</p>
        <p>
        
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">function</span> callWebService()
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">var</span> user
= <span style="COLOR: blue">new</span> User();
</p>
          <p style="MARGIN: 0px">
            user.ID = 1;
</p>
          <p style="MARGIN: 0px">
            user.Name = <span style="COLOR: #a31515">"Manuel"</span>;
</p>
          <p style="MARGIN: 0px">
            user.SurName = <span style="COLOR: #a31515">"Abadia"</span>;
</p>
          <p style="MARGIN: 0px">
            user.CreationDate = <span style="COLOR: blue">new</span> Date();
</p>
          <p style="MARGIN: 0px">
            user.Address = <span style="COLOR: blue">new</span> Address();
</p>
          <p style="MARGIN: 0px">
            user.Address.FirstLine = <span style="COLOR: #a31515">"C/
Torre Alvarez"</span>;
</p>
          <p style="MARGIN: 0px">
            user.Address.SecondLine = <span style="COLOR: #a31515">"Murcia,
2007"</span>;
</p>
          <p style="MARGIN: 0px">
            user.Address.Country = <span style="COLOR: #a31515">"Spain"</span>;
</p>
          <p style="MARGIN: 0px">
            AjaxWebService.GetModifiedUser(user,
OnSucceeded, OnError);
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">function</span> OnSucceeded(result)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">var</span> RsltElem
= document.getElementById(<span style="COLOR: #a31515">"Results"</span>);
</p>
          <p style="MARGIN: 0px">
            RsltElem.innerHTML = result.Name
+ <span style="COLOR: #a31515">"["</span> + result.ID + <span style="COLOR: #a31515">"]"</span>;
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">function</span> OnError(message)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
           alert(message.get_message() + <span style="COLOR: #a31515">"
"</span> + message.get_stackTrace());
</p>
          <p style="MARGIN: 0px">
        }
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
when the User instance is created it contains no members, but you keep adding them
in each assignment (this is how JavaScript works). You can even add nonexisting members
like user.Foo = "This property doesn't exists in server code" and they will be ignored
on the server side in the deserialization process.
</p>
        <p>
When the GetModifiedUser method is called from client script, it generates an asynchronous
HTTP request to the web service (<a href="http://localhost/AJAXServerSide1/AjaxWebService.asmx/GetModifiedUser">http://localhost/AJAXServerSide1/AjaxWebService.asmx/GetModifiedUser</a> in
my case) with the following posted data:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
{<span style="COLOR: #a31515">"usr"</span>:{<span style="COLOR: #a31515">"__type"</span>:<span style="COLOR: #a31515">"User"</span>,<span style="COLOR: #a31515">"ID"</span>:1,<span style="COLOR: #a31515">"Name"</span>:<span style="COLOR: #a31515">"Manuel"</span>,<span style="COLOR: #a31515">"SurName"</span>:<span style="COLOR: #a31515">"Abadia"</span>,<span style="COLOR: #a31515">"CreationDate"</span>:<span style="COLOR: #a31515">"\/Date(1174133124369)\/"</span>,<span style="COLOR: #a31515">"Address"</span>:{<span style="COLOR: #a31515">"__type"</span>:<span style="COLOR: #a31515">"Address"</span>,<span style="COLOR: #a31515">"FirstLine"</span>:<span style="COLOR: #a31515">"C/
Torre Alvarez"</span>,<span style="COLOR: #a31515">"SecondLine"</span>:<span style="COLOR: #a31515">"Murcia,
2007"</span>,<span style="COLOR: #a31515">"Country"</span>:<span style="COLOR: #a31515">"Spain"</span>}}}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
and the server generates a response with the following data:
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
{<span style="COLOR: #a31515">"__type"</span>:<span style="COLOR: #a31515">"User"</span>,<span style="COLOR: #a31515">"ID"</span>:2,<span style="COLOR: #a31515">"Name"</span>:<span style="COLOR: #a31515">"Manu"</span>,<span style="COLOR: #a31515">"SurName"</span>:<span style="COLOR: #a31515">"Abadia"</span>,<span style="COLOR: #a31515">"Address"</span>:{<span style="COLOR: #a31515">"__type"</span>:<span style="COLOR: #a31515">"Address"</span>,<span style="COLOR: #a31515">"FirstLine"</span>:<span style="COLOR: #a31515">"C/
Torre Alvarez"</span>,<span style="COLOR: #a31515">"SecondLine"</span>:<span style="COLOR: #a31515">"Murcia,
2007"</span>,<span style="COLOR: #a31515">"Country"</span>:<span style="COLOR: #a31515">"Spain"</span>},<span style="COLOR: #a31515">"CreationDate"</span>:<span style="COLOR: #a31515">"\/Date(1174133124369)\/"</span>}
</p>
        </div>
        <p>
that is passed to directly the User constructor in order to generate the returned
value from the web service.
</p>
        <p>
In my next post about MS AJAX I'll sumarize what we have learned and how it applies
to the ScriptHandlerFactory, the application web services, and then continue
with the next HttpHandler, the ScriptResourceHandler.
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=50bc4c5a-3e40-4f81-8137-f7843d4a486d" />
      </body>
      <title>ASP.NET AJAX Extensions Internals - Web Service Proxy Generation</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,50bc4c5a-3e40-4f81-8137-f7843d4a486d.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,50bc4c5a-3e40-4f81-8137-f7843d4a486d.aspx</link>
      <pubDate>Sat, 17 Mar 2007 13:09:19 GMT</pubDate>
      <description>&lt;p&gt;
In &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,22a125d3-1ed3-422b-ba2b-89ed63febce3.aspx"&gt;my
last post about MS AJAX&lt;/a&gt; I gave a brief explanation about the web.config changes
needed and explained the serialization process. 
&lt;/p&gt;
&lt;p&gt;
Now, I'm going to explain how a client proxy is generated. As I told in the last post,
the WebServiceClientProxyGenerator.GetClientProxyScript method was were all the job
was done.
&lt;/p&gt;
&lt;p&gt;
There are a few classes involved in the client proxy generation:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
WebServiceTypeData, that is used to store type information about the web service to
call.&lt;/li&gt;
&lt;li&gt;
WebServiceMethodData, that is used to store information about a web service method
(parameters, return type, caching, etc), and it has the functionality to invoke the
method.&lt;/li&gt;
&lt;li&gt;
WebServiceParameterData, used to store information about a parameter of a web service
method.&lt;/li&gt;
&lt;li&gt;
WebServiceData. This class uses the previous classes and has a lot of logic. Basically
a WebServiceData instance is created for each web service to call (for each instance
there is an associated WebServiceTypeData instance). When the web service methods
are required, the EnsureMethods method uses reflection to obtain all WebMethods from
the type (and its ancestors).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
By default, a web service can't be called from client script. To change this, the
web service needs the ScriptServiceAttribute applied to it.
&lt;/p&gt;
&lt;p&gt;
To be able to call a web method from client script, the parameters and return types
of the web method have to be available in client script, and the web service needs
to have the WebMethodAttribute (the ScriptMethodAttribute should be used only to override
the default invocation method and respone format, that is HTTP POST and JSON). If
a web service method needs a parameter of a custom type, we have to use the GenerateScriptTypeAttribute
attribute in the method or in the web service so MS AJAX will automatically generate
a client side class for that type.
&lt;/p&gt;
&lt;p&gt;
So when the methods are processed, the ClientTypes property will be filled in the
ProcessClientTypes method with a list of the types that need to be available in client
script.
&lt;/p&gt;
&lt;p&gt;
However, the automatic type generation has some limitations, as the GenerateScriptTypeAttribute
can not be applied to types implementing IEnumerable or IDictionary, interfaces, abstract
classes, types without a public parameterless constructor, and generic types with
more than one parameter.
&lt;/p&gt;
&lt;p&gt;
The WebServiceData class also inherits from the JavaScriptTypeResolver class to provide
string to type conversion (and viceversa) for the serialization/deserialization process.
You may be wondering why the SimpleTypeResolver isn't used, but as the GenerateScriptTypeAttribute
has a property called ScriptTypeId that modifies the __type field stored in the JSON,
another type resolver was needed.
&lt;/p&gt;
&lt;p&gt;
As you can see, the WebServiceData class does a lot of work, so to get WebServiceData
instances the static method GetWebServiceData is used because it caches instances
by URL.
&lt;/p&gt;
&lt;p&gt;
If you don't want to create a new class for a few methods, you can add them to your
ASPX page and call them directly. For this to work, the methods should be static and
have the WebMethodAttribute attribute applied.
&lt;/p&gt;
&lt;p&gt;
The ClientProxyGenerator class uses a WebServiceData instance and generates the client
proxy code, although the code calls to the static method GetClientProxyScript of the
WebServiceClientProxyGenerator class to get the generated client proxy code, because
it performs caching based on the web service type and the modified time of the associated
assembly. 
&lt;/p&gt;
&lt;p&gt;
For the following web service:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
[&lt;span style="COLOR: #2b91af"&gt;WebService&lt;/span&gt;(Namespace = &lt;span style="COLOR: #a31515"&gt;"http://tempuri.org/"&lt;/span&gt;)]
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
[&lt;span style="COLOR: #2b91af"&gt;WebServiceBinding&lt;/span&gt;(ConformsTo = &lt;span style="COLOR: #2b91af"&gt;WsiProfiles&lt;/span&gt;.BasicProfile1_1)]
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
[&lt;span style="COLOR: #2b91af"&gt;ScriptService&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;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;AjaxWebService&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;&amp;nbsp; [&lt;span style="COLOR: #2b91af"&gt;WebMethod&lt;/span&gt;]
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="COLOR: #2b91af"&gt;GenerateScriptType&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: #2b91af"&gt;User&lt;/span&gt;))]
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="COLOR: #2b91af"&gt;GenerateScriptType&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: #2b91af"&gt;Address&lt;/span&gt;))]
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;User&lt;/span&gt; GetModifiedUser(&lt;span style="COLOR: #2b91af"&gt;User&lt;/span&gt; usr)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; usr.ID = usr.ID * 2;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; usr.Name = &lt;span style="COLOR: #a31515"&gt;"Manu"&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; usr;
&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;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
the User and Address classes were introduced in the previous post.&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
the generated proxy is:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; AjaxWebService=&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; AjaxWebService.initializeBase(&lt;span style="COLOR: blue"&gt;this&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;._timeout = 0;
&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;._userContext = &lt;span style="COLOR: blue"&gt;null&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;._succeeded = &lt;span style="COLOR: blue"&gt;null&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;._failed = &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
AjaxWebService.prototype={
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; GetModifiedUser:&lt;span style="COLOR: blue"&gt;function&lt;/span&gt;(usr,succeededCallback,
failedCallback, userContext) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;._invoke(AjaxWebService.get_path(), &lt;span style="COLOR: #a31515"&gt;'GetModifiedUser'&lt;/span&gt;,&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; usr:usr
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ,succeededCallback,failedCallback,userContext);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
AjaxWebService.registerClass(&lt;span style="COLOR: #a31515"&gt;'AjaxWebService'&lt;/span&gt;,Sys.Net.WebServiceProxy);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
AjaxWebService._staticInstance = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; AjaxWebService();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
AjaxWebService.set_path = &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;var&lt;/span&gt; e = Function._validateParams(arguments,
[{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; name: &lt;span style="COLOR: #a31515"&gt;'path'&lt;/span&gt;,
type: String
&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;if&lt;/span&gt; (e) &lt;span style="COLOR: blue"&gt;throw&lt;/span&gt; e;
AjaxWebService._staticInstance._path = value;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
AjaxWebService.get_path = &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; AjaxWebService._staticInstance._path;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
AjaxWebService.set_timeout = &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;var&lt;/span&gt; e = Function._validateParams(arguments,
[{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; name: &lt;span style="COLOR: #a31515"&gt;'timeout'&lt;/span&gt;,
type: Number
&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;if&lt;/span&gt; (e) &lt;span style="COLOR: blue"&gt;throw&lt;/span&gt; e; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (value
&amp;amp;lt; 0) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;throw&lt;/span&gt; Error.argumentOutOfRange(&lt;span style="COLOR: #a31515"&gt;'value'&lt;/span&gt;,
value, Sys.Res.invalidTimeout);
&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; AjaxWebService._staticInstance._timeout = value;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
AjaxWebService.get_timeout = &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; AjaxWebService._staticInstance._timeout;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
AjaxWebService.set_defaultUserContext = &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; AjaxWebService._staticInstance._userContext = value;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
AjaxWebService.get_defaultUserContext = &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; AjaxWebService._staticInstance._userContext;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
AjaxWebService.set_defaultSucceededCallback = &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;var&lt;/span&gt; e = Function._validateParams(arguments,
[{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; name: &lt;span style="COLOR: #a31515"&gt;'defaultSucceededCallback'&lt;/span&gt;,
type: Function
&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;if&lt;/span&gt; (e) &lt;span style="COLOR: blue"&gt;throw&lt;/span&gt; e;
AjaxWebService._staticInstance._succeeded = value;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
AjaxWebService.get_defaultSucceededCallback = &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; AjaxWebService._staticInstance._succeeded;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
AjaxWebService.set_defaultFailedCallback = &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;var&lt;/span&gt; e = Function._validateParams(arguments,
[{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; name: &lt;span style="COLOR: #a31515"&gt;'defaultFailedCallback'&lt;/span&gt;,
type: Function
&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;if&lt;/span&gt; (e) &lt;span style="COLOR: blue"&gt;throw&lt;/span&gt; e;
AjaxWebService._staticInstance._failed = value;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
AjaxWebService.get_defaultFailedCallback = &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; AjaxWebService._staticInstance._failed;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
AjaxWebService.set_path(&lt;span style="COLOR: #a31515"&gt;"/AJAXServerSide1/AjaxWebService.asmx"&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
AjaxWebService.GetModifiedUser= &lt;span style="COLOR: blue"&gt;function&lt;/span&gt;(usr,onSuccess,onFailed,userContext)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; AjaxWebService._staticInstance.GetModifiedUser(usr,onSuccess,onFailed,userContext);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; gtc = Sys.Net.WebServiceProxy._generateTypedConstructor;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(Address)
=== &lt;span style="COLOR: #a31515"&gt;'undefined'&lt;/span&gt;) {
&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; Address=gtc(&lt;span style="COLOR: #a31515"&gt;"Address"&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Address.registerClass(&lt;span style="COLOR: #a31515"&gt;'Address'&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(User)
=== &lt;span style="COLOR: #a31515"&gt;'undefined'&lt;/span&gt;) {
&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; User=gtc(&lt;span style="COLOR: #a31515"&gt;"User"&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; User.registerClass(&lt;span style="COLOR: #a31515"&gt;'User'&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
} 
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The generated proxy class is called like the web service, and inherits from the Sys.Net.WebServiceProxy
class, which has the functionality to invoke a web service. The class have some properties
set in order call the specific web service that it is proxying, and the web methods
exposed (GetModifiedUser in our case).
&lt;/p&gt;
&lt;p&gt;
After the class to call the web service, the User and Address classes are created
and registered to be used by client code (thanks to the GenerateScriptTypeAttribute).
However, no property of the original classes is generated in client script. The core
of this client classes is the call to the Sys.Net.WebServiceProxy._generateTypedConstructor
method. This method creates a new class that accepts an object as a parameter for
the constructor. The constructor of the class will iterate through the members of
the object passed as the parameter and copy them to the current instance.
&lt;/p&gt;
&lt;p&gt;
So you can create an instance of the Address class that has 2 fields (propertyOne
and propertyTwo) like this:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; Address({&lt;span style="COLOR: #a31515"&gt;"firstField"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"firstValue"&lt;/span&gt;,&lt;span style="COLOR: #a31515"&gt;"secondField"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"secondValue"&lt;/span&gt;}).
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
and accessing to Address.firstField will return "firstValue".
&lt;/p&gt;
&lt;p&gt;
So if you want to call the previous web service from client script you can do something
like this:
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;function&lt;/span&gt; callWebService()
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; user
= &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; User();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; user.ID = 1;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; user.Name = &lt;span style="COLOR: #a31515"&gt;"Manuel"&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; user.SurName = &lt;span style="COLOR: #a31515"&gt;"Abadia"&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; user.CreationDate = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; Date();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; user.Address = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; Address();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; user.Address.FirstLine = &lt;span style="COLOR: #a31515"&gt;"C/
Torre Alvarez"&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; user.Address.SecondLine = &lt;span style="COLOR: #a31515"&gt;"Murcia,
2007"&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; user.Address.Country = &lt;span style="COLOR: #a31515"&gt;"Spain"&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; AjaxWebService.GetModifiedUser(user,
OnSucceeded, OnError);
&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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;function&lt;/span&gt; OnSucceeded(result)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;var&lt;/span&gt; RsltElem
= document.getElementById(&lt;span style="COLOR: #a31515"&gt;"Results"&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; RsltElem.innerHTML = result.Name
+ &lt;span style="COLOR: #a31515"&gt;"["&lt;/span&gt; + result.ID + &lt;span style="COLOR: #a31515"&gt;"]"&lt;/span&gt;;
&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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;function&lt;/span&gt; OnError(message)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp; alert(message.get_message() + &lt;span style="COLOR: #a31515"&gt;"
"&lt;/span&gt; + message.get_stackTrace());
&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;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
when the User instance is created it contains no members, but you keep adding them
in each assignment (this is how JavaScript works). You can even add nonexisting members
like user.Foo = "This property doesn't exists in server code" and they will be ignored
on the server side in the deserialization process.
&lt;/p&gt;
&lt;p&gt;
When the GetModifiedUser method is called from client script, it generates an asynchronous
HTTP request to the web service (&lt;a href="http://localhost/AJAXServerSide1/AjaxWebService.asmx/GetModifiedUser"&gt;http://localhost/AJAXServerSide1/AjaxWebService.asmx/GetModifiedUser&lt;/a&gt; in
my case) with the following posted data:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
{&lt;span style="COLOR: #a31515"&gt;"usr"&lt;/span&gt;:{&lt;span style="COLOR: #a31515"&gt;"__type"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"User"&lt;/span&gt;,&lt;span style="COLOR: #a31515"&gt;"ID"&lt;/span&gt;:1,&lt;span style="COLOR: #a31515"&gt;"Name"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"Manuel"&lt;/span&gt;,&lt;span style="COLOR: #a31515"&gt;"SurName"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"Abadia"&lt;/span&gt;,&lt;span style="COLOR: #a31515"&gt;"CreationDate"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"\/Date(1174133124369)\/"&lt;/span&gt;,&lt;span style="COLOR: #a31515"&gt;"Address"&lt;/span&gt;:{&lt;span style="COLOR: #a31515"&gt;"__type"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"Address"&lt;/span&gt;,&lt;span style="COLOR: #a31515"&gt;"FirstLine"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"C/
Torre Alvarez"&lt;/span&gt;,&lt;span style="COLOR: #a31515"&gt;"SecondLine"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"Murcia,
2007"&lt;/span&gt;,&lt;span style="COLOR: #a31515"&gt;"Country"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"Spain"&lt;/span&gt;}}}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
and the server generates a response with the following data:
&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;
{&lt;span style="COLOR: #a31515"&gt;"__type"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"User"&lt;/span&gt;,&lt;span style="COLOR: #a31515"&gt;"ID"&lt;/span&gt;:2,&lt;span style="COLOR: #a31515"&gt;"Name"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"Manu"&lt;/span&gt;,&lt;span style="COLOR: #a31515"&gt;"SurName"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"Abadia"&lt;/span&gt;,&lt;span style="COLOR: #a31515"&gt;"Address"&lt;/span&gt;:{&lt;span style="COLOR: #a31515"&gt;"__type"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"Address"&lt;/span&gt;,&lt;span style="COLOR: #a31515"&gt;"FirstLine"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"C/
Torre Alvarez"&lt;/span&gt;,&lt;span style="COLOR: #a31515"&gt;"SecondLine"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"Murcia,
2007"&lt;/span&gt;,&lt;span style="COLOR: #a31515"&gt;"Country"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"Spain"&lt;/span&gt;},&lt;span style="COLOR: #a31515"&gt;"CreationDate"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"\/Date(1174133124369)\/"&lt;/span&gt;}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
that is passed to directly the User constructor in order to generate the returned
value from the web service.
&lt;/p&gt;
&lt;p&gt;
In my next post about MS AJAX I'll sumarize what we have learned and how it applies
to the ScriptHandlerFactory, the application web services,&amp;nbsp;and then continue
with the next HttpHandler, the ScriptResourceHandler.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=50bc4c5a-3e40-4f81-8137-f7843d4a486d" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,50bc4c5a-3e40-4f81-8137-f7843d4a486d.aspx</comments>
      <category>Ajax;ASP.NET;JavaScript</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=22a125d3-1ed3-422b-ba2b-89ed63febce3</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,22a125d3-1ed3-422b-ba2b-89ed63febce3.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,22a125d3-1ed3-422b-ba2b-89ed63febce3.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=22a125d3-1ed3-422b-ba2b-89ed63febce3</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Some time ago I started bloging about the Client Side OOP Features of Atlas (now the
Microsoft AJAX Library. The posts are <a href="http://www.manuelabadia.com/blog/PermaLink,guid,c59facc0-301e-4e30-898d-428038828dcd.aspx">here</a> and <a href="http://www.manuelabadia.com/blog/PermaLink,guid,e440e756-b3fa-4ec2-aea7-f2f28dee1a38.aspx">here</a>). 
</p>
        <p>
As I think that most ASP.NET developers will use mainly the server side AJAX extensions
I'll start covering the internals of the server side additions to ASP.NET to support
AJAX.
</p>
        <p>
If you create a new Web Site in VS2005 using the "ASP.NET AJAX Enabled Web-Site" you'll
see that the web.config file for this web has quite a few additions to the default
one related to AJAX. The additions to the web.config are:
</p>
        <p>
1) Added some custom sections handlers to configure the new AJAX features 
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;</span>
            <span style="COLOR: #a31515">sectionGroup</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">system.web.extensions</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Configuration.SystemWebExtensionsSectionGroup,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>"<span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;</span>
            <span style="COLOR: #a31515">sectionGroup</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">scripting</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Configuration.ScriptingSectionGroup,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>"<span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        &lt;</span>
            <span style="COLOR: #a31515">section</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">scriptResourceHandler</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Configuration.ScriptingScriptResourceHandlerSection,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>"<span style="COLOR: blue"></span><span style="COLOR: red">requirePermission</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">false</span>"<span style="COLOR: blue"></span><span style="COLOR: red">allowDefinition</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">MachineToApplication</span>"<span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        &lt;</span>
            <span style="COLOR: #a31515">sectionGroup</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">webServices</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Configuration.ScriptingWebServicesSectionGroup,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>"<span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">          &lt;</span>
            <span style="COLOR: #a31515">section</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">jsonSerialization</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Configuration.ScriptingJsonSerializationSection,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>"<span style="COLOR: blue"></span><span style="COLOR: red">requirePermission</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">false</span>"<span style="COLOR: blue"></span><span style="COLOR: red">allowDefinition</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">Everywhere</span>"<span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">          &lt;</span>
            <span style="COLOR: #a31515">section</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">profileService</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Configuration.ScriptingProfileServiceSection,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>"<span style="COLOR: blue"></span><span style="COLOR: red">requirePermission</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">false</span>"<span style="COLOR: blue"></span><span style="COLOR: red">allowDefinition</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">MachineToApplication</span>"<span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">          &lt;</span>
            <span style="COLOR: #a31515">section</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">authenticationService</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Configuration.ScriptingAuthenticationServiceSection,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>"<span style="COLOR: blue"></span><span style="COLOR: red">requirePermission</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">false</span>"<span style="COLOR: blue"></span><span style="COLOR: red">allowDefinition</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">MachineToApplication</span>"<span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        &lt;/</span>
            <span style="COLOR: #a31515">sectionGroup</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;/</span>
            <span style="COLOR: #a31515">sectionGroup</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;/</span>
            <span style="COLOR: #a31515">sectionGroup</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <p>
          <!--EndFragment-->    
<br /></p>
        <p>
2) Configured the "asp" tag prefix for controls in the AJAX implementation assembly:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;</span>
            <span style="COLOR: #a31515">pages</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;</span>
            <span style="COLOR: #a31515">controls</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        &lt;</span>
            <span style="COLOR: #a31515">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">tagPrefix</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">asp</span>"<span style="COLOR: blue"></span><span style="COLOR: red">namespace</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.UI</span>"<span style="COLOR: blue"></span><span style="COLOR: red">assembly</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Extensions,
Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>"<span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;/</span>
            <span style="COLOR: #a31515">controls</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;/</span>
            <span style="COLOR: #a31515">pages</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <p>
          <!--EndFragment-->    
<br /></p>
        <p>
3) Added the AJAX assembly reference to the compilation process:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;</span>
            <span style="COLOR: #a31515">compilation</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">debug</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">false</span>"<span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;</span>
            <span style="COLOR: #a31515">assemblies</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        &lt;</span>
            <span style="COLOR: #a31515">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">assembly</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Extensions,
Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>"<span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;/</span>
            <span style="COLOR: #a31515">assemblies</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;/</span>
            <span style="COLOR: #a31515">compilation</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <p>
          <!--EndFragment-->    
<br /></p>
        <p>
4) Modified the HTTP Handlers:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;</span>
            <span style="COLOR: #a31515">httpHandlers</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;</span>
            <span style="COLOR: #a31515">remove</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">verb</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">*</span>"<span style="COLOR: blue"></span><span style="COLOR: red">path</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">*.asmx</span>"<span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;</span>
            <span style="COLOR: #a31515">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">verb</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">*</span>"<span style="COLOR: blue"></span><span style="COLOR: red">path</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">*.asmx</span>"<span style="COLOR: blue"></span><span style="COLOR: red">validate</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">false</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>"<span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;</span>
            <span style="COLOR: #a31515">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">verb</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">*</span>"<span style="COLOR: blue"></span><span style="COLOR: red">path</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">*_AppService.axd</span>"<span style="COLOR: blue"></span><span style="COLOR: red">validate</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">false</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>"<span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;</span>
            <span style="COLOR: #a31515">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">verb</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">GET,HEAD</span>"<span style="COLOR: blue"></span><span style="COLOR: red">path</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">ScriptResource.axd</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Handlers.ScriptResourceHandler,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>"<span style="COLOR: blue"></span><span style="COLOR: red">validate</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">false</span>"<span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;/</span>
            <span style="COLOR: #a31515">httpHandlers</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <p>
          <!--EndFragment-->    
<br /></p>
        <p>
5) Added an HTTP Module:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;</span>
            <span style="COLOR: #a31515">httpModules</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;</span>
            <span style="COLOR: #a31515">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">ScriptModule</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Handlers.ScriptModule,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35</span>"<span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;/</span>
            <span style="COLOR: #a31515">httpModules</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <p>
          <!--EndFragment-->    
<br /></p>
        <p>
6) Added the configuration sections to configure ASP.NET AJAX (the section handlers
were registered previously as explained in point 1).
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span>
            <span style="COLOR: #a31515">system.web.extensions</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;</span>
            <span style="COLOR: #a31515">scripting</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;</span>
            <span style="COLOR: #a31515">webServices</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        &lt;!--</span>
            <span style="COLOR: green"> Uncomment
this line to customize maxJsonLength and add a custom converter </span>
            <span style="COLOR: blue">--&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        &lt;!--</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">      &lt;jsonSerialization maxJsonLength="500"&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">        &lt;converters&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">          &lt;add name="ConvertMe"
type="Acme.SubAcme.ConvertMeTypeConverter"/&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">        &lt;/converters&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">      &lt;/jsonSerialization&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">      </span>
            <span style="COLOR: blue">--&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        &lt;!--</span>
            <span style="COLOR: green"> Uncomment
this line to enable the authentication service. Include requireSSL="true" if appropriate. </span>
            <span style="COLOR: blue">--&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        &lt;!--</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">        &lt;authenticationService enabled="true"
requireSSL = "true|false"/&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">      </span>
            <span style="COLOR: blue">--&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        &lt;!--</span>
            <span style="COLOR: green"> Uncomment
these lines to enable the profile service. To allow profile properties to be retrieved</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">          and modified in ASP.NET
AJAX applications, you need to add each property name to the readAccessProperties
and</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">          writeAccessProperties
attributes. </span>
            <span style="COLOR: blue">--&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        &lt;!--</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">      &lt;profileService enabled="true"</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">               
      readAccessProperties="propertyname1,propertyname2"</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">               
      writeAccessProperties="propertyname1,propertyname2" /&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">      </span>
            <span style="COLOR: blue">--&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;/</span>
            <span style="COLOR: #a31515">webServices</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;!--</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">      &lt;scriptResourceHandler enableCompression="true"
enableCaching="true" /&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">      </span>
            <span style="COLOR: blue">--&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;/</span>
            <span style="COLOR: #a31515">scripting</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;/</span>
            <span style="COLOR: #a31515">system.web.extensions</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <!--EndFragment-->
        <p>
          <br />
  
<br /></p>
        <p>
The most important additions to the web.config to support the Microsoft ASP.NET AJAX
Extensions (MS AJAX from now on) are point 4 and 5. As the ASP.NET HTTP pipeline is
very configurable, those additions can have severe implications on how request are
handled, so I'll start with them.
</p>
        <p>
In the HTTP handlers section, the first line removes the default handling for the
asmx extension, and the second one registers a new handler for the asmx extension.
This simple changes makes that any call to a web service doesn't work as we are used
to. The asmx requests now will go through the ScriptHandlerFactory.
</p>
        <p>
Usually in the HTTP handlers session we register a class that implements the IHttpHanlder
interface. The ProcessRequest method will be called to do all processing. 
</p>
        <p>
However, we can also register a class that implements an IHttpHandlerFactory. In this
case, the method GetHandler will be called in the factory, returning an IHttpHandler
that will handle the request. This is used when you want to return different IHttpHandler
instances depending on some conditions of the request.
</p>
        <p>
When a request that is handled by the ScriptHandlerFactory arrives, it checks if the
request is a REST request (REST is a way to transmit data over HTTP without using
any additional messaging layer. Consult <a href="http://en.wikipedia.org/wiki/REST">wikipedia</a> for
more information about it). If it is a REST request, the RestHandlerFactory (a MS
AJAX class) will take care of the request. If it isn't, the WebServiceHandlerFactory
will take care of it. Probably the class WebServiceHandlerFactory won't say much to
you, but this is the class that handles ASMX request in the ASP.NET 2.0, so when an
ASMX request isn't a REST request, it is handled in the same way as we're used to.  
</p>
        <p>
What is a REST request for MS AJAX? A REST request is an HTTP request that has the
ContentType property set to "application/json" (this is called a REST method request)
or an HTTP request whose path ends with "/js" or "/jsdebug" (this is called a REST
client proxy request).
</p>
        <p>
The RestHandlerFactory checks if the request is for a client proxy or for a REST method.
If the request is for a client proxy, a RestClientProxyHandler is created and servers
the request. The RestClientProxyHandler figures which client proxy has been requested,
gets the client proxy and sends it. All the hard work is done by the WebServiceClientProxyGenerator.GetClientProxyScript
method. Before entering in detail how the client script proxy is generated, lets see
how MS AJAX handles serialization.
</p>
        <p>
Data types are exchanged between client side and server side using JSON (JavaScript
Object Notation). To send data to the client side from the server, the data is serialized,
and to receive it from the client, the data is deserialized in the server.
</p>
        <p>
The main class responsible for this serialization/deserialization process is JavaScriptSerializer.
The public member for the class are:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">public</span>
            <span style="COLOR: blue">class</span>
            <span style="COLOR: #2b91af">JavaScriptSerializer</span>
          </p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span> JavaScriptSerializer();
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span> JavaScriptSerializer(<span style="COLOR: #2b91af">JavaScriptTypeResolver</span> resolver);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">int</span> MaxJsonLength
{ <span style="COLOR: blue">get</span>; <span style="COLOR: blue">set</span>; }
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">int</span> RecursionLimit
{ <span style="COLOR: blue">get</span>; <span style="COLOR: blue">set</span>; }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">string</span> Serialize(<span style="COLOR: blue">object</span> obj);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">void</span> Serialize(<span style="COLOR: blue">object</span> obj, <span style="COLOR: #2b91af">StringBuilder</span> output);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span> T Deserialize&lt;T&gt;(<span style="COLOR: blue">string</span> input);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">object</span> DeserializeObject(<span style="COLOR: blue">string</span> input);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span> T ConvertToType&lt;T&gt;(<span style="COLOR: blue">object</span> obj);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">void</span> RegisterConverters(IEnumerable&lt;<span style="COLOR: #2b91af">JavaScriptConverter</span>&gt;
converters);
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <!--EndFragment-->
        <p>
          <br />
 <br /></p>
        <p>
The serialization fails if there are more nested objects than RecursionLimit or if
the length of the serialized object is MaxJsonLength.
</p>
        <p>
A serialized object can optionally include type information. The type information
is provided by a class that inherits from JavaScriptTypeResolver, that has the following
methods to get a type from a string and viceversa: 
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">public</span>
            <span style="COLOR: blue">abstract</span>
            <span style="COLOR: blue">class</span>
            <span style="COLOR: #2b91af">JavaScriptTypeResolver</span>
          </p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">abstract</span><span style="COLOR: #2b91af">Type</span> ResolveType(<span style="COLOR: blue">string</span> id);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">abstract</span><span style="COLOR: blue">string</span> ResolveTypeId(<span style="COLOR: #2b91af">Type</span> type);
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
 
</p>
        <p>
The serializer will add the type information in a field called __type if it has an
associated JavaScriptTypeResolver.
</p>
        <p>
As the JavaScriptSerializer can not serialize/deserialize all types, you can supply
a custom class to support types not directly supported by the JavaScriptSerializer
using the RegisterConverters method. A converter has to inherit from:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">public</span>
            <span style="COLOR: blue">abstract</span>
            <span style="COLOR: blue">class</span>
            <span style="COLOR: #2b91af">JavaScriptConverter</span>
          </p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">abstract</span><span style="COLOR: #2b91af">IEnumerable</span>&lt;<span style="COLOR: #2b91af">Type</span>&gt;
SupportedTypes
</p>
          <p style="MARGIN: 0px">
    {
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">get</span>;
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">abstract</span><span style="COLOR: blue">object</span> Deserialize(<span style="COLOR: #2b91af">IDictionary</span>&lt;<span style="COLOR: blue">string</span>, <span style="COLOR: blue">object</span>&gt;
dictionary, <span style="COLOR: #2b91af">Type</span> type, <span style="COLOR: #2b91af">JavaScriptSerializer</span> serializer);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">abstract</span><span style="COLOR: #2b91af">IDictionary</span>&lt;<span style="COLOR: blue">string</span>, <span style="COLOR: blue">object</span>&gt;
Serialize(<span style="COLOR: blue">object</span> obj, <span style="COLOR: #2b91af">JavaScriptSerializer</span> serializer);
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <!--EndFragment-->
        <p>
          <br />
    
<br /></p>
        <p>
and it has to implement the Serialize and Deserialize methods, as well as providing
the list of supported types.
</p>
        <p>
The standard MS AJAX distribution doesn't have any converter, but you can find a DataSet,
DataTable and DataRow converter in the ASP.NET AJAX Futures release.
</p>
        <p>
The other methods of the JavaScriptSerializer class are just serialize/deserialize
variants, and the ConvertToType method that will be explained later.
</p>
        <p>
The serialization of the basic types is as follows:
</p>
        <p>
null or DBNull.Value -&gt; "null"<br />
bool -&gt; "true" or "false"<br />
char -&gt; if it is '\0', "null", like a string if not<br />
float, double -&gt; ToString("r", CultureInfo.InvariantCulture)<br />
DateTime -&gt; "\/Date(number of milliseconds elapsed since midnight 1970/01/01 UTC)\/"<br />
string -&gt; quoted string<br />
Guid -&gt; "\" + ToString() + "\"<br />
Uri -&gt; "\" + Uri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped)
+ "\"<br />
other primitive types and Decimal -&gt; IConvertible.ToString(CultureInfo.InvariantCulture)<br />
Enum -&gt; serialize the integer value of the enum<br />
IDictionary -&gt; JSON object<br />
IEnumerable -&gt; JSON array
</p>
        <p>
A custom object is serialized as a JSON object with the optional member "__type" :
typeName obtained using the JavaScriptResolver, where the other members are obtained
from the public instance fields and public instance properties without the ScriptIgnore
attribute applied.
</p>
        <p>
for more information about <a href="http://www.json.org/">JSON take a look here</a>.
</p>
        <p>
A Hashtable that compare references is used to throw an error if there is any circular
reference.
</p>
        <p>
Lets show an example of the serialization process. I'm going to use this User and
Address class:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <span style="COLOR: blue">
            <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
              <p style="MARGIN: 0px">
                <span style="COLOR: blue">public</span>
                <span style="COLOR: blue">class</span>
                <span style="COLOR: #2b91af">User</span>
              </p>
              <p style="MARGIN: 0px">
{
</p>
              <p style="MARGIN: 0px">
    <span style="COLOR: blue">private</span><span style="COLOR: blue">int</span> _id;
</p>
              <p style="MARGIN: 0px">
    <span style="COLOR: blue">private</span><span style="COLOR: blue">string</span> _name;
</p>
              <p style="MARGIN: 0px">
    <span style="COLOR: blue">private</span><span style="COLOR: blue">string</span> _surName;
</p>
              <p style="MARGIN: 0px">
    <span style="COLOR: blue">private</span><span style="COLOR: #2b91af">Address</span> _address;
</p>
              <p style="MARGIN: 0px">
    <span style="COLOR: blue">private</span><span style="COLOR: #2b91af">DateTime</span> _creationDate;
</p>
              <p style="MARGIN: 0px">
 
</p>
              <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">int</span> ID
</p>
              <p style="MARGIN: 0px">
    {
</p>
              <p style="MARGIN: 0px">
        <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> _id;
}
</p>
              <p style="MARGIN: 0px">
        <span style="COLOR: blue">set</span> { _id = <span style="COLOR: blue">value</span>;
}
</p>
              <p style="MARGIN: 0px">
    }
</p>
              <p style="MARGIN: 0px">
 
</p>
              <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">string</span> Name
</p>
              <p style="MARGIN: 0px">
    {
</p>
              <p style="MARGIN: 0px">
        <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> _name;
}
</p>
              <p style="MARGIN: 0px">
        <span style="COLOR: blue">set</span> { _name
= <span style="COLOR: blue">value</span>; }
</p>
              <p style="MARGIN: 0px">
    }
</p>
              <p style="MARGIN: 0px">
 
</p>
              <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">string</span> SurName
</p>
              <p style="MARGIN: 0px">
    {
</p>
              <p style="MARGIN: 0px">
        <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> _surName;
}
</p>
              <p style="MARGIN: 0px">
        <span style="COLOR: blue">set</span> { _surName
= <span style="COLOR: blue">value</span>; }
</p>
              <p style="MARGIN: 0px">
    }
</p>
              <p style="MARGIN: 0px">
 
</p>
              <p style="MARGIN: 0px">
    [<span style="COLOR: #2b91af">ScriptIgnore</span>]
</p>
              <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">string</span> FullName
</p>
              <p style="MARGIN: 0px">
    {
</p>
              <p style="MARGIN: 0px">
        <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> Name
+ <span style="COLOR: #a31515">" "</span> + SurName; }
</p>
              <p style="MARGIN: 0px">
    }
</p>
              <p style="MARGIN: 0px">
 
</p>
              <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: #2b91af">Address</span> Address
</p>
              <p style="MARGIN: 0px">
    {
</p>
              <p style="MARGIN: 0px">
        <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> _address;
}
</p>
              <p style="MARGIN: 0px">
        <span style="COLOR: blue">set</span> { _address
= <span style="COLOR: blue">value</span>; }
</p>
              <p style="MARGIN: 0px">
    }
</p>
              <p style="MARGIN: 0px">
 
</p>
              <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: #2b91af">DateTime</span> CreationDate
</p>
              <p style="MARGIN: 0px">
    {
</p>
              <p style="MARGIN: 0px">
        <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> _creationDate;
}
</p>
              <p style="MARGIN: 0px">
        <span style="COLOR: blue">set</span> { _creationDate
= <span style="COLOR: blue">value</span>; }
</p>
              <p style="MARGIN: 0px">
    }
</p>
              <p style="MARGIN: 0px">
 
</p>
              <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span> User()
</p>
              <p style="MARGIN: 0px">
    {
</p>
              <p style="MARGIN: 0px">
    }
</p>
              <p style="MARGIN: 0px">
}
</p>
              <p style="MARGIN: 0px">
 
</p>
            </div>
            <!--EndFragment-->
          </span>
        </div>
        <!--EndFragment-->
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">public</span>
            <span style="COLOR: blue">class</span>
            <span style="COLOR: #2b91af">Address</span>
          </p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">private</span><span style="COLOR: blue">string</span> _firstLine;
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">private</span><span style="COLOR: blue">string</span> _secondLine;
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">private</span><span style="COLOR: blue">string</span> _country;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">string</span> FirstLine
</p>
          <p style="MARGIN: 0px">
    {
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> _firstLine;
}
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">set</span> { _firstLine
= <span style="COLOR: blue">value</span>; }
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">string</span> SecondLine
</p>
          <p style="MARGIN: 0px">
    {
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> _secondLine;
}
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">set</span> { _secondLine
= <span style="COLOR: blue">value</span>; }
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">string</span> Country
</p>
          <p style="MARGIN: 0px">
    {
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> _country;
}
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">set</span> { _country
= <span style="COLOR: blue">value</span>; }
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span> Address()
</p>
          <p style="MARGIN: 0px">
    {
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
With the following code:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: #2b91af">JavaScriptSerializer</span> js = <span style="COLOR: blue">new</span><span style="COLOR: #2b91af">JavaScriptSerializer</span>(<span style="COLOR: blue">new</span><span style="COLOR: #2b91af">SimpleTypeResolver</span>());
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: #2b91af">User</span> usr = <span style="COLOR: blue">new</span><span style="COLOR: #2b91af">User</span>();
</p>
          <p style="MARGIN: 0px">
usr.ID = 12345;
</p>
          <p style="MARGIN: 0px">
usr.Name = <span style="COLOR: #a31515">"John"</span>;
</p>
          <p style="MARGIN: 0px">
usr.SurName = <span style="COLOR: #a31515">"Smith"</span>;
</p>
          <p style="MARGIN: 0px">
usr.Address = <span style="COLOR: blue">new</span><span style="COLOR: #2b91af">Address</span>();
</p>
          <p style="MARGIN: 0px">
usr.Address.FirstLine = <span style="COLOR: #a31515">"1st Avenue, 1234"</span>;
</p>
          <p style="MARGIN: 0px">
usr.Address.SecondLine = <span style="COLOR: #a31515">"San Diego, CA 92101"</span>;
</p>
          <p style="MARGIN: 0px">
usr.CreationDate = <span style="COLOR: #2b91af">DateTime</span>.Now;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">string</span> str = js.Serialize(usr);
</p>
        </div>
        <p>
          <!--EndFragment-->  <br /></p>
        <p>
The SimpleTypeResolver inherits from the JavaScriptTypeResolver class explained before,
converting a Type a string using the AssemblyQualifiedName and viceversa.
</p>
        <p>
Is serialized as:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: #a31515">"__type"</span>:<span style="COLOR: #a31515">"User,
AJAXServerSide1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"</span>,
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: #a31515">"ID"</span>:12345,
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: #a31515">"Name"</span>:<span style="COLOR: #a31515">"John"</span>,
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: #a31515">"SurName"</span>:<span style="COLOR: #a31515">"Smith"<font color="#000000">,</font></span><span style="COLOR: #a31515"></span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: #a31515">"Address"</span>:
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: #a31515">"__type"</span>:<span style="COLOR: #a31515">"Address,
AJAXServerSide1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"</span>,
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: #a31515">"FirstLine"</span>:<span style="COLOR: #a31515">"1st
Avenue, 1234"</span>,
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: #a31515">"SecondLine"</span>:<span style="COLOR: #a31515">"San
Diego, CA 92101"</span>,
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: #a31515">"Country"</span>:<span style="COLOR: blue">null</span></p>
          <p style="MARGIN: 0px">
        }<font color="#000000">,</font></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: #a31515">"CreationDate"</span><font color="#000000">:</font><span style="COLOR: #a31515">"\/Date(1173541909382)\/"</span></p>
          <p style="MARGIN: 0px">
} 
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
Note that the FullName property of the User is not serialized because the ScriptIgnore
attribute.
</p>
        <p>
The deserialization process is delegated to the JavaScriptObjectDeserializer class.
This class uses the JavaScriptString and the ObjectConverter class. The JavaScriptString
class is a helper class used to tokenize the JSON data. As when the data is serialized
all types are converted to JSON types (strings, numbers, JSON objects and JSON arrays)
some kind of conversion back to the original type must take place. The JavaScriptObjectDeserializer
does some simple conversions like checking if a string is a character, a boolean,
a date or a null value, most significant conversions are handled by the ConvertObjectToTypeInternal
method of the ObjectConverter class. 
</p>
        <p>
The ConvertObjectToTypeInternal uses the __type field, source object type and destination
type to perform the convertion. If the source data is of type IDictionary it tries
to create an object of the destination type and sets its fields and properties with
the values stored in the dictionary. If the source data is of type IList, it tries
to create a collection of the destination type and adds each of the items of the list
to the collection. If the collection is a generic collection, it extract the item
type of the collection and tries to convert the items as they're added to the collection.
</p>
        <p>
If the source type isn't neither an IDictionary nor an IList, it gets the TypeConverter
for the destination type and check if the source data can be converted to that type.
If the source type doesn't have a conversion to the destination type, it converts
the source type to a string and then tries to convert that string to the destination
type (all of the conversion that involve the TypeConverter use the InvariantCulture). 
</p>
        <p>
If everything fails, a conversion exception is thrown. 
</p>
        <p>
To continue the previous example, this converts the string obtained from the Serialize
method back to an User instance:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: #2b91af">User</span> u = js.Deserialize&lt;User&gt;(str);
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
 
</p>
        <p>
When comparing the initial User instance with the deserialized one, the CreationDate
is different by one hour (at least in my machine), so there is a bug in the MS AJAX
code that handles DateTimes :-(
</p>
        <p>
One curious thing about serialization is that the property names are case insensitive
when deserializing an object, as the AssignToPropertyOrField method uses the BindingFlags.IgnoreCase
to retrieve properties and fields. However, when an object is serialized, the properties
for the client code are case sensitive.
</p>
        <p>
I have run out of time for this week but soon I'll continue with the internals of
the additions of MS AJAX to the web.config.
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=22a125d3-1ed3-422b-ba2b-89ed63febce3" />
      </body>
      <title>ASP.NET AJAX Extensions Internals - Web.Config and Serialization</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,22a125d3-1ed3-422b-ba2b-89ed63febce3.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,22a125d3-1ed3-422b-ba2b-89ed63febce3.aspx</link>
      <pubDate>Sun, 11 Mar 2007 18:10:25 GMT</pubDate>
      <description>&lt;p&gt;
Some time ago I started bloging about the Client Side OOP Features of Atlas (now the
Microsoft AJAX Library. The posts are &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,c59facc0-301e-4e30-898d-428038828dcd.aspx"&gt;here&lt;/a&gt; and &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,e440e756-b3fa-4ec2-aea7-f2f28dee1a38.aspx"&gt;here&lt;/a&gt;). 
&lt;/p&gt;
&lt;p&gt;
As I think that most ASP.NET developers will use mainly the server side AJAX extensions
I'll start covering the internals of the server side additions to ASP.NET to support
AJAX.
&lt;/p&gt;
&lt;p&gt;
If you create a new Web Site in VS2005 using the "ASP.NET AJAX Enabled Web-Site" you'll
see that the web.config file for this web has quite a few additions to the default
one related to AJAX. The additions to the web.config are:
&lt;/p&gt;
&lt;p&gt;
1) Added some custom sections handlers to configure the new AJAX features 
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;sectionGroup&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;system.web.extensions&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Configuration.SystemWebExtensionsSectionGroup,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;sectionGroup&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;scripting&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Configuration.ScriptingSectionGroup,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;section&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;scriptResourceHandler&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Configuration.ScriptingScriptResourceHandlerSection,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;requirePermission&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;false&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;allowDefinition&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;MachineToApplication&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;sectionGroup&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;webServices&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Configuration.ScriptingWebServicesSectionGroup,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;section&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;jsonSerialization&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Configuration.ScriptingJsonSerializationSection,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;requirePermission&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;false&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;allowDefinition&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Everywhere&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;section&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;profileService&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Configuration.ScriptingProfileServiceSection,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;requirePermission&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;false&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;allowDefinition&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;MachineToApplication&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;section&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;authenticationService&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Configuration.ScriptingAuthenticationServiceSection,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;requirePermission&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;false&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;allowDefinition&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;MachineToApplication&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;sectionGroup&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;sectionGroup&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;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;sectionGroup&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
2) Configured the "asp" tag prefix for controls in the AJAX implementation assembly:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;pages&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;controls&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;tagPrefix&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;asp&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;namespace&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.UI&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;assembly&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Extensions,
Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;controls&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;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;pages&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
3) Added the AJAX assembly reference to the compilation process:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;compilation&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;debug&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;false&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;assemblies&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;assembly&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Extensions,
Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;assemblies&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;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;compilation&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
4) Modified the HTTP Handlers:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;httpHandlers&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;remove&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;verb&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;*&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;path&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;*.asmx&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;verb&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;*&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;path&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;*.asmx&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;validate&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;false&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;verb&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;*&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;path&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;*_AppService.axd&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;validate&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;false&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Script.Services.ScriptHandlerFactory,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;verb&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;GET,HEAD&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;path&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;ScriptResource.axd&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Handlers.ScriptResourceHandler,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;validate&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;false&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;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;httpHandlers&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
5) Added an HTTP Module:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;httpModules&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;ScriptModule&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Handlers.ScriptModule,
System.Web.Extensions, Version=1.0.61025.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35&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;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;httpModules&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
6) Added the configuration sections to configure ASP.NET AJAX (the section handlers
were registered previously as explained in point 1).
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;system.web.extensions&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;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;scripting&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;webServices&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;!--&lt;/span&gt;&lt;span style="COLOR: green"&gt; Uncomment
this line to customize maxJsonLength and add a custom converter &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;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;!--&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;jsonSerialization maxJsonLength="500"&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;converters&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;add name="ConvertMe"
type="Acme.SubAcme.ConvertMeTypeConverter"/&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/converters&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/jsonSerialization&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &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;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;!--&lt;/span&gt;&lt;span style="COLOR: green"&gt; Uncomment
this line to enable the authentication service. Include requireSSL="true" if appropriate. &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;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;!--&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;authenticationService enabled="true"
requireSSL = "true|false"/&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &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;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;!--&lt;/span&gt;&lt;span style="COLOR: green"&gt; Uncomment
these lines to enable the profile service. To allow profile properties to be retrieved&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; and modified in ASP.NET
AJAX applications, you need to add each property name to the readAccessProperties
and&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; writeAccessProperties
attributes. &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;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;!--&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;profileService enabled="true"&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
&amp;nbsp; &amp;nbsp; &amp;nbsp; readAccessProperties="propertyname1,propertyname2"&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;
&amp;nbsp; &amp;nbsp; &amp;nbsp; writeAccessProperties="propertyname1,propertyname2" /&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;webServices&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;!--&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;scriptResourceHandler enableCompression="true"
enableCaching="true" /&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: green"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &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;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;scripting&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;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;system.web.extensions&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&lt;br&gt;
&amp;nbsp; 
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
The most important additions to the web.config to support the Microsoft ASP.NET AJAX
Extensions (MS AJAX from now on) are point 4 and 5. As the ASP.NET HTTP pipeline is
very configurable, those additions can have severe implications on how request are
handled, so I'll start with them.
&lt;/p&gt;
&lt;p&gt;
In the HTTP handlers section, the first line removes the default handling for the
asmx extension, and the second one registers a new handler for the asmx extension.
This simple changes makes that any call to a web service doesn't work as we are used
to. The asmx requests now will go through the ScriptHandlerFactory.
&lt;/p&gt;
&lt;p&gt;
Usually in the HTTP handlers session we register a class that implements the IHttpHanlder
interface. The ProcessRequest method will be called to do all processing. 
&lt;/p&gt;
&lt;p&gt;
However, we can also register a class that implements an IHttpHandlerFactory. In this
case, the method GetHandler will be called in the factory, returning an IHttpHandler
that will handle the request. This is used when you want to return different IHttpHandler
instances depending on some conditions of the request.
&lt;/p&gt;
&lt;p&gt;
When a request that is handled by the ScriptHandlerFactory arrives, it checks if the
request is a REST request (REST is a way to transmit data over HTTP without using
any additional messaging layer. Consult &lt;a href="http://en.wikipedia.org/wiki/REST"&gt;wikipedia&lt;/a&gt; for
more information about it). If it is a REST request, the RestHandlerFactory (a MS
AJAX class) will take care of the request. If it isn't, the WebServiceHandlerFactory
will take care of it. Probably the class WebServiceHandlerFactory won't say much to
you, but this is the class that handles ASMX request in the ASP.NET 2.0, so when an
ASMX request isn't a REST request, it is handled in the same way as we're used to.&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
What is a REST request for MS AJAX? A REST request is an HTTP request that has the
ContentType property set to "application/json" (this is called a REST method request)
or an HTTP request whose path ends with "/js" or "/jsdebug" (this is called a REST
client proxy request).
&lt;/p&gt;
&lt;p&gt;
The RestHandlerFactory checks if the request is for a client proxy or for a REST method.
If the request is for a client proxy, a RestClientProxyHandler is created and servers
the request. The RestClientProxyHandler figures which client proxy has been requested,
gets the client proxy and sends it. All the hard work is done by the WebServiceClientProxyGenerator.GetClientProxyScript
method. Before entering in detail how the client script proxy is generated, lets see
how MS AJAX handles serialization.
&lt;/p&gt;
&lt;p&gt;
Data types are exchanged between client side and server side using JSON (JavaScript
Object Notation). To send data to the client side from the server, the data is serialized,
and to receive it from the client, the data is deserialized in the server.
&lt;/p&gt;
&lt;p&gt;
The main class responsible for this serialization/deserialization process is JavaScriptSerializer.
The public member for the class are:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&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: #2b91af"&gt;JavaScriptSerializer&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; JavaScriptSerializer();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; JavaScriptSerializer(&lt;span style="COLOR: #2b91af"&gt;JavaScriptTypeResolver&lt;/span&gt; resolver);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; MaxJsonLength
{ &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &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;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; RecursionLimit
{ &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &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;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; Serialize(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; obj);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Serialize(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; obj, &lt;span style="COLOR: #2b91af"&gt;StringBuilder&lt;/span&gt; output);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; T Deserialize&amp;lt;T&amp;gt;(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; input);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;object&lt;/span&gt; DeserializeObject(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; input);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; T ConvertToType&amp;lt;T&amp;gt;(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; obj);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; RegisterConverters(IEnumerable&amp;lt;&lt;span style="COLOR: #2b91af"&gt;JavaScriptConverter&lt;/span&gt;&amp;gt;
converters);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&lt;br&gt;
&amp;nbsp;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
The serialization fails if there are more nested objects than RecursionLimit or if
the length of the serialized object is MaxJsonLength.
&lt;/p&gt;
&lt;p&gt;
A serialized object can optionally include type information. The type information
is provided by a class that inherits from JavaScriptTypeResolver, that has the following
methods to get a type from a string and viceversa: 
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;JavaScriptTypeResolver&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Type&lt;/span&gt; ResolveType(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; id);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; ResolveTypeId(&lt;span style="COLOR: #2b91af"&gt;Type&lt;/span&gt; type);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The serializer will add the type information in a field called __type if it has an
associated JavaScriptTypeResolver.
&lt;/p&gt;
&lt;p&gt;
As the JavaScriptSerializer can not serialize/deserialize all types, you can supply
a custom class to support types not directly supported by the JavaScriptSerializer
using the RegisterConverters method. A converter has to inherit from:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;JavaScriptConverter&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IEnumerable&lt;/span&gt;&amp;lt;&lt;span style="COLOR: #2b91af"&gt;Type&lt;/span&gt;&amp;gt;
SupportedTypes
&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;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;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;object&lt;/span&gt; Deserialize(&lt;span style="COLOR: #2b91af"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt;
dictionary, &lt;span style="COLOR: #2b91af"&gt;Type&lt;/span&gt; type, &lt;span style="COLOR: #2b91af"&gt;JavaScriptSerializer&lt;/span&gt; serializer);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;object&lt;/span&gt;&amp;gt;
Serialize(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; obj, &lt;span style="COLOR: #2b91af"&gt;JavaScriptSerializer&lt;/span&gt; serializer);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; 
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
and it has to implement the Serialize and Deserialize methods, as well as providing
the list of supported types.
&lt;/p&gt;
&lt;p&gt;
The standard MS AJAX distribution doesn't have any converter, but you can find a DataSet,
DataTable and DataRow converter in the ASP.NET AJAX Futures release.
&lt;/p&gt;
&lt;p&gt;
The other methods of the JavaScriptSerializer class are just serialize/deserialize
variants, and the ConvertToType method that will be explained later.
&lt;/p&gt;
&lt;p&gt;
The serialization of the basic types is as follows:
&lt;/p&gt;
&lt;p&gt;
null or DBNull.Value -&amp;gt; "null"&lt;br&gt;
bool -&amp;gt; "true" or "false"&lt;br&gt;
char -&amp;gt; if it is '\0', "null", like a string if not&lt;br&gt;
float, double -&amp;gt; ToString("r", CultureInfo.InvariantCulture)&lt;br&gt;
DateTime -&amp;gt; "\/Date(number of milliseconds elapsed since midnight 1970/01/01 UTC)\/"&lt;br&gt;
string -&amp;gt; quoted string&lt;br&gt;
Guid -&amp;gt; "\" + ToString() + "\"&lt;br&gt;
Uri -&amp;gt; "\" + Uri.GetComponents(UriComponents.SerializationInfoString, UriFormat.UriEscaped)
+ "\"&lt;br&gt;
other primitive types and Decimal -&amp;gt; IConvertible.ToString(CultureInfo.InvariantCulture)&lt;br&gt;
Enum -&amp;gt; serialize the integer value of the enum&lt;br&gt;
IDictionary -&amp;gt; JSON object&lt;br&gt;
IEnumerable -&amp;gt; JSON array
&lt;/p&gt;
&lt;p&gt;
A custom object is serialized as a JSON object with the optional member "__type" :
typeName obtained using the JavaScriptResolver, where the other members are obtained
from the public instance fields and public instance properties without the ScriptIgnore
attribute applied.
&lt;/p&gt;
&lt;p&gt;
for more information about &lt;a href="http://www.json.org/"&gt;JSON take a look here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
A Hashtable that compare references is used to throw an error if there is any circular
reference.
&lt;/p&gt;
&lt;p&gt;
Lets show an example of the serialization process. I'm going to use this User and
Address class:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;&lt;span style="COLOR: blue"&gt; 
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&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: #2b91af"&gt;User&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; _id;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; _name;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; _surName;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Address&lt;/span&gt; _address;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;DateTime&lt;/span&gt; _creationDate;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; ID
&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;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; _id;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; { _id = &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;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; Name
&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;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; _name;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; { _name
= &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;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; SurName
&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;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; _surName;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; { _surName
= &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;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; [&lt;span style="COLOR: #2b91af"&gt;ScriptIgnore&lt;/span&gt;]
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; FullName
&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;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; Name
+ &lt;span style="COLOR: #a31515"&gt;" "&lt;/span&gt; + SurName; }
&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;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Address&lt;/span&gt; Address
&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;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; _address;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; { _address
= &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;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;DateTime&lt;/span&gt; CreationDate
&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;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; _creationDate;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; { _creationDate
= &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;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; User()
&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;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;&lt;/span&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&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: #2b91af"&gt;Address&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; _firstLine;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; _secondLine;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; _country;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; FirstLine
&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;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; _firstLine;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; { _firstLine
= &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;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; SecondLine
&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;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; _secondLine;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; { _secondLine
= &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;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; Country
&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;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; _country;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; { _country
= &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;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; Address()
&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;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
With the following code:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;JavaScriptSerializer&lt;/span&gt; js = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;JavaScriptSerializer&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;SimpleTypeResolver&lt;/span&gt;());
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;User&lt;/span&gt; usr = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;User&lt;/span&gt;();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
usr.ID = 12345;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
usr.Name = &lt;span style="COLOR: #a31515"&gt;"John"&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
usr.SurName = &lt;span style="COLOR: #a31515"&gt;"Smith"&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
usr.Address = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: #2b91af"&gt;Address&lt;/span&gt;();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
usr.Address.FirstLine = &lt;span style="COLOR: #a31515"&gt;"1st Avenue, 1234"&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
usr.Address.SecondLine = &lt;span style="COLOR: #a31515"&gt;"San Diego, CA 92101"&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
usr.CreationDate = &lt;span style="COLOR: #2b91af"&gt;DateTime&lt;/span&gt;.Now;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; str = js.Serialize(usr);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;&amp;nbsp;&amp;nbsp;&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
The SimpleTypeResolver inherits from the JavaScriptTypeResolver class explained before,
converting a Type a string using the AssemblyQualifiedName and viceversa.
&lt;/p&gt;
&lt;p&gt;
Is serialized as:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #a31515"&gt;"__type"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"User,
AJAXServerSide1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span style="COLOR: #a31515"&gt;"ID"&lt;/span&gt;:12345,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #a31515"&gt;"Name"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"John"&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #a31515"&gt;"SurName"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"Smith"&lt;font color=#000000&gt;,&lt;/font&gt;&lt;/span&gt;&lt;span style="COLOR: #a31515"&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #a31515"&gt;"Address"&lt;/span&gt;:
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #a31515"&gt;"__type"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"Address,
AJAXServerSide1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #a31515"&gt;"FirstLine"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"1st
Avenue, 1234"&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #a31515"&gt;"SecondLine"&lt;/span&gt;:&lt;span style="COLOR: #a31515"&gt;"San
Diego, CA 92101"&lt;/span&gt;,
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #a31515"&gt;"Country"&lt;/span&gt;:&lt;span style="COLOR: blue"&gt;null&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;font color=#000000&gt;,&lt;/font&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: #a31515"&gt;"CreationDate"&lt;/span&gt;&lt;font color=#000000&gt;:&lt;/font&gt;&lt;span style="COLOR: #a31515"&gt;"\/Date(1173541909382)\/"&lt;/span&gt;
&lt;/p&gt;
&gt; 
&lt;p style="MARGIN: 0px"&gt;
} 
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Note that the FullName property of the User is not serialized because the ScriptIgnore
attribute.
&lt;/p&gt;
&lt;p&gt;
The deserialization process is delegated to the JavaScriptObjectDeserializer class.
This class uses the JavaScriptString and the ObjectConverter class. The JavaScriptString
class is a helper class used to tokenize the JSON data. As when the data is serialized
all types are converted to JSON types (strings, numbers, JSON objects and JSON arrays)
some kind of conversion back to the original type must take place. The JavaScriptObjectDeserializer
does some simple conversions like checking if a string is a character, a boolean,
a date or a null value, most significant conversions are handled by the ConvertObjectToTypeInternal
method of the ObjectConverter class. 
&lt;/p&gt;
&lt;p&gt;
The ConvertObjectToTypeInternal uses the __type field, source object type and destination
type to perform the convertion. If the source data is of type IDictionary it tries
to create an object of the destination type and sets its fields and properties with
the values stored in the dictionary. If the source data is of type IList, it tries
to create a collection of the destination type and adds each of the items of the list
to the collection. If the collection is a generic collection, it extract the item
type of the collection and tries to convert the items as they're added to the collection.
&lt;/p&gt;
&lt;p&gt;
If the source type isn't neither an IDictionary nor an IList, it gets the TypeConverter
for the destination type and check if the source data can be converted to that type.
If the source type doesn't have a conversion to the destination type, it converts
the source type to a string and then tries to convert that string to the destination
type (all of the conversion that involve the TypeConverter use the InvariantCulture). 
&lt;/p&gt;
&lt;p&gt;
If everything fails, a conversion exception is thrown. 
&lt;/p&gt;
&lt;p&gt;
To continue the previous example, this converts the string obtained from the Serialize
method back to an User instance:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: #2b91af"&gt;User&lt;/span&gt; u = js.Deserialize&amp;lt;User&amp;gt;(str);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
When comparing the initial User instance with the deserialized one, the CreationDate
is different by one hour (at least in my machine), so there is a bug in the MS AJAX
code that handles DateTimes :-(
&lt;/p&gt;
&lt;p&gt;
One curious thing about serialization is that the property names are case insensitive
when deserializing an object, as the AssignToPropertyOrField method uses the BindingFlags.IgnoreCase
to retrieve properties and fields. However, when an object is serialized, the properties
for the client code are case sensitive.
&lt;/p&gt;
&lt;p&gt;
I have run out of time for this week but soon I'll continue with the internals of
the additions of MS AJAX to the web.config.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=22a125d3-1ed3-422b-ba2b-89ed63febce3" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,22a125d3-1ed3-422b-ba2b-89ed63febce3.aspx</comments>
      <category>Ajax;ASP.NET;JavaScript</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=560b6980-d109-4047-a886-4c523f090522</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,560b6980-d109-4047-a886-4c523f090522.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,560b6980-d109-4047-a886-4c523f090522.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=560b6980-d109-4047-a886-4c523f090522</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The ObjectDataSource supports using generic classes in the TypeName property although
it doesn't provide any support for it. Usually you'll see that the TypeName property
stores the name of a type (i.e. CustomProject.MyDAL), but it can store the type's
full assembly qualified name (i.e. CustomProject.MyDAL, CustomProject, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=a7a65c534534e209).
</p>
        <p>
The type's full assembly qualified name can be quite complicated and it is described
by the following grammar:
</p>
        <p>
          <br />
          <font face="Courier New">TypeName := NamespaceTypeName | NamespaceTypeName ',' AssemblyNameSpec<br />
 <br />
NamespaceTypeName := NestedTypeName | NamespaceSpec '.' NestedTypeName<br />
 <br />
NestedTypeName := GenericTypeName | NestedTypeName '+' GenericTypeName</font>
        </p>
        <p>
          <font face="Courier New">GenericTypeName := IDENTIFIER | IDENTIFIER '`' Number '['
GenericTypeArgList ']' </font>
        </p>
        <p>
          <font face="Courier New">GenericTypeArgList := GenericTypeArg | GenericTypeArg ','
GenericTypeArgList</font>
        </p>
        <p>
          <font face="Courier New">GenericTypeArg := NamespaceTypeName | '[' TypeSpec ']'<br />
 <br />
NamespaceSpec := IDENTIFIER | NamespaceSpec '.' IDENTIFIER<br />
 <br />
AssemblyNameSpec := IDENTIFIER | IDENTIFIER ',' AssemblyProperties<br />
 <br />
AssemblyProperties := AssemblyProperty | AssemblyProperties ',' AssemblyProperty<br />
 <br />
AssemblyProperty := AssemblyPropertyName '=' AssemblyPropertyValue</font>
        </p>
        <p>
          <br />
For more details about the grammar for type's full assembly qualified name in .NET
Framework v1 take a look <a href="http://msdn2.microsoft.com/en-us/library/yfsftwz6(VS.80).aspx">here</a></p>
        <p>
If you look in detail the grammar, it accept generic type names, that have a '`',
then the number of generic argument and then the generic arguments inside square brackets.
</p>
        <p>
So the following are valid type names:  
</p>
        <p>
          <font face="Courier New">System.Colllections.Generic.List`1[System.Int32], mscorlib</font>
        </p>
        <p>
          <font face="Courier New">MyGraph`2[[Utilities.Set, Utilities],[Utilities.Graph, Utilities]],
MyGraphLibrary</font>
        </p>
        <p>
          <font face="Courier New">MyGraph`2[[Utilities.Set, Utilities, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=a7a65c534534e209],[Utilities.Graph, Utilities, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=a7a65c534534e209]], MyGraphLibrary, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=2134afb4534e209</font>
        </p>
        <p>
So if you want to use a generic type in the ObjectDataSource you just have to specify
it using the syntax explained above. Be sure to add the assembly names if you use
generic types.
</p>
        <p>
What happens if the generic type you want to use is in the App_Code folder? The code
in the App_Code folder gets compiled into a dynamically generated assembly with a
random name so it is impossible to know it. Fortunately, you can use __code as the
assembly name and it will work. Why does this work? When the framework can't resolve
an assembly, the AppDomain AssemblyResolve event is fired. The BuildManager class
(that is a helper class for ASP.NET compilation), captures this event and checks the
specified assembly name. If it is __code, it returns the dynamically generated assembly
for the App_Code folder. Returning App_Code also works (and you save executing a few
instructions).
</p>
        <p>
As an special case, you can use VB, C# or other .NET supported language in the same
web application if you place the code for each language in a different folder. For
example, if you want to use VB and C# you have to create these folders:<br />
App_Code/VB<br />
App_Code/CS
</p>
        <p>
and add this to the web.config:
</p>
        <p>
&lt;codeSubDirectories&gt;<br />
    &lt;add directoryName="VB"/&gt;<br />
    &lt;add directoryName="CS"/&gt;<br />
&lt;/codeSubDirectories&gt;
</p>
        <p>
If you use this configuration two assemblies will be dynamically generated for your
code behind classes, one for each folder. If you want to reference it in the TypeName
of the ObjectDataSource or where the framework expects a fully qualified name you
have to use App_SubCode_VB or App_SubCode_CS.
</p>
        <p>
Of course, the ObjectDataSource doesn't have design time support for this. In fact,
the ObjectDataSource choose type dialog filters out the generic types, the interfaces
and the types registered in the GAC.
</p>
        <p>
The <a href="http://www.manuelabadia.com/products/EODS_features.aspx">ExtendedObjectDataSource</a> will
have full design time support for generic types and more control about the types that
are filtered in the next version:
</p>
        <p>
          <img src="http://www.manuelabadia.com/blog/content/binary/EODS_generics1.png" border="0" />
        </p>
        <p>
When you select a generic type, a textbox and a button appear. You can use the textbox
to specify the type of the generic parameters and click in the button to select the
generic type. Also, there are some checkbox to have control over what types get filtered.
</p>
        <p>
The above dialog has some little positioning issues that I think are caused by Windows
Vista, because the dialog was defined as:
</p>
        <p>
          <img src="http://www.manuelabadia.com/blog/content/binary/EODS_generics2.png" border="0" />
        </p>
        <p>
In a future post I'll talk about generic methods.  
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=560b6980-d109-4047-a886-4c523f090522" />
      </body>
      <title>ObjectDataSource and Generics (part 1)</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,560b6980-d109-4047-a886-4c523f090522.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,560b6980-d109-4047-a886-4c523f090522.aspx</link>
      <pubDate>Wed, 21 Feb 2007 23:52:54 GMT</pubDate>
      <description>&lt;p&gt;
The ObjectDataSource supports using generic classes in the TypeName property although
it doesn't provide any support for it. Usually you'll see that the TypeName property
stores the name of a type (i.e. CustomProject.MyDAL), but it can store the type's
full assembly qualified name (i.e. CustomProject.MyDAL, CustomProject, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=a7a65c534534e209).
&lt;/p&gt;
&lt;p&gt;
The type's full assembly qualified name can be quite complicated and it is described
by the following grammar:
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&lt;font face="Courier New"&gt;TypeName := NamespaceTypeName | NamespaceTypeName ',' AssemblyNameSpec&lt;br&gt;
&amp;nbsp;&lt;br&gt;
NamespaceTypeName := NestedTypeName | NamespaceSpec '.' NestedTypeName&lt;br&gt;
&amp;nbsp;&lt;br&gt;
NestedTypeName := GenericTypeName | NestedTypeName '+' GenericTypeName&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;GenericTypeName := IDENTIFIER | IDENTIFIER '`' Number '['
GenericTypeArgList ']' &lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;GenericTypeArgList := GenericTypeArg | GenericTypeArg ','
GenericTypeArgList&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;GenericTypeArg := NamespaceTypeName | '[' TypeSpec ']'&lt;br&gt;
&amp;nbsp;&lt;br&gt;
NamespaceSpec := IDENTIFIER | NamespaceSpec '.' IDENTIFIER&lt;br&gt;
&amp;nbsp;&lt;br&gt;
AssemblyNameSpec := IDENTIFIER | IDENTIFIER ',' AssemblyProperties&lt;br&gt;
&amp;nbsp;&lt;br&gt;
AssemblyProperties := AssemblyProperty | AssemblyProperties ',' AssemblyProperty&lt;br&gt;
&amp;nbsp;&lt;br&gt;
AssemblyProperty := AssemblyPropertyName '=' AssemblyPropertyValue&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
For more details about the grammar for type's full assembly qualified name in .NET
Framework v1 take a look &lt;a href="http://msdn2.microsoft.com/en-us/library/yfsftwz6(VS.80).aspx"&gt;here&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
If you look in detail the grammar, it accept generic type names, that have a '`',
then the number of generic argument and then the generic arguments inside square brackets.
&lt;/p&gt;
&lt;p&gt;
So the following are valid type names:&amp;nbsp; 
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;System.Colllections.Generic.List`1[System.Int32], mscorlib&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;MyGraph`2[[Utilities.Set, Utilities],[Utilities.Graph, Utilities]],
MyGraphLibrary&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;font face="Courier New"&gt;MyGraph`2[[Utilities.Set, Utilities, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=a7a65c534534e209],[Utilities.Graph, Utilities, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=a7a65c534534e209]], MyGraphLibrary, Version=1.0.0.0, Culture=neutral,
PublicKeyToken=2134afb4534e209&lt;/font&gt;
&lt;/p&gt;
&lt;p&gt;
So if you want to use a generic type in the ObjectDataSource you just have to specify
it using the syntax explained above. Be sure to add the assembly names if you use
generic types.
&lt;/p&gt;
&lt;p&gt;
What happens if the generic type you want to use is in the App_Code folder? The code
in the App_Code folder gets compiled into a dynamically generated assembly with a
random name so it is impossible to know it. Fortunately, you can use __code as the
assembly name and it will work. Why does this work? When the framework can't resolve
an assembly, the AppDomain AssemblyResolve event is fired. The BuildManager class
(that is a helper class for ASP.NET compilation), captures this event and checks the
specified assembly name. If it is __code, it returns the dynamically generated assembly
for the App_Code folder. Returning App_Code also works (and you save executing a few
instructions).
&lt;/p&gt;
&lt;p&gt;
As an special case, you can use VB, C# or other .NET supported language in the same
web application if you place the code for each language in a different folder. For
example, if you want to use VB and C# you have to create these folders:&lt;br&gt;
App_Code/VB&lt;br&gt;
App_Code/CS
&lt;/p&gt;
&lt;p&gt;
and add this to the web.config:
&lt;/p&gt;
&lt;p&gt;
&amp;lt;codeSubDirectories&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add directoryName="VB"/&amp;gt;&lt;br&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;add directoryName="CS"/&amp;gt;&lt;br&gt;
&amp;lt;/codeSubDirectories&amp;gt;
&lt;/p&gt;
&lt;p&gt;
If you use this configuration two assemblies will be dynamically generated for your
code behind classes, one for each folder. If you want to reference it in the TypeName
of the ObjectDataSource or where the framework expects a fully qualified name you
have to use App_SubCode_VB or App_SubCode_CS.
&lt;/p&gt;
&lt;p&gt;
Of course, the ObjectDataSource doesn't have design time support for this. In fact,
the ObjectDataSource choose type dialog filters out the generic types, the interfaces
and the types registered in the GAC.
&lt;/p&gt;
&lt;p&gt;
The &lt;a href="http://www.manuelabadia.com/products/EODS_features.aspx"&gt;ExtendedObjectDataSource&lt;/a&gt; will
have full design time support for generic types and more control about the types that
are filtered in the next version:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/EODS_generics1.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
When you select a generic type, a textbox and a button appear. You can use the textbox
to specify the type of the generic parameters and click in the button to select the
generic type. Also, there are some checkbox to have control over what types get filtered.
&lt;/p&gt;
&lt;p&gt;
The above dialog has some little positioning issues that I think are caused by Windows
Vista, because the dialog was defined as:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/EODS_generics2.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
In a future post I'll talk about generic methods.&amp;nbsp; 
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=560b6980-d109-4047-a886-4c523f090522" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,560b6980-d109-4047-a886-4c523f090522.aspx</comments>
      <category>ASP.NET;Microsoft .NET Framework</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=c8f39803-b507-4449-919a-462198a80645</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,c8f39803-b507-4449-919a-462198a80645.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,c8f39803-b507-4449-919a-462198a80645.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=c8f39803-b507-4449-919a-462198a80645</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <title>Microsoft ASP.NET AJAX v1.0 released!</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,c8f39803-b507-4449-919a-462198a80645.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,c8f39803-b507-4449-919a-462198a80645.aspx</link>
      <pubDate>Wed, 24 Jan 2007 17:17:12 GMT</pubDate>
      <description>&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;span lang=EN-GB style="mso-ansi-language: EN-GB"&gt;Finally the Microsoft AJAX library
1.0 has been released. Take a look to ScottGu's blog for&amp;nbsp;the details:&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;span lang=EN-GB style="mso-ansi-language: EN-GB"&gt;&lt;/span&gt;&amp;nbsp;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;span lang=EN-GB style="mso-ansi-language: EN-GB"&gt;&lt;a href="http://weblogs.asp.net/scottgu/archive/2007/01/23/asp-net-ajax-1-0-released.aspx"&gt;http://weblogs.asp.net/scottgu/archive/2007/01/23/asp-net-ajax-1-0-released.aspx&lt;/a&gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;span lang=EN-GB style="mso-ansi-language: EN-GB"&gt;&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;span lang=EN-GB style="mso-ansi-language: EN-GB"&gt;&lt;?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /&gt;What
is really cool about this is that Microsoft has also released the full source code
for the 
&lt;st1:place w:st="on"&gt;
&lt;st1:City w:st="on"&gt;AJAX&lt;/st1:City&gt;
&lt;/st1:place&gt;
library. That move can give a lot of people that do not work with Microsoft related
technologies a reason to try it and use it, and for the rest of us a chance to take
a look to some of the internals if it is needed.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;span lang=EN-GB style="mso-ansi-language: EN-GB"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;span lang=EN-GB style="mso-ansi-language: EN-GB"&gt;It is a shame that some parts of
the initial ATLAS library like the Bindings didn’t make it in the final release. Anyway,
they’re available in the AJAX Futures CTP and someday will be part of the official
release.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;span lang=EN-GB style="mso-ansi-language: EN-GB"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;span lang=EN-GB style="mso-ansi-language: EN-GB"&gt;Will this mean that we will see
a lot of .NET developers working directly with the Microsoft AJAX library? IMHO, no.
Probably most developers will use the Ajax Control Toolkit and the UpdatePanel to
add 
&lt;st1:place w:st="on"&gt;
&lt;st1:City w:st="on"&gt;AJAX&lt;/st1:City&gt;
&lt;/st1:place&gt;
capabilities to their projects. 
&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;span lang=EN-GB style="mso-ansi-language: EN-GB"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;span lang=EN-GB style="mso-ansi-language: EN-GB"&gt;Creating ASP.NET components that
make use the client side of the Microsoft AJAX library is not easy: You need to know
quite a bunch of stuff: a .NET programming language, ASP.NET, Javascript, HTML, DHTML,
CSS, XML and AJAX Library internals… so I guess a lot of developers are out of luck.&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;span lang=EN-GB style="mso-ansi-language: EN-GB"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;span lang=EN-GB style="mso-ansi-language: EN-GB"&gt;Fortunately, Nikhil’s Script# can
help a bit, and finally changed the type system to be compatible with the AJAX Library
(I asked Nikhil about this a few months ago and I wasn’t sure that he will do it,
but I’m glad he did!).&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;span lang=EN-GB style="mso-ansi-language: EN-GB"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;span lang=EN-GB style="mso-ansi-language: EN-GB"&gt;Also, there is a lot of other new
stuff to look as a .NET developer: WPF, WCF, WF, LINQ, DLINQ, WPF/E. And if you’re
using SQL Server 2005, there are a lot of new things to look at…&lt;o:p&gt;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;span lang=EN-GB style="mso-ansi-language: EN-GB"&gt;
&lt;o:p&gt;&amp;nbsp;&lt;/o:p&gt;
&lt;/span&gt;
&lt;/p&gt;
&lt;p class=MsoNormal style="MARGIN: 0cm 0cm 0pt"&gt;
&lt;span lang=EN-GB style="mso-ansi-language: EN-GB"&gt;Personally I have to learn the Microsoft
AJAX Library in detail but I’m also interested in learning Windows Workflow Foundation,
so I’m not sure in what to center my attention at the moment.&lt;/span&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=c8f39803-b507-4449-919a-462198a80645" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,c8f39803-b507-4449-919a-462198a80645.aspx</comments>
      <category>Ajax;ASP.NET;JavaScript;Microsoft .NET Framework;WPF/E</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=1981d708-5949-4d87-b7f4-ae60df47b298</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,1981d708-5949-4d87-b7f4-ae60df47b298.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,1981d708-5949-4d87-b7f4-ae60df47b298.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=1981d708-5949-4d87-b7f4-ae60df47b298</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Another year ends and a new one comes. Life goes as fast as usual and we’re keep
on our way. It’s time to think about it… our actions, hopes, wishes, mistakes,
etc. 
</p>
        <p>
I usually listen to a special song a few minutes after the start of the year.
In the last few years I have been choosing "Aerosmith – Full Circle" because it has
special connotations for me. 
</p>
        <p>
I wish you the best in the coming year.
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=1981d708-5949-4d87-b7f4-ae60df47b298" />
      </body>
      <title>Happy 2007!</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,1981d708-5949-4d87-b7f4-ae60df47b298.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,1981d708-5949-4d87-b7f4-ae60df47b298.aspx</link>
      <pubDate>Mon, 01 Jan 2007 23:36:54 GMT</pubDate>
      <description>&lt;p&gt;
Another year ends and a new one comes. Life goes as fast as usual and we’re&amp;nbsp;keep
on&amp;nbsp;our way. It’s time to think about it… our actions, hopes, wishes, mistakes,
etc. 
&lt;/p&gt;
&lt;p&gt;
I usually listen to a special song&amp;nbsp;a few minutes after the start of the year.
In the last few years I have been choosing "Aerosmith – Full Circle" because it has
special connotations for me. 
&lt;/p&gt;
&lt;p&gt;
I wish you the best in the coming year.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=1981d708-5949-4d87-b7f4-ae60df47b298" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,1981d708-5949-4d87-b7f4-ae60df47b298.aspx</comments>
      <category>Ajax;ANTLR;ASP.NET;CSS;Games;General;JavaScript;Microsoft .NET Framework;Music;WPF/E</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=6a92c0cd-8138-4dca-93a8-c7c301759179</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,6a92c0cd-8138-4dca-93a8-c7c301759179.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,6a92c0cd-8138-4dca-93a8-c7c301759179.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=6a92c0cd-8138-4dca-93a8-c7c301759179</wfw:commentRss>
      <slash:comments>6</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I haven’t paid too much attention to WPF but after the first CTP of WPF/E I was curious
to see what is the status of WPF/E (mostly, because I had a project in mind that needed
some vector graphics and I was going to use SVG to do it) so I installed it and take
a quick look at it.
</p>
        <p>
You can install it here:
</p>
        <p>
          <u>
            <font color="#800080">
              <a href="http://go.microsoft.com/fwlink/?linkid=77791&amp;clcid=0x409">http://go.microsoft.com/fwlink/?linkid=77791&amp;clcid=0x409</a>
            </font>
          </u>
          <a href="http://msdn2.microsoft.com/en-us/asp.net/bb187358.aspx">
          </a>
        </p>
        <p>
And an introduction video can be watched here:
</p>
        <p>
          <a href="http://channel9.msdn.com/showpost.aspx?postid=263358">http://channel9.msdn.com/showpost.aspx?postid=263358</a>
        </p>
        <p>
The truth is that I am a bit dissapointed with it, but don’t get me wrong. WPF/E is
a cool idea in the initial stages of development, so with a bit of luck it can evolve
to something really useful. However, this initial release lacks a lot of stuff: 
<br />
- there isn’t any direct pixel manipulation method available making this a very
limiting factor for games. 
<br />
- there isn’t any input control.<br />
- missing keyboard support.<br />
- Also there isn’t a linux version yet. 
<br />
- The SDK samples aren't as good as the ones shown in the video.
</p>
        <p>
Hopefully those problems will be addressed in future releases if Microsoft wants to
create something that can replace flash in a lot of scenarios. Currently is only usable
for displaying charts, shapes and video.
</p>
        <p>
Also, as a MSDN professional subscriber, I’m a bit pissed of because the Microsoft
Expression suite isn’t available to us, but that’s another story…<br /></p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=6a92c0cd-8138-4dca-93a8-c7c301759179" />
      </body>
      <title>WPF/E - First impressions</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,6a92c0cd-8138-4dca-93a8-c7c301759179.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,6a92c0cd-8138-4dca-93a8-c7c301759179.aspx</link>
      <pubDate>Tue, 19 Dec 2006 18:02:16 GMT</pubDate>
      <description>&lt;p&gt;
I haven’t paid too much attention to WPF but after the first CTP of WPF/E I was curious
to see what is the status of WPF/E (mostly, because I had a project in mind that needed
some vector graphics and I was going to use SVG to do it) so I installed it and take
a quick look at it.
&lt;/p&gt;
&lt;p&gt;
You can install it here:
&lt;/p&gt;
&lt;p&gt;
&lt;u&gt;&lt;font color=#800080&gt;&lt;a href="http://go.microsoft.com/fwlink/?linkid=77791&amp;amp;clcid=0x409"&gt;http://go.microsoft.com/fwlink/?linkid=77791&amp;amp;clcid=0x409&lt;/a&gt;&lt;/font&gt;&lt;/u&gt;&lt;a href="http://msdn2.microsoft.com/en-us/asp.net/bb187358.aspx"&gt;&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
And an introduction video can be watched here:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://channel9.msdn.com/showpost.aspx?postid=263358"&gt;http://channel9.msdn.com/showpost.aspx?postid=263358&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
The truth is that I am a bit dissapointed with it, but don’t get me wrong. WPF/E is
a cool idea in the initial stages of development, so with a bit of luck it can evolve
to something really useful. However, this initial release lacks a lot of stuff: 
&lt;br&gt;
-&amp;nbsp;there isn’t any direct pixel manipulation method available making this a very
limiting factor for games. 
&lt;br&gt;
-&amp;nbsp;there isn’t any input control.&lt;br&gt;
-&amp;nbsp;missing keyboard support.&lt;br&gt;
-&amp;nbsp;Also there isn’t a linux version yet. 
&lt;br&gt;
- The SDK samples aren't as good as the ones shown in the video.
&lt;/p&gt;
&lt;p&gt;
Hopefully those problems will be addressed in future releases if Microsoft wants to
create something that can replace flash in a lot of scenarios. Currently is only usable
for displaying charts, shapes and video.
&lt;/p&gt;
&lt;p&gt;
Also, as a MSDN professional subscriber, I’m a bit pissed of because the Microsoft
Expression suite isn’t available to us, but that’s another story…&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=6a92c0cd-8138-4dca-93a8-c7c301759179" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,6a92c0cd-8138-4dca-93a8-c7c301759179.aspx</comments>
      <category>ASP.NET;WPF/E</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=6839c49c-d9c9-4fc7-80e0-1fc4dd384cdc</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,6839c49c-d9c9-4fc7-80e0-1fc4dd384cdc.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,6839c49c-d9c9-4fc7-80e0-1fc4dd384cdc.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=6839c49c-d9c9-4fc7-80e0-1fc4dd384cdc</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I couldn’t resist to improve StructsViz in order to add support for trees. Even if
everybody has his own tree implementation, we can come up with a common agreement: 
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
            <strong>
              <em>A tree is a collection of nodes, where each node has zero or more child
nodes. Each node has zero or one parent. The only node that doesn’t have a parent
is the root node.</em>
            </strong>
          </p>
        </blockquote>
        <p>
So based on the previous definition, I have defined this interface that is mandatory
to implement in order to visualize a tree node in StructsViz:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">public</span>
            <span style="COLOR: blue">interface</span>
            <span style="COLOR: teal">ITreeNode</span>&lt;T&gt;
</p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    T Value { <span style="COLOR: blue">get</span>; <span style="COLOR: blue">set</span>;
}
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: teal">ITreeNode</span>&lt;T&gt; Parent { <span style="COLOR: blue">get</span>; <span style="COLOR: blue">set</span>;
}
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">bool</span> HasChildren { <span style="COLOR: blue">get</span>;
}
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: teal">ICollection</span>&lt;<span style="COLOR: teal">ITreeNode</span>&lt;T&gt;&gt;
Children { <span style="COLOR: blue">get</span>; }
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
I think that any tree node implementation can easily implement this interface. 
</p>
        <p>
With that interface implemented, StructsViz will be able to draw your tree node.
</p>
        <p>
I have been playing a bit with automatic layout positioning for trees, and with different
kind of connections:
</p>
        <img src="http://www.manuelabadia.com/blog/content/binary/tree1.PNG" border="0" />
        <br />
        <img src="http://www.manuelabadia.com/blog/content/binary/tree2.PNG" border="0" />
        <br />
        <img src="http://www.manuelabadia.com/blog/content/binary/tree3.PNG" border="0" />
        <br />
        <br />
        <p>
 
</p>
        <p>
The pictures show debug information of the subtree areas needed to position the elements
properly using a recursive algorithm. For example, the rectangle labeled as ST 2,
is the subtree area for node 2, and it is calculated based on the ST 6 and ST 7 (subtree
areas for node 6 and 7 respectively). With ST 1, ST 2 and ST 3, we can properly position
node 0.
</p>
        <p>
I’m giving the final touches to this and it will be included in the next StructsViz
version.<br /></p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=6839c49c-d9c9-4fc7-80e0-1fc4dd384cdc" />
      </body>
      <title>Debugging trees</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,6839c49c-d9c9-4fc7-80e0-1fc4dd384cdc.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,6839c49c-d9c9-4fc7-80e0-1fc4dd384cdc.aspx</link>
      <pubDate>Sat, 02 Dec 2006 16:17:59 GMT</pubDate>
      <description>&lt;p&gt;
I couldn’t resist to improve StructsViz in order to add support for trees. Even if
everybody has his own tree implementation, we can come up with a common agreement: 
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
&lt;strong&gt;&lt;em&gt;A tree is a collection of nodes, where each node has zero or more child
nodes. Each node has zero or one parent. The only node that doesn’t have a parent
is the root node.&lt;/em&gt;&lt;/strong&gt;
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
So based on the previous definition, I have defined this interface that is mandatory
to implement in order to visualize a tree node in StructsViz:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;interface&lt;/span&gt; &lt;span style="COLOR: teal"&gt;ITreeNode&lt;/span&gt;&amp;lt;T&amp;gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; T Value { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &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;span style="COLOR: teal"&gt;ITreeNode&lt;/span&gt;&amp;lt;T&amp;gt; Parent { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; &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;span style="COLOR: blue"&gt;bool&lt;/span&gt; HasChildren { &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;span style="COLOR: teal"&gt;ICollection&lt;/span&gt;&amp;lt;&lt;span style="COLOR: teal"&gt;ITreeNode&lt;/span&gt;&amp;lt;T&amp;gt;&amp;gt;
Children { &lt;span style="COLOR: blue"&gt;get&lt;/span&gt;; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
I think that any tree node implementation can easily implement this interface. 
&lt;/p&gt;
&lt;p&gt;
With that interface implemented, StructsViz will be able to draw your tree node.
&lt;/p&gt;
&lt;p&gt;
I have been playing a bit with automatic layout positioning for trees, and with different
kind of connections:
&lt;/p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/tree1.PNG" border=0&gt;
&lt;br&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/tree2.PNG" border=0&gt;
&lt;br&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/tree3.PNG" border=0&gt;
&lt;br&gt;
&lt;br&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The pictures show debug information of the subtree areas needed to position the elements
properly using a recursive algorithm. For example, the rectangle labeled as ST 2,
is the subtree area for node 2, and it is calculated based on the ST 6 and ST 7 (subtree
areas for node 6 and 7 respectively). With ST 1, ST 2 and ST 3, we can properly position
node 0.
&lt;/p&gt;
&lt;p&gt;
I’m giving the final touches to this and it will be included in the next StructsViz
version.&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=6839c49c-d9c9-4fc7-80e0-1fc4dd384cdc" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,6839c49c-d9c9-4fc7-80e0-1fc4dd384cdc.aspx</comments>
      <category>ASP.NET;Microsoft .NET Framework</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=3eb29015-3e3b-484f-8d81-392b893667e6</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,3eb29015-3e3b-484f-8d81-392b893667e6.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,3eb29015-3e3b-484f-8d81-392b893667e6.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=3eb29015-3e3b-484f-8d81-392b893667e6</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Visual Studio.NET 2005 has a really cool feature called debugger visualizers. When
you are inspecting an object while debugging, there are times that the standard inspection
of fields and properties of the debugger is not the best way to check if the internal
state of the object is correct. For example, a DataSet is very difficult to debug,
because the data is stored in a long hierarchy of objects. A debugger visualizer is
a viewer of objects of a predetermined type that presents the object to the developer
using a custom UI that helps debugging it.
</p>
        <p>
The debugger visualizer executes on a different application domain than the application
we’re debugging so to access the object being inspected the data needs to be sent
from one application domain to the other application domain. This implies that the
object we’re inspecting needs to be serializable or we need to create a serializable
proxy in order to visualize it.
</p>
        <p>
There are quite a few articles on the web about debugger visualizers so I will not
enter in detail in the process of writing a visualizer, but I’ll explain the basics.
As I explained before, the visualizer runs in a different application domain than
the process we’re debugging. To communicate those application domains, an object that
inherits from VisualizerObjectSource is created. The visualizer inherits from the
DialogDebuggerVisualizer class and has to implement the Show method, showing a custom
dialog. Before showing the dialog, the visualizer usually retrieves data requesting
it to the VisualizerObjectSource using an intermediate object that implements the
IVisualizerObjectProvider.
</p>
        <p>
The main method of the VisualizerObjectSource is GetData, where the object being debugged
should be sent through a stream. If the object being debugged is big, this could be
a long operation so a thing that can be done is to send a simplified object in the
GetData method, and when the user wants to see more detail of the simplified object,
transfer a more data using the TransferData method.
</p>
        <p>
A data structure is something that is better represented graphically so I spent some
days writing a bunch of visualizers for all the .NET System.Collections.* classes.
Here you have some pics of it:
</p>
        <img alt="Stack visualizer" src="http://www.manuelabadia.com/products/content-images/stackvisualizer.png" />
        <img alt="StringDictionary visualizer" src="http://www.manuelabadia.com/products/content-images/stringdictionaryvisualizer.png" />
        <img alt="Custom collection visualizer" src="http://www.manuelabadia.com/products/content-images/customcollectionvisualizer.png" />
        <p>
I had to write a basic diagramming engine in order to get some nice results. Writing
the diagramming engine was the funniest part. I wanted a lot of flexibility so I end
up implementing absolute and relative element positioning, cascading styles, shape
composition, expandable elements, automatic layout adjustment, zooming, etc. I think
that the resulting object model was pretty good even if it isn’t a complete diagramming
engine.
</p>
        <p>
After some work with the debugger visualizers, a big limitation surfaces. You can
only attach a visualizer to classes and not to interfaces. I think Microsoft should
change this is the next version as this is severely limiting the power of the visualizers.
</p>
        <p>
Also, it is a shame that the .NET framework doesn’t include more complex data structures
like a Tree or a Graph. A visualizer for a Dictionary, a List or a Queue can be useful,
but a visualizer for a Tree and a Graph is very very useful. Every developer has to
code his own Tree and Graph, so creating a viewer for them will make the developers
to use my implementation if they want to visualize it because of the limitation of
the debugger visualizers, and that can’t be done in a lot of cases.
</p>
        <p>
You can read more about the visualizer pack here:
</p>
        <p>
          <a href="http://www.manuelabadia.com/products/StructsViz_features.aspx">http://www.manuelabadia.com/products/StructsViz_features.aspx</a>
        </p>
        <p>
You can take a look to the evaluation version here:
</p>
        <p>
          <a href="http://www.manuelabadia.com/products/Purchase.aspx">http://www.manuelabadia.com/products/Purchase.aspx</a>
          <br />
        </p>
        <p>
        </p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=3eb29015-3e3b-484f-8d81-392b893667e6" />
      </body>
      <title>Debugger Visualizers and Data Structures</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,3eb29015-3e3b-484f-8d81-392b893667e6.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,3eb29015-3e3b-484f-8d81-392b893667e6.aspx</link>
      <pubDate>Sun, 26 Nov 2006 23:37:06 GMT</pubDate>
      <description>&lt;p&gt;
Visual Studio.NET 2005 has a really cool feature called debugger visualizers. When
you are inspecting an object while debugging, there are times that the standard inspection
of fields and properties of the debugger is not the best way to check if the internal
state of the object is correct. For example, a DataSet is very difficult to debug,
because the data is stored in a long hierarchy of objects. A debugger visualizer is
a viewer of objects of a predetermined type that presents the object to the developer
using a custom UI that helps debugging it.
&lt;/p&gt;
&lt;p&gt;
The debugger visualizer executes on a different application domain than the application
we’re debugging so to access the object being inspected the data needs to be sent
from one application domain to the other application domain. This implies that the
object we’re inspecting needs to be serializable or we need to create a serializable
proxy in order to visualize it.
&lt;/p&gt;
&lt;p&gt;
There are quite a few articles on the web about debugger visualizers so I will not
enter in detail in the process of writing a visualizer, but I’ll explain the basics.
As I explained before, the visualizer runs in a different application domain than
the process we’re debugging. To communicate those application domains, an object that
inherits from VisualizerObjectSource is created. The visualizer inherits from the
DialogDebuggerVisualizer class and has to implement the Show method, showing a custom
dialog. Before showing the dialog, the visualizer usually retrieves data requesting
it to the VisualizerObjectSource using an intermediate object that implements the
IVisualizerObjectProvider.
&lt;/p&gt;
&lt;p&gt;
The main method of the VisualizerObjectSource is GetData, where the object being debugged
should be sent through a stream. If the object being debugged is big, this could be
a long operation so a thing that can be done is to send a simplified object in the
GetData method, and when the user wants to see more detail of the simplified object,
transfer a more data using the TransferData method.
&lt;/p&gt;
&lt;p&gt;
A data structure is something that is better represented graphically so I spent some
days writing a bunch of visualizers for all the .NET System.Collections.* classes.
Here you have some pics of it:
&lt;/p&gt;
&lt;img alt="Stack visualizer" src="http://www.manuelabadia.com/products/content-images/stackvisualizer.png"&gt; &lt;img alt="StringDictionary visualizer" src="http://www.manuelabadia.com/products/content-images/stringdictionaryvisualizer.png"&gt; &lt;img alt="Custom collection visualizer" src="http://www.manuelabadia.com/products/content-images/customcollectionvisualizer.png"&gt; 
&lt;p&gt;
I had to write a basic diagramming engine in order to get some nice results. Writing
the diagramming engine was the funniest part. I wanted a lot of flexibility so I end
up implementing absolute and relative element positioning, cascading styles, shape
composition, expandable elements, automatic layout adjustment, zooming, etc. I think
that the resulting object model was pretty good even if it isn’t a complete diagramming
engine.
&lt;/p&gt;
&lt;p&gt;
After some work with the debugger visualizers, a big limitation surfaces. You can
only attach a visualizer to classes and not to interfaces. I think Microsoft should
change this is the next version as this is severely limiting the power of the visualizers.
&lt;/p&gt;
&lt;p&gt;
Also, it is a shame that the .NET framework doesn’t include more complex data structures
like a Tree or a Graph. A visualizer for a Dictionary, a List or a Queue can be useful,
but a visualizer for a Tree and a Graph is very very useful. Every developer has to
code his own Tree and Graph, so creating a viewer for them will make the developers
to use my implementation if they want to visualize it because of the limitation of
the debugger visualizers, and that can’t be done in a lot of cases.
&lt;/p&gt;
&lt;p&gt;
You can read more about the visualizer pack here:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.manuelabadia.com/products/StructsViz_features.aspx"&gt;http://www.manuelabadia.com/products/StructsViz_features.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
You can take a look to the evaluation version here:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.manuelabadia.com/products/Purchase.aspx"&gt;http://www.manuelabadia.com/products/Purchase.aspx&lt;/a&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=3eb29015-3e3b-484f-8d81-392b893667e6" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,3eb29015-3e3b-484f-8d81-392b893667e6.aspx</comments>
      <category>ASP.NET;Microsoft .NET Framework</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=23bf78a6-e5b3-441f-9b89-e500b5c787c7</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,23bf78a6-e5b3-441f-9b89-e500b5c787c7.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,23bf78a6-e5b3-441f-9b89-e500b5c787c7.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=23bf78a6-e5b3-441f-9b89-e500b5c787c7</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I have spent most of the last weeks changing some designs to use pure CSS layouts
instead of table based designs and having to support IE 5.0+.  So you can imagine
my frustation level. It’s really sad to see the required work to make a complex design
work in IE 5.0, IE 5.5 MAC IE 5, IE 6, IE 7, Firefox, Safari and Opera. IE versions
prior to IE 6 are really terrible in CSS compliance and you need to have solid IE
bug theory to fix those limitations. 
</p>
        <p>
It is really sad that here (in Spain) and maybe in other countries too, there are
still a significative percentage of users using IE 5.0 and IE 5.5. IMO there should
be some kind of movement to delete old browsers from the earth. For example, in Europe
there will be an analogic TV shutdown before 2012. There should be something similar
periodically for old browsers. For example every year most of the webpages should
use an updated script to completely fail in browsers older than 2 or 3 years, forcing
the people to upgrade because most of the webpages they visit will not work for them
(as some people will only upgrade for that reason).
</p>
        <p>
Talking about browsers, it is sad to see that IE 7 does not pass the ACID2 tests.
Also Firefox, the browser that claimed to be more standard compliant than IE and that
will save our souls, doesn’t pass the ACID2 tests either (in the 2.0 release). The
first version of Firefox was very good compared to the browsers out there but now
they haven’t improved it very much lately. Anyway, the developer extensions for firefox
are so good that it is a must have. I was very surprised with Opera 9 because it passed
ACID2 tests, has finally added support for rich text editing so things like R.A.D.
editor (<a href="http://www.telerik.com">www.telerik.com</a>) finally works and it
has an excellent zoom tool, not like the Firefox one that the only thing that does
is to break all pages when you zoom a bit.
</p>
        <p>
But to be fair, a big part of the problems are because of the lack of a reference
implementation by the W3C. CSS will be better designed and more trouble free with
a reference implementation so the people defining and implementing the standard can
play with. It won’t be too difficult to produce automated tests to compare rendered
web pages with different implementations of the standard using a common set of stylesheets
and fonts, so a pixel perfect comparision will be possible if the rendering engines
do not employ any dithering. Having a reference implementation to play with will also
help in making a more robust and useful specification (why is so complex to align
something vertically in CSS when aligning it horizontally is trivial?).
</p>
        <p>
Will this situation change some day? It is changing slowly but with some help it will
be able to change faster and let us focus in real problems and not in stupid incompatibility
problems that only causes us headaches and slow down web evolution.
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=23bf78a6-e5b3-441f-9b89-e500b5c787c7" />
      </body>
      <title>*&amp;&amp;$&amp;# CSS incompatibilities</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,23bf78a6-e5b3-441f-9b89-e500b5c787c7.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,23bf78a6-e5b3-441f-9b89-e500b5c787c7.aspx</link>
      <pubDate>Fri, 27 Oct 2006 23:34:44 GMT</pubDate>
      <description>&lt;p&gt;
I have spent most of the last weeks changing some designs to use pure CSS layouts
instead of table based designs and having to support IE 5.0+.&amp;nbsp; So you can imagine
my frustation level. It’s really sad to see the required work to make a complex design
work in IE 5.0, IE 5.5 MAC IE 5, IE 6, IE 7, Firefox, Safari and Opera. IE versions
prior to IE 6 are really terrible in CSS compliance and you need to have solid IE
bug theory to fix those limitations. 
&lt;/p&gt;
&lt;p&gt;
It is really sad that here (in Spain) and maybe in other countries too, there are
still a significative percentage of users using IE 5.0 and IE 5.5. IMO there should
be some kind of movement to delete old browsers from the earth. For example, in Europe
there will be an analogic TV shutdown before 2012. There should be something similar
periodically for old browsers. For example every year most of the webpages should
use an updated script to completely fail in browsers older than 2 or 3 years, forcing
the people to upgrade because most of the webpages they visit will not work for them
(as some people will only upgrade for that reason).
&lt;/p&gt;
&lt;p&gt;
Talking about browsers, it is sad to see that IE 7 does not pass the ACID2 tests.
Also Firefox, the browser that claimed to be more standard compliant than IE and that
will save our souls, doesn’t pass the ACID2 tests either (in the 2.0 release). The
first version of Firefox was very good compared to the browsers out there but now
they haven’t improved it very much lately. Anyway, the developer extensions for firefox
are so good that it is a must have. I was very surprised with Opera 9 because it passed
ACID2 tests, has finally added support for rich text editing so things like R.A.D.
editor (&lt;a href="http://www.telerik.com"&gt;www.telerik.com&lt;/a&gt;) finally works and it
has an excellent zoom tool, not like the Firefox one that the only thing that does
is to break all pages when you zoom a bit.
&lt;/p&gt;
&lt;p&gt;
But to be fair, a big part of the problems are because of the lack of a reference
implementation by the W3C. CSS will be better designed and more trouble free with
a reference implementation so the people defining and implementing the standard can
play with. It won’t be too difficult to produce automated tests to compare rendered
web pages with different implementations of the standard using a common set of stylesheets
and fonts, so a pixel perfect comparision will be possible if the rendering engines
do not employ any dithering. Having a reference implementation to play with will also
help in making a more robust and useful specification (why is so&amp;nbsp;complex to align
something vertically in CSS when aligning it horizontally is trivial?).
&lt;/p&gt;
&lt;p&gt;
Will this situation change some day? It is changing slowly but with some help it will
be able to change faster and let us focus in real problems and not in stupid incompatibility
problems that only causes us headaches and slow down web evolution.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=23bf78a6-e5b3-441f-9b89-e500b5c787c7" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,23bf78a6-e5b3-441f-9b89-e500b5c787c7.aspx</comments>
      <category>Ajax;ASP.NET;CSS;JavaScript</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=e440e756-b3fa-4ec2-aea7-f2f28dee1a38</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,e440e756-b3fa-4ec2-aea7-f2f28dee1a38.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,e440e756-b3fa-4ec2-aea7-f2f28dee1a38.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=e440e756-b3fa-4ec2-aea7-f2f28dee1a38</wfw:commentRss>
      <slash:comments>5</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Note: Bertrand Le Roy has confirmed that the next Microsoft AJAX Library release will
use the prototype based approach instead of the closure approach (really great news!),
and clearly explains the differences:
</p>
        <p>
          <a href="http://weblogs.asp.net/bleroy/archive/2006/10/11/From-closures-to-prototypes_2C00_-part-1.aspx">http://weblogs.asp.net/bleroy/archive/2006/10/11/From-closures-to-prototypes_2C00_-part-1.aspx</a>
        </p>
        <p>
In <a href="http://www.manuelabadia.com/blog/PermaLink,guid,c59facc0-301e-4e30-898d-428038828dcd.aspx">part
1</a> we saw how the inheritance infrastructure worked, how to create namespaces,
and how to create classes. Now it is time to continue with the other stuff.
</p>
        <p>
          <strong>Interfaces</strong>
        </p>
        <p>
To create an interface is similar to create a class, but we use the registerInterface
method instead and we define the methods to be abstract. For example:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.MyInterface = <span style="COLOR: blue">function</span>() {
</p>
          <p style="MARGIN: 0px">
   <span style="COLOR: blue">this</span>.method1 = Function.abstractMethod;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.MyInterface.registerInterface(<span style="COLOR: maroon">'Manu.Atlas.Tests.MyInterface'</span>);
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
We can define the interface using the prototype method instead of the closure method:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
            <p style="MARGIN: 0px">
Manu.Atlas.Tests.MyInterface = <span style="COLOR: blue">function</span>() {
</p>
            <p style="MARGIN: 0px">
}
</p>
            <p style="MARGIN: 0px">
 
</p>
            <p style="MARGIN: 0px">
Manu.Atlas.Tests.MyInterface.prototype.method1 = Function.abstractMethod;
</p>
            <p style="MARGIN: 0px">
 
</p>
            <p style="MARGIN: 0px">
Manu.Atlas.Tests.MyInterface.registerInterface(<span style="COLOR: maroon">'Manu.Atlas.Tests.MyInterface'</span>);
</p>
          </div>
          <!--EndFragment-->
        </div>
        <p>
 
</p>
        <p>
The registerInterface method (defined in the Function type) just set the _typeName
of the type where the method is invoked, and sets the boolean properties _interface,
_abstract and _sealed to true.
</p>
        <p>
          <strong>Enumerations</strong>
        </p>
        <p>
There are two kinds of enumerations that we can create. One where the enumeration
items act as flags so we may want to combine them and the other type is where we can’t
combine the enumeration items.
</p>
        <p>
The first type is created using the createFlags method and the second one is created
using the createEnum method (of the Type class). The parameters for those methods
are:
</p>
        <p>
Type.createFlags(enumerationName, enumerationItems)<br />
Type.createEnum(enumerationName, enumerationItems)
</p>
        <p>
          <br />
Where enumerationName is the name of the enumeration, and enumerationItems are a variable
number of parameters that specify the different enumeration items. Each item in the
enumeration is specified as two parameters, the first is the string with the item
name, and the second the associated value.
</p>
        <p>
The common methods are:<br />
• toString: converts the value passed to the method to a string.<br />
• parse: converts the string passed to a value.<br />
• getName: returns the name of the enumeration
</p>
        <p>
The enumeration where you can use the items as flags has a method called isFlags that
return true. The other enumeration type has a method called isEnum that returns true,
and a method called getValues that returns a hashtable with the items of the enumeration.
</p>
        <p>
An example follows:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
Type.createEnum(<span style="COLOR: maroon">'Manu.Atlas.Tests.MyEnum'</span>, <span style="COLOR: maroon">'enum_item1'</span>,
1, <span style="COLOR: maroon">'enum_item2'</span>, 2);
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">var</span> val = Manu.Atlas.Tests.MyEnum.enum_item1;
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">var</span> str = Manu.Atlas.Tests.MyEnum.toString(val);
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">var</span> valaux = Manu.Atlas.Tests.MyEnum.parse(<span style="COLOR: maroon">'enum_item2'</span>);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
Type.createFlags(<span style="COLOR: maroon">'Manu.Atlas.Tests.MyEnum2'</span>, <span style="COLOR: maroon">'enum_item1'</span>,
1, <span style="COLOR: maroon">'enum_item2'</span>, 2, <span style="COLOR: maroon">'enum_item3'</span>,
4);
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">var</span> val2 = Manu.Atlas.Tests.MyEnum2.enum_item1 |
Manu.Atlas.Tests.MyEnum2.enum_item3;
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">var</span> str2 = Manu.Atlas.Tests.MyEnum2.toString(val2);
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">var</span> val2aux = Manu.Atlas.Tests.MyEnum2.parse(<span style="COLOR: maroon">'enum_item2
| enum_item3'</span>);
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
The values of the variables after execution are:
</p>
        <p>
val = 1<br />
str = “enum_item1”<br />
valaux = 2<br />
val2 = 5<br />
str2 = “enum_item1 | enum_item3”<br />
val2aux = 6
</p>
        <p>
Both kinds of enumerations are implemented the same way. A hashtable with the same
name as the enumeration is created, and each enumeration item name is stored as a
key of the hashtable and the enumeration item value is stored as the associated value
for the key.
</p>
        <p>
From now on, when showing a class or an interface, I’ll be using C# syntax to show
it instead of the JavaScript version of the class for clarity. The naming convention
for the JavaScript classes is distinct from the C# naming convention so if a property
is called Text in C#, the equivalent getter and setter will be get_text and set_text
instead of get_Text and set_Text, so don’t get confused.
</p>
        <p>
          <strong>Attributes</strong>
        </p>
        <p>
In .NET is very common to decorate classes, properties and methods with attributes
that provide useful information about them. The Microsoft AJAX library adds this extension
to JavaScript.
</p>
        <p>
The attributes are very important to generate reusable code. The xml-script parsing
process and the validation controls use it.
</p>
        <p>
An attribute is a static property of the class Sys.Attributes. The class has a method
called defineAttribute that creates a new attribute:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
Sys.Attributes.defineAttribute(<span style="COLOR: maroon">'MyCustomAttribute'</span>);
</p>
        </div>
        <!--EndFragment-->
        <p>
After having created the attribute we can reference it using Sys.Attributes. 'MyCustomAttribute.
The attributes can be associated to a class or to a property as we will see in the
next section. 
</p>
        <p>
          <strong>Reflection</strong>
        </p>
        <p>
Even if JavaScript has some flexibility that can be used to perform some tasks similar
to what reflection does (retrieve all fields from an object, retrieve a field from
an instance using a string with the property name, invoke a method from an object
based on the method name, etc), as the Microsoft AJAX library added OO features to
it, it has to provide a way to interact with all the new OO infrastructure generically
and more .NET friendly.
</p>
        <p>
These features are provided by the Sys.TypeDescriptor class. Most of the classes in
the library implement the interface ITypeDescriptorProvider:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">public</span>
            <span style="COLOR: blue">interface</span>
            <span style="COLOR: teal">ITypeDescriptorProvider</span>
          </p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: teal">TypeDescriptor</span> GetDescriptor();
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
The only method present in the interface returns the TypeDescriptor for the class
implementing the interface.
</p>
        <p>
The TypeDescriptor class is like this:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">public</span>
            <span style="COLOR: blue">sealed</span>
            <span style="COLOR: blue">class</span>
            <span style="COLOR: teal">TypeDescriptor</span>
          </p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">void</span> AddAttribute(<span style="COLOR: blue">string</span> name, <span style="COLOR: blue">object</span> value);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">void</span> AddEvent(<span style="COLOR: blue">string</span> name, <span style="COLOR: blue">object</span> supportActions);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">void</span> AddMethod(<span style="COLOR: blue">string</span> name, <span style="COLOR: blue">object</span> value);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">void</span> AddProperty(<span style="COLOR: blue">string</span> name, <span style="COLOR: teal">Type</span> type, <span style="COLOR: blue">bool</span> readOnly, <span style="COLOR: blue">params</span><span style="COLOR: blue">object</span>[]
attributes);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span> TypeDescriptor();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">static</span><span style="COLOR: blue">void</span> AddType(<span style="COLOR: blue">string</span> tagPrefix, <span style="COLOR: blue">string</span> tagName, <span style="COLOR: teal">Type</span> type);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">static</span><span style="COLOR: teal">Type</span> GetPropertyType(<span style="COLOR: blue">object</span> instance, <span style="COLOR: blue">string</span> name, <span style="COLOR: blue">string</span> key);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">static</span><span style="COLOR: teal">Type</span> GetType(<span style="COLOR: blue">string</span> tagPrefix, <span style="COLOR: blue">string</span> tagName);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">static</span><span style="COLOR: teal">TypeDescriptor</span> GetTypeDescriptor(<span style="COLOR: blue">object</span> instance);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">static</span><span style="COLOR: blue">object</span> InvokeMethod(<span style="COLOR: blue">object</span> instance, <span style="COLOR: blue">string</span> name, <span style="COLOR: blue">object</span>[]
parameters);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">static</span><span style="COLOR: teal">ParameterInfo</span> CreateParameter(<span style="COLOR: blue">string</span> name, <span style="COLOR: teal">Type</span> type);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">static</span><span style="COLOR: blue">string</span> GetAttribute(<span style="COLOR: blue">object</span> instance, <span style="COLOR: blue">string</span> name);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">static</span><span style="COLOR: blue">object</span> GetProperty(<span style="COLOR: blue">object</span> instance, <span style="COLOR: blue">string</span> name, <span style="COLOR: blue">string</span> key);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">static</span><span style="COLOR: blue">void</span> SetProperty(<span style="COLOR: blue">object</span> instance, <span style="COLOR: blue">string</span> name, <span style="COLOR: blue">object</span> value, <span style="COLOR: blue">string</span> key);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">static</span><span style="COLOR: blue">void</span> Unload();
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
A class implementing ITypeDescriptorProvider returns a new instance of the TypeDescriptor
class where all the attributes, properties, methods are events supported by the class
have been added using the AddXXX instance methods. The CreateParameter method is used
with the AddMethod method to specify the parameters for the method. 
</p>
        <p>
The information about a particular instance is stored in four dictionaries (_attributes,
_events, _methods and _properties). The static methods AddType and GetType are used
to register types and to get information about the registered types in the system.
The TypeDescriptor class has a static field called _registeredTags (of type hashtable),
where it stores a hashtable of typeNames and its associated type, using the tagPrefix
as key. This is mainly used by the xml-script infrastructure as we’ll see in a future
post. The Unload method erases the information stored in the _registeredTags hashtable.
</p>
        <p>
The other methods are self explanatory.
</p>
        <p>
          <strong>Events</strong>
        </p>
        <p>
The event mechanism implemented by the library is very reminiscent of the .NET one,
although it has some differences.
</p>
        <p>
An event is an instance of the Type.Event class:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">public</span>
            <span style="COLOR: blue">sealed</span>
            <span style="COLOR: blue">class</span>
            <span style="COLOR: teal">Event</span> : <span style="COLOR: teal">IDisposable</span></p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">bool</span> AutoInvoke
{ <span style="COLOR: blue">get</span>; }
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">bool</span> IsInvoked
{ <span style="COLOR: blue">get</span>; }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span> Event(<span style="COLOR: teal">Component</span> owner, <span style="COLOR: blue">bool</span> autoInvoke);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">void</span> Add(<span style="COLOR: teal">JavascriptFunction</span> handler);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">void</span> AddAction(<span style="COLOR: teal">IAction</span> action);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">void</span> Remove(<span style="COLOR: teal">JavascriptFunction</span> handler);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">void</span> RemoveAction(<span style="COLOR: teal">IAction</span> action);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">bool</span> IsActive();
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">void</span> Invoke(<span style="COLOR: blue">object</span> sender, <span style="COLOR: teal">EventArgs</span> eventArgs);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">void</span> SetInvoked(<span style="COLOR: blue">bool</span> invoked);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">void</span> Dispose();
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
An event is declared like this:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">this</span>.propertyChanged = <span style="COLOR: blue">new</span> Type.Event(<span style="COLOR: blue">null</span>, <span style="COLOR: blue">false</span>);
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
And to subscribe to the event we have to write the following code:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">var</span> propertyChangedHandler = Function.createDelegate(<span style="COLOR: blue">this</span>,
onPropertyChanged);
</p>
          <p style="MARGIN: 0px">
myInstance.propertyChanged.add(propertyChangedHandler);
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
the onPropertyChange method will be called when the event is fired. The method should
have a signature like this:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">function</span> onPropertyChanged(sender, args) {
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
And the first parameter will be the object that fired the event, and the second parameter
will be the arguments specific for the event.
</p>
        <p>
The arguments are an instance of the class EventArgs or any of its subclasses:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">public</span>
            <span style="COLOR: blue">class</span>
            <span style="COLOR: teal">EventArgs</span> : <span style="COLOR: teal">ITypeDescriptorProvider</span></p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">static</span><span style="COLOR: teal">EventArgs</span> Empty
= <span style="COLOR: blue">new</span><span style="COLOR: teal">EventArgs</span>();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span> EventArgs();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">virtual</span><span style="COLOR: teal">TypeDescriptor</span> GetDescriptor();
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
Note that the EventArgs class implements the ITypeDescriptorProvider interface explained
before.
</p>
        <p>
The Event class implements the IDisposable interface that is like this:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">public</span>
            <span style="COLOR: blue">interface</span>
            <span style="COLOR: teal">IDisposable</span>
          </p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">void</span> Dispose();
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
yes, the same as .NET.
</p>
        <p>
The Event class has methods to add and remove event handlers and also to add and remove
actions. What is an action? Actions will be covered in more detail in a future post
but for now think of them as tasks that can be executed before the event handler is
called or after the event handler is called. 
</p>
        <p>
The Event constructor takes a Component as the first parameter, because actions operate
on components. The autoInvoke parameter is used to call to a handler when adding it
to the event if the event has already been fired. This is useful because some critical
methods should be called in response to events that may happen before the full Microsoft
AJAX Library has been initialized.
</p>
        <p>
          <strong>Additions to the default JavaScript objects</strong>
        </p>
        <p>
The library adds some methods to the default JavaScript objects to make them more
.NET alike:
</p>
        <p>
Boolean -&gt; parse<br />
Number -&gt; parse<br />
String -&gt; startsWith, endsWith, lTrim, rTrim, format, localeFormat<br />
Array -&gt; add, addRange, cloar, clone, contains, dequeue, indexOf, foreach, insert,
remove, removeAt, parse, get_length, get_Item. Also, Array implements the IArray interface
(get_length, get_Item).
</p>
        <p>
RegExp -&gt; parse
</p>
        <p>
Error -&gt; createError (that is the replacement for: throw new Exception(…) in the
.net framework.
</p>
        <p>
Date -&gt; toFormattedString, serialize
</p>
        <p>
In the next post I’ll talk about the Component class and related classes. There is
a lot of theory behind it to fully understand all the details involved…<br /></p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=e440e756-b3fa-4ec2-aea7-f2f28dee1a38" />
      </body>
      <title>Microsoft AJAX Library (Atlas) – Javascript OOP enhancements (Part 2)</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,e440e756-b3fa-4ec2-aea7-f2f28dee1a38.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,e440e756-b3fa-4ec2-aea7-f2f28dee1a38.aspx</link>
      <pubDate>Wed, 11 Oct 2006 08:22:24 GMT</pubDate>
      <description>&lt;p&gt;
Note: Bertrand Le Roy has confirmed that the next Microsoft AJAX Library release will
use the prototype based approach instead of the closure approach (really great news!),
and clearly explains the differences:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://weblogs.asp.net/bleroy/archive/2006/10/11/From-closures-to-prototypes_2C00_-part-1.aspx"&gt;http://weblogs.asp.net/bleroy/archive/2006/10/11/From-closures-to-prototypes_2C00_-part-1.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
In &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,c59facc0-301e-4e30-898d-428038828dcd.aspx"&gt;part
1&lt;/a&gt; we saw how the inheritance infrastructure worked, how to create namespaces,
and how to create classes. Now it is time to continue with the other stuff.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Interfaces&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
To create an interface is similar to create a class, but we use the registerInterface
method instead and we define the methods to be abstract. For example:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.MyInterface = &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;this&lt;/span&gt;.method1 = Function.abstractMethod;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.MyInterface.registerInterface(&lt;span style="COLOR: maroon"&gt;'Manu.Atlas.Tests.MyInterface'&lt;/span&gt;);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
We can define the interface using the prototype method instead of the closure method:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.MyInterface = &lt;span style="COLOR: blue"&gt;function&lt;/span&gt;() {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.MyInterface.prototype.method1 = Function.abstractMethod;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.MyInterface.registerInterface(&lt;span style="COLOR: maroon"&gt;'Manu.Atlas.Tests.MyInterface'&lt;/span&gt;);
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The registerInterface method (defined in the Function type) just set the _typeName
of the type where the method is invoked, and sets the boolean properties _interface,
_abstract and _sealed to true.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Enumerations&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
There are two kinds of enumerations that we can create. One where the enumeration
items act as flags so we may want to combine them and the other type is where we can’t
combine the enumeration items.
&lt;/p&gt;
&lt;p&gt;
The first type is created using the createFlags method and the second one is created
using the createEnum method (of the Type class). The parameters for those methods
are:
&lt;/p&gt;
&lt;p&gt;
Type.createFlags(enumerationName, enumerationItems)&lt;br&gt;
Type.createEnum(enumerationName, enumerationItems)
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
Where enumerationName is the name of the enumeration, and enumerationItems are a variable
number of parameters that specify the different enumeration items. Each item in the
enumeration is specified as two parameters, the first is the string with the item
name, and the second the associated value.
&lt;/p&gt;
&lt;p&gt;
The common methods are:&lt;br&gt;
•&amp;nbsp;toString: converts the value passed to the method to a string.&lt;br&gt;
•&amp;nbsp;parse: converts the string passed to a value.&lt;br&gt;
•&amp;nbsp;getName: returns the name of the enumeration
&lt;/p&gt;
&lt;p&gt;
The enumeration where you can use the items as flags has a method called isFlags that
return true. The other enumeration type has a method called isEnum that returns true,
and a method called getValues that returns a hashtable with the items of the enumeration.
&lt;/p&gt;
&lt;p&gt;
An example follows:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
Type.createEnum(&lt;span style="COLOR: maroon"&gt;'Manu.Atlas.Tests.MyEnum'&lt;/span&gt;, &lt;span style="COLOR: maroon"&gt;'enum_item1'&lt;/span&gt;,
1, &lt;span style="COLOR: maroon"&gt;'enum_item2'&lt;/span&gt;, 2);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; val = Manu.Atlas.Tests.MyEnum.enum_item1;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; str = Manu.Atlas.Tests.MyEnum.toString(val);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; valaux = Manu.Atlas.Tests.MyEnum.parse(&lt;span style="COLOR: maroon"&gt;'enum_item2'&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Type.createFlags(&lt;span style="COLOR: maroon"&gt;'Manu.Atlas.Tests.MyEnum2'&lt;/span&gt;, &lt;span style="COLOR: maroon"&gt;'enum_item1'&lt;/span&gt;,
1, &lt;span style="COLOR: maroon"&gt;'enum_item2'&lt;/span&gt;, 2, &lt;span style="COLOR: maroon"&gt;'enum_item3'&lt;/span&gt;,
4);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; val2 = Manu.Atlas.Tests.MyEnum2.enum_item1 |
Manu.Atlas.Tests.MyEnum2.enum_item3;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; str2 = Manu.Atlas.Tests.MyEnum2.toString(val2);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; val2aux = Manu.Atlas.Tests.MyEnum2.parse(&lt;span style="COLOR: maroon"&gt;'enum_item2
| enum_item3'&lt;/span&gt;);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
The values of the variables after execution are:
&lt;/p&gt;
&lt;p&gt;
val = 1&lt;br&gt;
str = “enum_item1”&lt;br&gt;
valaux = 2&lt;br&gt;
val2 = 5&lt;br&gt;
str2 = “enum_item1 | enum_item3”&lt;br&gt;
val2aux = 6
&lt;/p&gt;
&lt;p&gt;
Both kinds of enumerations are implemented the same way. A hashtable with the same
name as the enumeration is created, and each enumeration item name is stored as a
key of the hashtable and the enumeration item value is stored as the associated value
for the key.
&lt;/p&gt;
&lt;p&gt;
From now on, when showing a class or an interface, I’ll be using C# syntax to show
it instead of the JavaScript version of the class for clarity. The naming convention
for the JavaScript classes is distinct from the C# naming convention so if a property
is called Text in C#, the equivalent getter and setter will be get_text and set_text
instead of get_Text and set_Text, so don’t get confused.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Attributes&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
In .NET is very common to decorate classes, properties and methods with attributes
that provide useful information about them. The Microsoft AJAX library adds this extension
to JavaScript.
&lt;/p&gt;
&lt;p&gt;
The attributes are very important to generate reusable code. The xml-script parsing
process and the validation controls use it.
&lt;/p&gt;
&lt;p&gt;
An attribute is a static property of the class Sys.Attributes. The class has a method
called defineAttribute that creates a new attribute:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
Sys.Attributes.defineAttribute(&lt;span style="COLOR: maroon"&gt;'MyCustomAttribute'&lt;/span&gt;);
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
After having created the attribute we can reference it using Sys.Attributes. 'MyCustomAttribute.
The attributes can be associated to a class or to a property as we will see in the
next section. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Reflection&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Even if JavaScript has some flexibility that can be used to perform some tasks similar
to what reflection does (retrieve all fields from an object, retrieve a field from
an instance using a string with the property name, invoke a method from an object
based on the method name, etc), as the Microsoft AJAX library added OO features to
it, it has to provide a way to interact with all the new OO infrastructure generically
and more .NET friendly.
&lt;/p&gt;
&lt;p&gt;
These features are provided by the Sys.TypeDescriptor class. Most of the classes in
the library implement the interface ITypeDescriptorProvider:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;interface&lt;/span&gt; &lt;span style="COLOR: teal"&gt;ITypeDescriptorProvider&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;TypeDescriptor&lt;/span&gt; GetDescriptor();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
The only method present in the interface returns the TypeDescriptor for the class
implementing the interface.
&lt;/p&gt;
&lt;p&gt;
The TypeDescriptor class is like this:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;sealed&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: teal"&gt;TypeDescriptor&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; AddAttribute(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; name, &lt;span style="COLOR: blue"&gt;object&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;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; AddEvent(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; name, &lt;span style="COLOR: blue"&gt;object&lt;/span&gt; supportActions);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; AddMethod(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; name, &lt;span style="COLOR: blue"&gt;object&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;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; AddProperty(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; name, &lt;span style="COLOR: teal"&gt;Type&lt;/span&gt; type, &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; readOnly, &lt;span style="COLOR: blue"&gt;params&lt;/span&gt; &lt;span style="COLOR: blue"&gt;object&lt;/span&gt;[]
attributes);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; TypeDescriptor();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; AddType(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; tagPrefix, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; tagName, &lt;span style="COLOR: teal"&gt;Type&lt;/span&gt; type);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: teal"&gt;Type&lt;/span&gt; GetPropertyType(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; instance, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; name, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; key);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: teal"&gt;Type&lt;/span&gt; GetType(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; tagPrefix, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; tagName);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: teal"&gt;TypeDescriptor&lt;/span&gt; GetTypeDescriptor(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; instance);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;object&lt;/span&gt; InvokeMethod(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; instance, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; name, &lt;span style="COLOR: blue"&gt;object&lt;/span&gt;[]
parameters);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: teal"&gt;ParameterInfo&lt;/span&gt; CreateParameter(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; name, &lt;span style="COLOR: teal"&gt;Type&lt;/span&gt; type);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; GetAttribute(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; instance, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; name);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;object&lt;/span&gt; GetProperty(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; instance, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; name, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; key);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; SetProperty(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; instance, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; name, &lt;span style="COLOR: blue"&gt;object&lt;/span&gt; value, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; key);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Unload();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
A class implementing ITypeDescriptorProvider returns a new instance of the TypeDescriptor
class where all the attributes, properties, methods are events supported by the class
have been added using the AddXXX instance methods. The CreateParameter method is used
with the AddMethod method to specify the parameters for the method. 
&lt;/p&gt;
&lt;p&gt;
The information about a particular instance is stored in four dictionaries (_attributes,
_events, _methods and _properties). The static methods AddType and GetType are used
to register types and to get information about the registered types in the system.
The TypeDescriptor class has a static field called _registeredTags (of type hashtable),
where it stores a hashtable of typeNames and its associated type, using the tagPrefix
as key. This is mainly used by the xml-script infrastructure as we’ll see in a future
post. The Unload method erases the information stored in the _registeredTags hashtable.
&lt;/p&gt;
&lt;p&gt;
The other methods are self explanatory.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Events&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The event mechanism implemented by the library is very reminiscent of the .NET one,
although it has some differences.
&lt;/p&gt;
&lt;p&gt;
An event is an instance of the Type.Event class:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;sealed&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: teal"&gt;Event&lt;/span&gt; : &lt;span style="COLOR: teal"&gt;IDisposable&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; AutoInvoke
{ &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;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; IsInvoked
{ &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;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; Event(&lt;span style="COLOR: teal"&gt;Component&lt;/span&gt; owner, &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; autoInvoke);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Add(&lt;span style="COLOR: teal"&gt;JavascriptFunction&lt;/span&gt; handler);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; AddAction(&lt;span style="COLOR: teal"&gt;IAction&lt;/span&gt; action);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Remove(&lt;span style="COLOR: teal"&gt;JavascriptFunction&lt;/span&gt; handler);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; RemoveAction(&lt;span style="COLOR: teal"&gt;IAction&lt;/span&gt; action);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; IsActive();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Invoke(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; sender, &lt;span style="COLOR: teal"&gt;EventArgs&lt;/span&gt; eventArgs);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; SetInvoked(&lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; invoked);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Dispose();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
An event is declared like this:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;.propertyChanged = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; Type.Event(&lt;span style="COLOR: blue"&gt;null&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;false&lt;/span&gt;);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
And to subscribe to the event we have to write the following code:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; propertyChangedHandler = Function.createDelegate(&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;,
onPropertyChanged);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
myInstance.propertyChanged.add(propertyChangedHandler);
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
the onPropertyChange method will be called when the event is fired. The method should
have a signature like this:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;function&lt;/span&gt; onPropertyChanged(sender, args) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
And the first parameter will be the object that fired the event, and the second parameter
will be the arguments specific for the event.
&lt;/p&gt;
&lt;p&gt;
The arguments are an instance of the class EventArgs or any of its subclasses:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&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;EventArgs&lt;/span&gt; : &lt;span style="COLOR: teal"&gt;ITypeDescriptorProvider&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: teal"&gt;EventArgs&lt;/span&gt; Empty
= &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;EventArgs&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;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; EventArgs();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;virtual&lt;/span&gt; &lt;span style="COLOR: teal"&gt;TypeDescriptor&lt;/span&gt; GetDescriptor();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
Note that the EventArgs class implements the ITypeDescriptorProvider interface explained
before.
&lt;/p&gt;
&lt;p&gt;
The Event class implements the IDisposable interface that is like this:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;interface&lt;/span&gt; &lt;span style="COLOR: teal"&gt;IDisposable&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Dispose();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
yes, the same as .NET.
&lt;/p&gt;
&lt;p&gt;
The Event class has methods to add and remove event handlers and also to add and remove
actions. What is an action? Actions will be covered in more detail in a future post
but for now think of them as tasks that can be executed before the event handler is
called or after the event handler is called. 
&lt;/p&gt;
&lt;p&gt;
The Event constructor takes a Component as the first parameter, because actions operate
on components. The autoInvoke parameter is used to call to a handler when adding it
to the event if the event has already been fired. This is useful because some critical
methods should be called in response to events that may happen before the full Microsoft
AJAX Library has been initialized.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Additions to the default JavaScript objects&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The library adds some methods to the default JavaScript objects to make them more
.NET alike:
&lt;/p&gt;
&lt;p&gt;
Boolean -&amp;gt; parse&lt;br&gt;
Number -&amp;gt; parse&lt;br&gt;
String -&amp;gt; startsWith, endsWith, lTrim, rTrim, format, localeFormat&lt;br&gt;
Array -&amp;gt; add, addRange, cloar, clone, contains, dequeue, indexOf, foreach, insert,
remove, removeAt, parse, get_length, get_Item. Also, Array implements the IArray interface
(get_length, get_Item).
&lt;/p&gt;
&lt;p&gt;
RegExp -&amp;gt; parse
&lt;/p&gt;
&lt;p&gt;
Error -&amp;gt; createError (that is the replacement for: throw new Exception(…) in the
.net framework.
&lt;/p&gt;
&lt;p&gt;
Date -&amp;gt; toFormattedString, serialize
&lt;/p&gt;
&lt;p&gt;
In the next post I’ll talk about the Component class and related classes. There is
a lot of theory behind it to fully understand all the details involved…&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=e440e756-b3fa-4ec2-aea7-f2f28dee1a38" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,e440e756-b3fa-4ec2-aea7-f2f28dee1a38.aspx</comments>
      <category>Ajax;ASP.NET;JavaScript</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=77dd4e93-e052-4b65-9b9d-81a17f0e2b6e</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,77dd4e93-e052-4b65-9b9d-81a17f0e2b6e.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,77dd4e93-e052-4b65-9b9d-81a17f0e2b6e.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=77dd4e93-e052-4b65-9b9d-81a17f0e2b6e</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The health monitoring in ASP.NET 2.0 is a framework to generate and capture events
during the life of the application. The health monitoring uses the provider model.
A health monitoring provider can capture events and do any processing with them (log
them, send them by email, etc). There are a lot of predefined events and we can create
our custom events. As we will see, it is very easy to use the health monitoring system,
but we need a solid understanding of the different elements involved. 
</p>
        <p>
To configure the health monitoring system we have to use the web.config. The health
monitoring section has to be placed inside the &lt;system.web&gt; section and has
the following structure:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span>
            <span style="COLOR: maroon">healthMonitoring</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">bufferModes</span>
            <span style="COLOR: blue">/&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">providers</span>
            <span style="COLOR: blue">/&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">profiles</span>
            <span style="COLOR: blue">/&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">rules</span>
            <span style="COLOR: blue">/&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">eventMappings</span>
            <span style="COLOR: blue">/&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;/</span>
            <span style="COLOR: maroon">healthMonitoring</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
The healthMonitoring element has two attributes:<br />
• enabled: specifies if the health monitoring system is enabled or not.<br />
• heartbeatInterval: the system will raise WebHeartbeatEvent with the frequency
specified here (more on this later).
</p>
        <p>
          <br />
          <strong>Buffer modes:</strong>
        </p>
        <p>
There are some events that can be buffered so the provider saves some events in memory
before doing some work with them. The buffering options are specified in the providers
in the bufferModes subsection, and then a buffered provider points to a buffer mode
in order to use buffering. The buffer mode specifies the number of events of the buffer
and the flushing frequency and intervals.
</p>
        <p>
The default buffer modes are (extracted from the global web.config):
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span>
            <span style="COLOR: maroon">bufferModes</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">clear</span>
            <span style="COLOR: blue"> /&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">Critical
Notification</span>"<span style="COLOR: blue"></span><span style="COLOR: red">maxBufferSize</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">100</span>"<span style="COLOR: blue"></span><span style="COLOR: red">maxFlushSize</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">20</span>"<span style="COLOR: blue"></span><span style="COLOR: red">urgentFlushThreshold</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">1</span>"<span style="COLOR: blue"></span><span style="COLOR: red">regularFlushInterval</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">Infinite</span>"<span style="COLOR: blue"></span><span style="COLOR: red">urgentFlushInterval</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">00:01:00</span>"<span style="COLOR: blue"></span><span style="COLOR: red">maxBufferThreads</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">1</span>"<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">Notification</span>"<span style="COLOR: blue"></span><span style="COLOR: red">maxBufferSize</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">300</span>"<span style="COLOR: blue"></span><span style="COLOR: red">maxFlushSize</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">20</span>"<span style="COLOR: blue"></span><span style="COLOR: red">urgentFlushThreshold</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">1</span>"<span style="COLOR: blue"></span><span style="COLOR: red">regularFlushInterval</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">Infinite</span>"<span style="COLOR: blue"></span><span style="COLOR: red">urgentFlushInterval</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">00:01:00</span>"<span style="COLOR: blue"></span><span style="COLOR: red">maxBufferThreads</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">1</span>"<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">Analysis</span>"<span style="COLOR: blue"></span><span style="COLOR: red">maxBufferSize</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">1000</span>"<span style="COLOR: blue"></span><span style="COLOR: red">maxFlushSize</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">100</span>"<span style="COLOR: blue"></span><span style="COLOR: red">urgentFlushThreshold</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">100</span>"<span style="COLOR: blue"></span><span style="COLOR: red">regularFlushInterval</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">00:05:00</span>"<span style="COLOR: blue"></span><span style="COLOR: red">urgentFlushInterval</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">00:01:00</span>"<span style="COLOR: blue"></span><span style="COLOR: red">maxBufferThreads</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">1</span>"<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">Logging</span>"<span style="COLOR: blue"></span><span style="COLOR: red">maxBufferSize</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">1000</span>"<span style="COLOR: blue"></span><span style="COLOR: red">maxFlushSize</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">200</span>"<span style="COLOR: blue"></span><span style="COLOR: red">urgentFlushThreshold</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">800</span>"<span style="COLOR: blue"></span><span style="COLOR: red">regularFlushInterval</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">00:30:00</span>"<span style="COLOR: blue"></span><span style="COLOR: red">urgentFlushInterval</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">00:05:00</span>"<span style="COLOR: blue"></span><span style="COLOR: red">maxBufferThreads</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">1</span>"<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;/</span>
            <span style="COLOR: maroon">bufferModes</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
The name attribute is used to associate a buffer mode with a provider. The maxBufferSize
attributes specifies the maximum number of events that can be buffered before flushing
them. 
</p>
        <p>
Usually, events are flushed at constant intervals specified by the regularFlushInterval.
However, some times is better to flush events more quickly than the regularFlushInterval.
When the number of buffered events is greater or equal than the urgentFlushThreshold,
the events will be flushed at an interval specified by the urgentFlushInterval. 
</p>
        <p>
The maxFlushSize specifies the maximum number of events to process when flushing.
</p>
        <p>
The maxBufferThreads attribute specifies the maximum number of threads used for flushing.
</p>
        <p>
For example, suppose we are using a provider that saves the events to a DB using the
“Logging” buffer mode. The buffer can hold up to 1000 events. Usually, the events
will be saved every 30 minutes, but if there are 800 or more events waiting to be
logged, they don’t have to wait 30 minutes to be saved, they will be saved at 5 minutes
intervals, until there are less than 800 in the buffer, as the provider will save
only 200 events at a time.
</p>
        <p>
          <strong>Providers:</strong>
        </p>
        <p>
A provider is a class that inherits from System.Web.Management.WebEventProvider. In
the providers configuration subsection we can add the providers that we want in order
to process the captured events. However, the association of providers and events to
capture is made in the rules section that will be explained later. The provider has
2 common attributes, name and type. Each specific provider can have more attributes
needed for its respective tasks. The name type is used for referencing the provider
in different sections and the type specifies the class and assembly where the provider
is located.
</p>
        <p>
This class diagram shows the available providers:
</p>
        <p>
          <img src="http://www.manuelabadia.com/blog/content/binary/healthmon_providers.png" border="0" />
        </p>
        <p>
The available providers are:
</p>
        <p>
• SqlWebEventProvider stores events in a Sql Server database. 
<br />
• EventLogWebEventProvider stores events in the windows event log.<br />
• TraceWebEventProvider passes events to the Trace object.<br />
• WmiWebEventProvider maps events to WMI events.<br />
• SimpleMailWebEventProvider sends emails with event notifications.<br />
• TemplateMailWebEventProvider uses a template to format the emails that sends
with event notifications.
</p>
        <p>
To configurate the Sql Server database for the SqlWebEventProvider take a look <a href="http://weblogs.asp.net/scottgu/archive/2005/08/25/423703.aspx">here</a>.
</p>
        <p>
The WebEventProvider class has 3 abstract methods:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">public</span>
            <span style="COLOR: blue">abstract</span>
            <span style="COLOR: blue">class</span>
            <span style="COLOR: teal">WebEventProvider</span> :
ProviderBase
</p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">protected</span> WebEventProvider();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">abstract</span><span style="COLOR: blue">void</span> Flush();
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">abstract</span><span style="COLOR: blue">void</span> ProcessEvent(<span style="COLOR: teal">WebBaseEvent</span> raisedEvent);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">abstract</span><span style="COLOR: blue">void</span> Shutdown();
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
The buffered event providers (Sql server provider and the mail providers) inherit
from the BufferedWebEventProvider class that provides the basic infrastructure for
a buffered provider:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">public</span>
            <span style="COLOR: blue">abstract</span>
            <span style="COLOR: blue">class</span>
            <span style="COLOR: teal">BufferedWebEventProvider</span> : <span style="COLOR: teal">WebEventProvider</span></p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">protected</span> BufferedWebEventProvider();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">string</span> BufferMode
{ <span style="COLOR: blue">get</span>; }
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">bool</span> UseBuffering
{ <span style="COLOR: blue">get</span>; }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">override</span><span style="COLOR: blue">void</span> Flush();
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">override</span><span style="COLOR: blue">void</span> Initialize(<span style="COLOR: blue">string</span> name,
NameValueCollection config);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">override</span><span style="COLOR: blue">void</span> ProcessEvent(<span style="COLOR: teal">WebBaseEvent</span> eventRaised);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">abstract</span><span style="COLOR: blue">void</span> ProcessEventFlush(<span style="COLOR: teal">WebEventBufferFlushInfo</span> flushInfo);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">override</span><span style="COLOR: blue">void</span> Shutdown();
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
A buffered provider has two extra parameters, buffer and bufferMode. Buffering is
only used if buffer=”true”. If buffering is used, bufferMode links the provider with
a buffer mode that was explained in the previous section.
</p>
        <p>
The default configuration for the providers is (extracted from the global web.config):
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span>
            <span style="COLOR: maroon">providers</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">clear</span>
            <span style="COLOR: blue"> /&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">EventLogProvider</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Management.EventLogWebEventProvider,System.Web”
/&gt;</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">SqlWebEventProvider</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Management.SqlWebEventProvider,System.Web”</span>"<span style="COLOR: blue"></span><span style="COLOR: red">connectionStringName</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">LocalSqlServer</span>"<span style="COLOR: blue"></span><span style="COLOR: red">maxEventDetailsLength</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">1073741823</span>"<span style="COLOR: blue"></span><span style="COLOR: red">buffer</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">false</span>"<span style="COLOR: blue"></span><span style="COLOR: red">bufferMode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">Notification</span>"<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">WmiWebEventProvider</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Management.WmiWebEventProvider”
/&gt;</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;/</span>
            <span style="COLOR: maroon">providers</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
          <strong>Profiles:</strong>
        </p>
        <p>
Some events should be always logged using a provider, but sometimes, an event can
happen a lot of times per second if an important error surfaces, so the profile subsection
can help to configure if we have to log all events received or if we can ignore the
same event for a short period of time.
</p>
        <p>
A group of events can be assigned a concrete profile in the rules section as we’ll
see soon.
</p>
        <p>
The default configuration for the profiles is (extracted from the global web.config):
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span>
            <span style="COLOR: maroon">profiles</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">clear</span>
            <span style="COLOR: blue"> /&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">Default</span>"<span style="COLOR: blue"></span><span style="COLOR: red">minInstances</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">1</span>"<span style="COLOR: blue"></span><span style="COLOR: red">maxLimit</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">Infinite</span>"<span style="COLOR: blue"></span><span style="COLOR: red">minInterval</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">00:01:00</span>"<span style="COLOR: blue"></span><span style="COLOR: red">custom</span><span style="COLOR: blue">=</span>""<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">Critical</span>"<span style="COLOR: blue"></span><span style="COLOR: red">minInstances</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">1</span>"<span style="COLOR: blue"></span><span style="COLOR: red">maxLimit</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">Infinite</span>"<span style="COLOR: blue"></span><span style="COLOR: red">minInterval</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">00:00:00</span>"<span style="COLOR: blue"></span><span style="COLOR: red">custom</span><span style="COLOR: blue">=</span>""<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;/</span>
            <span style="COLOR: maroon">profiles</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
The name attribute is used to associate an event with the profile. The minInstances
indicates the minimum number of occurrences of an event before the event is logged.
The maxLimit is used to stop logging an event after the number of occurrences of the
event is greater or equal to this value. The minInterval can be used to avoid logging
events if the interval between events is less than the minInterval. 
</p>
        <p>
The custom attribute can be used to do more complex evaluations to check if the event
should be sent to the providers. See the IWebEventCustomEvaluator interface for more
information.
</p>
        <p>
As you can see, there are two predefined profile modes: the Critical, that logs every
event without exception; and the Default, that avoids logging the same event twice
in a minute.
</p>
        <p>
          <strong>Event Mappings:</strong>
        </p>
        <p>
In this configuration subsection, we associate a name with an event or group of events. 
</p>
        <p>
Without knowing a bit of the event types we can’t understand the health monitoring
system, so here it is an introduction to the different event classes:
</p>
        <p>
          <img src="http://www.manuelabadia.com/blog/content/binary/healthmon_events.png" border="0" />
        </p>
        <p>
The WebHeartbeatEvent event can be raised periodically to give information about the
status of the application (thread count, managed heap size, number of app domains,
requests queued, requests executing, request rejected, information about the working
set, etc).
</p>
        <p>
The WebApplicationLifetimeEvent represents an important event in the application life
cycle (application start, application shutdown, etc) and the information that can
give you is very important, as you can analyze why your site is shutting down. For
example, these are some constants that specify the shutdown reason:
</p>
        <p>
ApplicationShutdownUnknown 
<br />
ApplicationShutdownHostingEnvironment<br />
ApplicationShutdownChangeInGlobalAsax<br />
ApplicationShutdownConfigurationChange<br />
ApplicationShutdownUnloadAppDomainCalled<br />
ApplicationShutdownChangeInSecurityPolicyFile<br />
ApplicationShutdownBinDirChangeOrDirectoryRename<br />
ApplicationShutdownBrowsersDirChangeOrDirectoryRename<br />
ApplicationShutdownCodeDirChangeOrDirectoryRename<br />
ApplicationShutdownResourcesDirChangeOrDirectoryRename<br />
ApplicationShutdownIdleTimeout<br />
ApplicationShutdownPhysicalApplicationPathChanged<br />
ApplicationShutdownHttpRuntimeClose<br />
ApplicationShutdownInitializationError<br />
ApplicationShutdownMaxRecompilationsReached
</p>
        <p>
The WebRequestEvent event is raised at every request and contains information about
the IP of the user that makes the request, URL of the request, etc.
</p>
        <p>
The WebBaseErrorEvent class is the base class for all events that report error conditions.
The WebErrorEvent event is raise when configuration or code problems arise (for example,
when the code throws an unhandled exception). The WebRequestErrorEvent event is raised
when there is an error with a request (for example, a deserialization error in the
ObjectStateFormatter).
</p>
        <p>
The WebAuditEvent class is the base class for success (WebSuccessAuditEvent) or failure
(WebFailureAuditEvent) of security related operations. When an user try to log in
the web application, a WebAuthenticationSuccessAuditEvent WebAuthenticationFailureAuditEvent
if the login process completed successfully or not. If the view state has been altered,
the WebViewStateFailureAuditEvent will be raised.
</p>
        <p>
The default event mappings are (extracted from the global web.config):
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span>
            <span style="COLOR: maroon">eventMappings</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">clear</span>
            <span style="COLOR: blue"> /&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">All
Events</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Management.WebBaseEvent,System.Web</span>"<span style="COLOR: blue"></span><span style="COLOR: red">startEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">0</span>"<span style="COLOR: blue"></span><span style="COLOR: red">endEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">2147483647</span>"<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">Heartbeats</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Management.WebHeartbeatEvent,System.Web </span>"<span style="COLOR: blue"></span><span style="COLOR: red">startEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">0</span>"<span style="COLOR: blue"></span><span style="COLOR: red">endEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">2147483647</span>"<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">Application
Lifetime Events</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Management.WebApplicationLifetimeEvent,System.Web </span>"<span style="COLOR: blue"></span><span style="COLOR: red">startEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">0</span>"<span style="COLOR: blue"></span><span style="COLOR: red">endEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">2147483647</span>"<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">Request
Processing Events</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Management.WebRequestEvent,System.Web </span>"<span style="COLOR: blue"></span><span style="COLOR: red">startEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">0</span>"<span style="COLOR: blue"></span><span style="COLOR: red">endEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">2147483647</span>"<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">All
Errors</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Management.WebBaseErrorEvent,System.Web </span>"<span style="COLOR: blue"></span><span style="COLOR: red">startEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">0</span>"<span style="COLOR: blue"></span><span style="COLOR: red">endEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">2147483647</span>"<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">Infrastructure
Errors</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Management.WebErrorEvent,System.Web </span>"<span style="COLOR: blue"></span><span style="COLOR: red">startEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">0</span>"<span style="COLOR: blue"></span><span style="COLOR: red">endEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">2147483647</span>"<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">Request
Processing Errors</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Management.WebRequestErrorEvent,System.Web </span>"<span style="COLOR: blue"></span><span style="COLOR: red">startEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">0</span>"<span style="COLOR: blue"></span><span style="COLOR: red">endEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">2147483647</span>"<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">All
Audits</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Management.WebAuditEvent,System.Web </span>"<span style="COLOR: blue"></span><span style="COLOR: red">startEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">0</span>"<span style="COLOR: blue"></span><span style="COLOR: red">endEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">2147483647</span>"<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">Failure
Audits</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Management.WebFailureAuditEvent,System.Web </span>"<span style="COLOR: blue"></span><span style="COLOR: red">startEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">0</span>"<span style="COLOR: blue"></span><span style="COLOR: red">endEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">2147483647</span>"<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">Success
Audits</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Management.WebSuccessAuditEvent,System.Web </span>"<span style="COLOR: blue"></span><span style="COLOR: red">startEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">0</span>"<span style="COLOR: blue"></span><span style="COLOR: red">endEventCode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">2147483647</span>"<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;/</span>
            <span style="COLOR: maroon">eventMappings</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
The name attribute is used to associate a rule with a provider and a group of events
as we’ll see in the rules section. The type specifies a class of event that is mapped
to the event group. Note that all derived classes are also mapped by the same event
group.
</p>
        <p>
The startEventCode and the endEventCode attributes are used to specify a range of
event codes. The event code is also saved with the event and helps in the identification
of the event.
</p>
        <p>
As a summary, the default web.config has this mapping:
</p>
        <p>
All Events -&gt; WebBaseEvent<br />
Heartbeats -&gt; WebHeartbeatEvent<br />
Application Lifetime Events -&gt; WebApplicationLifetimeEvent<br />
Request Processing Events -&gt; WebRequestEvent<br />
All Errors -&gt; WebBaseErrorEvent<br />
Request Processing Errors -&gt; WebRequestErrorEvent<br />
All Audits -&gt; WebAuditEvent<br />
Failure Audits -&gt; WebFailureAuditEvent<br />
Success Audits -&gt; WebSuccessAuditEvent
</p>
        <p>
Note that the constructor for these events is protected so you can’t create instances
of the predefined events. Instead you should create your custom event inheriting from
the appropriate event class.
</p>
        <p>
          <strong>Rules:</strong>
        </p>
        <p>
This configuration subsection is where all the associations and entities seen earlier
take place.
</p>
        <p>
The default configuration for the rules is (extracted from the global web.config):
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span>
            <span style="COLOR: maroon">rules</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">clear</span>
            <span style="COLOR: blue"> /&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">All
Errors Default</span>"<span style="COLOR: blue"></span><span style="COLOR: red">eventName</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">All
Errors</span>"<span style="COLOR: blue"></span><span style="COLOR: red">provider</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">EventLogProvider</span>"<span style="COLOR: blue"></span><span style="COLOR: red">profile</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">Default</span>"<span style="COLOR: blue"></span><span style="COLOR: red">minInstances</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">1</span>"<span style="COLOR: blue"></span><span style="COLOR: red">maxLimit</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">Infinite</span>"<span style="COLOR: blue"></span><span style="COLOR: red">minInterval</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">00:01:00</span>"<span style="COLOR: blue"></span><span style="COLOR: red">custom</span><span style="COLOR: blue">=</span>""<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">  &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">Failure
Audits Default</span>"<span style="COLOR: blue"></span><span style="COLOR: red">eventName</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">Failure
Audits</span>"<span style="COLOR: blue"></span><span style="COLOR: red">provider</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">EventLogProvider</span>"<span style="COLOR: blue"></span><span style="COLOR: red">profile</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">Default</span>"<span style="COLOR: blue"></span><span style="COLOR: red">minInstances</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">1</span>"<span style="COLOR: blue"></span><span style="COLOR: red">maxLimit</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">Infinite</span>"<span style="COLOR: blue"></span><span style="COLOR: red">minInterval</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">00:01:00</span>"<span style="COLOR: blue"></span><span style="COLOR: red">custom</span><span style="COLOR: blue">=</span>""<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;/</span>
            <span style="COLOR: maroon">rules</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
The attributes for each rule are:<br />
 * name: a string representing the name of the rule.<br />
 * eventName: associates an event group with this rule.<br />
 * provider: the provider to use to log the events generated of the eventName
group.<br />
 * profile: associates a profile with this rule (this isn’t required).<br />
 * minInstances, maxLimit, minInterval and custom: have the same meaning than
in the profile configuration subsection, but if you set its value, these settings
override the settings of the profile.
</p>
        <p>
For example, the first rule is called “All Errors Default”, and captures all events
from the “All Errors” group, that is, all events derived from WebBaseErrorEvent, to
the EventLog provider. The events are logged starting with the first event, but only
the first event is saved if there are similar events in the same minute.
</p>
        <p>
The second rule (called “Failure Audits Default”) saves events from the “Failure Audits”
event group (events derived from WebFailureAuditEvent, that gets triggered in an unsuccessful
login operation) to the EventLog provider, with the same profile properties as the
previous rule.
</p>
        <p>
Note that minInstances, maxLimit, minInterval and custom are redundant here because
the Default profile has the same attributes.
</p>
        <p>
          <strong>Example of use:</strong>
        </p>
        <p>
To use the SqlWebEventProvider in our own application we have to create the necessary
tables and stored procedures. One way is to use the aspnet_regsql.exe application.
If we have direct access to the server (remote connections are allowed) we can use
this:
</p>
        <p>
aspnet_regsql -S MyServer -d MyDataBase -U MyUserName -P MyPassword -A w
</p>
        <p>
If our server doesn't allow remote connections, we can generate the a script to run
using:
</p>
        <p>
aspnet_regsql -d MyDataBase -U MyUserName -P MyPassword  -A w -sqlexportonly
addwebevents.sql
</p>
        <p>
Another option to generate the required sql infrastructure if we're running in
full trust is to execute this code:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
System.Web.Management.<span style="COLOR: teal">SqlServices</span>.Install(<span style="COLOR: maroon">"MyDatabase"</span>,
System.Web.Management.<span style="COLOR: teal">SqlFeatures</span>.SqlWebEventProvider, <span style="COLOR: teal">ConfigurationManager</span>.ConnectionStrings[<span style="COLOR: maroon">"MyConnection"</span>].ConnectionString);
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
After the required sql infrastructure has been created, you have to configure the
health monitoring system using the web.config. An example of the configuration to
log appliaction lifetime events and errors is:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;</span>
            <span style="COLOR: maroon">healthMonitoring</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">enabled</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">true</span>"<span style="COLOR: blue"></span><span style="COLOR: red">heartbeatInterval</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">0</span>"<span style="COLOR: blue">&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;</span>
            <span style="COLOR: maroon">providers</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">MySqlWebEventProvider</span>"<span style="COLOR: blue"></span><span style="COLOR: red">type</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">System.Web.Management.SqlWebEventProvider,System.Web,Version=2.0.0.0,
Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a</span>"<span style="COLOR: blue"> </span><span style="COLOR: red">connectionStringName</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">MyConnection</span>"<span style="COLOR: blue"></span><span style="COLOR: red">maxEventDetailsLength</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">1073741823</span>"<span style="COLOR: blue"></span><span style="COLOR: red">buffer</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">true</span>"<span style="COLOR: blue"></span><span style="COLOR: red">bufferMode</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">Notification</span>"<span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;/</span>
            <span style="COLOR: maroon">providers</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;</span>
            <span style="COLOR: maroon">rules</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        &lt;</span>
            <span style="COLOR: maroon">clear</span>
            <span style="COLOR: blue"> /&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">All
Errors Default</span>"<span style="COLOR: blue"></span><span style="COLOR: red">eventName</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">All
Errors</span>"<span style="COLOR: blue"></span><span style="COLOR: red">provider</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">MySqlWebEventProvider</span>"<span style="COLOR: blue"></span><span style="COLOR: red">profile</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">Default</span>"<span style="COLOR: blue"> /&gt; 
      </span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">name</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">Application
Lifetime Events Default</span>"<span style="COLOR: blue"></span><span style="COLOR: red">eventName</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">Application
Lifetime Events</span>"<span style="COLOR: blue"></span><span style="COLOR: red">provider</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">MySqlWebEventProvider</span>"<span style="COLOR: blue"></span><span style="COLOR: red">profile</span><span style="COLOR: blue">=</span>"<span style="COLOR: blue">Default</span>"<span style="COLOR: blue"> /&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;/</span>
            <span style="COLOR: maroon">rules</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;/</span>
            <span style="COLOR: maroon">healthMonitoring</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
If you have used another event logging library like log4net or the enterprise library
you may wonder if it is better to use them instead of the health monitoring system.
My advice is that your project has only a web scenario and you don’t have to maintain
legacy code that uses log4net or the enterprise library, just use the health monitoring
system. Otherwise use log4net, the enterprise library or any other logging solutions
that you want.
</p>
        <p>
I think this is enough for an introduction to the health monitoring system. I may
post more in depth information about it in a future if time permits.<br /></p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=77dd4e93-e052-4b65-9b9d-81a17f0e2b6e" />
      </body>
      <title>ASP.NET 2.0 - Health Monitoring</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,77dd4e93-e052-4b65-9b9d-81a17f0e2b6e.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,77dd4e93-e052-4b65-9b9d-81a17f0e2b6e.aspx</link>
      <pubDate>Thu, 05 Oct 2006 16:28:10 GMT</pubDate>
      <description>&lt;p&gt;
The health monitoring in ASP.NET 2.0 is a framework to generate and capture events
during the life of the application. The health monitoring uses the provider model.
A health monitoring provider can capture events and do any processing with them (log
them, send them by email, etc). There are a lot of predefined events and we can create
our custom events. As we will see, it is very easy to use the health monitoring system,
but we need a solid understanding of the different elements involved. 
&lt;/p&gt;
&lt;p&gt;
To configure the health monitoring system we have to use the web.config. The health
monitoring section has to be placed inside the &amp;lt;system.web&amp;gt; section and has
the following structure:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;healthMonitoring&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;bufferModes&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;providers&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;profiles&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;rules&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;eventMappings&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;healthMonitoring&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The healthMonitoring element has two attributes:&lt;br&gt;
•&amp;nbsp;enabled: specifies if the health monitoring system is enabled or not.&lt;br&gt;
•&amp;nbsp;heartbeatInterval: the system will raise WebHeartbeatEvent with the frequency
specified here (more on this later).
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
&lt;strong&gt;Buffer modes:&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
There are some events that can be buffered so the provider saves some events in memory
before doing some work with them. The buffering options are specified in the providers
in the bufferModes subsection, and then a buffered provider points to a buffer mode
in order to use buffering. The buffer mode specifies the number of events of the buffer
and the flushing frequency and intervals.
&lt;/p&gt;
&lt;p&gt;
The default buffer modes are (extracted from the global web.config):
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;bufferModes&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;clear&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Critical
Notification&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxBufferSize&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;100&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxFlushSize&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;20&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;urgentFlushThreshold&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;1&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;regularFlushInterval&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Infinite&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;urgentFlushInterval&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;00:01:00&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxBufferThreads&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;1&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Notification&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxBufferSize&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;300&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxFlushSize&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;20&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;urgentFlushThreshold&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;1&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;regularFlushInterval&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Infinite&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;urgentFlushInterval&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;00:01:00&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxBufferThreads&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;1&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Analysis&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxBufferSize&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;1000&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxFlushSize&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;100&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;urgentFlushThreshold&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;100&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;regularFlushInterval&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;00:05:00&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;urgentFlushInterval&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;00:01:00&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxBufferThreads&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;1&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Logging&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxBufferSize&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;1000&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxFlushSize&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;200&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;urgentFlushThreshold&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;800&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;regularFlushInterval&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;00:30:00&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;urgentFlushInterval&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;00:05:00&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxBufferThreads&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;1&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;bufferModes&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The name attribute is used to associate a buffer mode with a provider. The maxBufferSize
attributes specifies the maximum number of events that can be buffered before flushing
them. 
&lt;/p&gt;
&lt;p&gt;
Usually, events are flushed at constant intervals specified by the regularFlushInterval.
However, some times is better to flush events more quickly than the regularFlushInterval.
When the number of buffered events is greater or equal than the urgentFlushThreshold,
the events will be flushed at an interval specified by the urgentFlushInterval. 
&lt;/p&gt;
&lt;p&gt;
The maxFlushSize specifies the maximum number of events to process when flushing.
&lt;/p&gt;
&lt;p&gt;
The maxBufferThreads attribute specifies the maximum number of threads used for flushing.
&lt;/p&gt;
&lt;p&gt;
For example, suppose we are using a provider that saves the events to a DB using the
“Logging” buffer mode. The buffer can hold up to 1000 events. Usually, the events
will be saved every 30 minutes, but if there are 800 or more events waiting to be
logged, they don’t have to wait 30 minutes to be saved, they will be saved at 5 minutes
intervals, until there are less than 800 in the buffer, as the provider will save
only 200 events at a time.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Providers:&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
A provider is a class that inherits from System.Web.Management.WebEventProvider. In
the providers configuration subsection we can add the providers that we want in order
to process the captured events. However, the association of providers and events to
capture is made in the rules section that will be explained later. The provider has
2 common attributes, name and type. Each specific provider can have more attributes
needed for its respective tasks. The name type is used for referencing the provider
in different sections and the type specifies the class and assembly where the provider
is located.
&lt;/p&gt;
&lt;p&gt;
This class diagram shows the available providers:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/healthmon_providers.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
The available providers are:
&lt;/p&gt;
&lt;p&gt;
•&amp;nbsp;SqlWebEventProvider stores events in a Sql Server database. 
&lt;br&gt;
•&amp;nbsp;EventLogWebEventProvider stores events in the windows event log.&lt;br&gt;
•&amp;nbsp;TraceWebEventProvider passes events to the Trace object.&lt;br&gt;
•&amp;nbsp;WmiWebEventProvider maps events to WMI events.&lt;br&gt;
•&amp;nbsp;SimpleMailWebEventProvider sends emails with event notifications.&lt;br&gt;
•&amp;nbsp;TemplateMailWebEventProvider uses a template to format the emails that sends
with event notifications.
&lt;/p&gt;
&lt;p&gt;
To configurate the Sql Server database for the SqlWebEventProvider take a look &lt;a href="http://weblogs.asp.net/scottgu/archive/2005/08/25/423703.aspx"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
The WebEventProvider class has 3 abstract methods:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: teal"&gt;WebEventProvider&lt;/span&gt; :
ProviderBase
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; WebEventProvider();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Flush();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; ProcessEvent(&lt;span style="COLOR: teal"&gt;WebBaseEvent&lt;/span&gt; raisedEvent);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Shutdown();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
The buffered event providers (Sql server provider and the mail providers) inherit
from the BufferedWebEventProvider class that provides the basic infrastructure for
a buffered provider:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: teal"&gt;BufferedWebEventProvider&lt;/span&gt; : &lt;span style="COLOR: teal"&gt;WebEventProvider&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; BufferedWebEventProvider();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; BufferMode
{ &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;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; UseBuffering
{ &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;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Flush();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Initialize(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; name,
NameValueCollection config);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; ProcessEvent(&lt;span style="COLOR: teal"&gt;WebBaseEvent&lt;/span&gt; eventRaised);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;abstract&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; ProcessEventFlush(&lt;span style="COLOR: teal"&gt;WebEventBufferFlushInfo&lt;/span&gt; flushInfo);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Shutdown();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
A buffered provider has two extra parameters, buffer and bufferMode. Buffering is
only used if buffer=”true”. If buffering is used, bufferMode links the provider with
a buffer mode that was explained in the previous section.
&lt;/p&gt;
&lt;p&gt;
The default configuration for the providers is (extracted from the global web.config):
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;providers&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;clear&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;EventLogProvider&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Management.EventLogWebEventProvider,System.Web”
/&amp;gt;&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;SqlWebEventProvider&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Management.SqlWebEventProvider,System.Web”&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;connectionStringName&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;LocalSqlServer&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxEventDetailsLength&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;1073741823&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;buffer&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;false&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;bufferMode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Notification&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;WmiWebEventProvider&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Management.WmiWebEventProvider”
/&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;providers&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Profiles:&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Some events should be always logged using a provider, but sometimes, an event can
happen a lot of times per second if an important error surfaces, so the profile subsection
can help to configure if we have to log all events received or if we can ignore the
same event for a short period of time.
&lt;/p&gt;
&lt;p&gt;
A group of events can be assigned a concrete profile in the rules section as we’ll
see soon.
&lt;/p&gt;
&lt;p&gt;
The default configuration for the profiles is (extracted from the global web.config):
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;profiles&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;clear&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Default&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;minInstances&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;1&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxLimit&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Infinite&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;minInterval&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;00:01:00&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;custom&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Critical&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;minInstances&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;1&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxLimit&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Infinite&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;minInterval&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;00:00:00&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;custom&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&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;profiles&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The name attribute is used to associate an event with the profile. The minInstances
indicates the minimum number of occurrences of an event before the event is logged.
The maxLimit is used to stop logging an event after the number of occurrences of the
event is greater or equal to this value. The minInterval can be used to avoid logging
events if the interval between events is less than the minInterval. 
&lt;/p&gt;
&lt;p&gt;
The custom attribute can be used to do more complex evaluations to check if the event
should be sent to the providers. See the IWebEventCustomEvaluator interface for more
information.
&lt;/p&gt;
&lt;p&gt;
As you can see, there are two predefined profile modes: the Critical, that logs every
event without exception; and the Default, that avoids logging the same event twice
in a minute.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Event Mappings:&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
In this configuration subsection, we associate a name with an event or group of events. 
&lt;/p&gt;
&lt;p&gt;
Without knowing a bit of the event types we can’t understand the health monitoring
system, so here it is an introduction to the different event classes:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/healthmon_events.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
The WebHeartbeatEvent event can be raised periodically to give information about the
status of the application (thread count, managed heap size, number of app domains,
requests queued, requests executing, request rejected, information about the working
set, etc).
&lt;/p&gt;
&lt;p&gt;
The WebApplicationLifetimeEvent represents an important event in the application life
cycle (application start, application shutdown, etc) and the information that can
give you is very important, as you can analyze why your site is shutting down. For
example, these are some constants that specify the shutdown reason:
&lt;/p&gt;
&lt;p&gt;
ApplicationShutdownUnknown 
&lt;br&gt;
ApplicationShutdownHostingEnvironment&lt;br&gt;
ApplicationShutdownChangeInGlobalAsax&lt;br&gt;
ApplicationShutdownConfigurationChange&lt;br&gt;
ApplicationShutdownUnloadAppDomainCalled&lt;br&gt;
ApplicationShutdownChangeInSecurityPolicyFile&lt;br&gt;
ApplicationShutdownBinDirChangeOrDirectoryRename&lt;br&gt;
ApplicationShutdownBrowsersDirChangeOrDirectoryRename&lt;br&gt;
ApplicationShutdownCodeDirChangeOrDirectoryRename&lt;br&gt;
ApplicationShutdownResourcesDirChangeOrDirectoryRename&lt;br&gt;
ApplicationShutdownIdleTimeout&lt;br&gt;
ApplicationShutdownPhysicalApplicationPathChanged&lt;br&gt;
ApplicationShutdownHttpRuntimeClose&lt;br&gt;
ApplicationShutdownInitializationError&lt;br&gt;
ApplicationShutdownMaxRecompilationsReached
&lt;/p&gt;
&lt;p&gt;
The WebRequestEvent event is raised at every request and contains information about
the IP of the user that makes the request, URL of the request, etc.
&lt;/p&gt;
&lt;p&gt;
The WebBaseErrorEvent class is the base class for all events that report error conditions.
The WebErrorEvent event is raise when configuration or code problems arise (for example,
when the code throws an unhandled exception). The WebRequestErrorEvent event is raised
when there is an error with a request (for example, a deserialization error in the
ObjectStateFormatter).
&lt;/p&gt;
&lt;p&gt;
The WebAuditEvent class is the base class for success (WebSuccessAuditEvent) or failure
(WebFailureAuditEvent) of security related operations. When an user try to log in
the web application, a WebAuthenticationSuccessAuditEvent WebAuthenticationFailureAuditEvent
if the login process completed successfully or not. If the view state has been altered,
the WebViewStateFailureAuditEvent will be raised.
&lt;/p&gt;
&lt;p&gt;
The default event mappings are (extracted from the global web.config):
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;eventMappings&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;clear&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;All
Events&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Management.WebBaseEvent,System.Web&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;startEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;0&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;endEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;2147483647&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Heartbeats&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Management.WebHeartbeatEvent,System.Web &lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;startEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;0&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;endEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;2147483647&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Application
Lifetime Events&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Management.WebApplicationLifetimeEvent,System.Web &lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;startEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;0&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;endEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;2147483647&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Request
Processing Events&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Management.WebRequestEvent,System.Web &lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;startEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;0&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;endEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;2147483647&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;All
Errors&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Management.WebBaseErrorEvent,System.Web &lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;startEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;0&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;endEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;2147483647&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Infrastructure
Errors&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Management.WebErrorEvent,System.Web &lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;startEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;0&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;endEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;2147483647&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Request
Processing Errors&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Management.WebRequestErrorEvent,System.Web &lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;startEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;0&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;endEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;2147483647&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;All
Audits&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Management.WebAuditEvent,System.Web &lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;startEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;0&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;endEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;2147483647&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Failure
Audits&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Management.WebFailureAuditEvent,System.Web &lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;startEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;0&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;endEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;2147483647&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Success
Audits&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Management.WebSuccessAuditEvent,System.Web &lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;startEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;0&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;endEventCode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;2147483647&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;eventMappings&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
The name attribute is used to associate a rule with a provider and a group of events
as we’ll see in the rules section. The type specifies a class of event that is mapped
to the event group. Note that all derived classes are also mapped by the same event
group.
&lt;/p&gt;
&lt;p&gt;
The startEventCode and the endEventCode attributes are used to specify a range of
event codes. The event code is also saved with the event and helps in the identification
of the event.
&lt;/p&gt;
&lt;p&gt;
As a summary, the default web.config has this mapping:
&lt;/p&gt;
&lt;p&gt;
All Events -&amp;gt; WebBaseEvent&lt;br&gt;
Heartbeats -&amp;gt; WebHeartbeatEvent&lt;br&gt;
Application Lifetime Events -&amp;gt; WebApplicationLifetimeEvent&lt;br&gt;
Request Processing Events -&amp;gt; WebRequestEvent&lt;br&gt;
All Errors -&amp;gt; WebBaseErrorEvent&lt;br&gt;
Request Processing Errors -&amp;gt; WebRequestErrorEvent&lt;br&gt;
All Audits -&amp;gt; WebAuditEvent&lt;br&gt;
Failure Audits -&amp;gt; WebFailureAuditEvent&lt;br&gt;
Success Audits -&amp;gt; WebSuccessAuditEvent
&lt;/p&gt;
&lt;p&gt;
Note that the constructor for these events is protected so you can’t create instances
of the predefined events. Instead you should create your custom event inheriting from
the appropriate event class.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Rules:&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
This configuration subsection is where all the associations and entities seen earlier
take place.
&lt;/p&gt;
&lt;p&gt;
The default configuration for the rules is (extracted from the global web.config):
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;rules&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;clear&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;All
Errors Default&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;eventName&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;All
Errors&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;provider&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;EventLogProvider&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;profile&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Default&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;minInstances&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;1&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxLimit&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Infinite&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;minInterval&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;00:01:00&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;custom&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&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;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Failure
Audits Default&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;eventName&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Failure
Audits&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;provider&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;EventLogProvider&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;profile&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Default&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;minInstances&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;1&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxLimit&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Infinite&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;minInterval&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;00:01:00&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;custom&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&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;rules&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
The attributes for each rule are:&lt;br&gt;
&amp;nbsp;* name: a string representing the name of the rule.&lt;br&gt;
&amp;nbsp;* eventName: associates an event group with this rule.&lt;br&gt;
&amp;nbsp;* provider: the provider to use to log the events generated of the eventName
group.&lt;br&gt;
&amp;nbsp;* profile: associates a profile with this rule (this isn’t required).&lt;br&gt;
&amp;nbsp;* minInstances, maxLimit, minInterval and custom: have the same meaning than
in the profile configuration subsection, but if you set its value, these settings
override the settings of the profile.
&lt;/p&gt;
&lt;p&gt;
For example, the first rule is called “All Errors Default”, and captures all events
from the “All Errors” group, that is, all events derived from WebBaseErrorEvent, to
the EventLog provider. The events are logged starting with the first event, but only
the first event is saved if there are similar events in the same minute.
&lt;/p&gt;
&lt;p&gt;
The second rule (called “Failure Audits Default”) saves events from the “Failure Audits”
event group (events derived from WebFailureAuditEvent, that gets triggered in an unsuccessful
login operation) to the EventLog provider, with the same profile properties as the
previous rule.
&lt;/p&gt;
&lt;p&gt;
Note that minInstances, maxLimit, minInterval and custom are redundant here because
the Default profile has the same attributes.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Example of use:&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
To use the SqlWebEventProvider&amp;nbsp;in our own application we have to create the necessary
tables and stored procedures. One way is to use the aspnet_regsql.exe application.
If we have direct access to the server (remote connections are allowed) we can use
this:
&lt;/p&gt;
&lt;p&gt;
aspnet_regsql -S MyServer -d MyDataBase -U MyUserName -P MyPassword -A w
&lt;/p&gt;
&lt;p&gt;
If our server doesn't allow remote connections, we can generate the a script to run
using:
&lt;/p&gt;
&lt;p&gt;
aspnet_regsql -d MyDataBase -U MyUserName -P MyPassword&amp;nbsp; -A w -sqlexportonly
addwebevents.sql
&lt;/p&gt;
&lt;p&gt;
Another option to generate the required sql infrastructure&amp;nbsp;if we're running in
full trust is to execute this code:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
System.Web.Management.&lt;span style="COLOR: teal"&gt;SqlServices&lt;/span&gt;.Install(&lt;span style="COLOR: maroon"&gt;"MyDatabase"&lt;/span&gt;,
System.Web.Management.&lt;span style="COLOR: teal"&gt;SqlFeatures&lt;/span&gt;.SqlWebEventProvider, &lt;span style="COLOR: teal"&gt;ConfigurationManager&lt;/span&gt;.ConnectionStrings[&lt;span style="COLOR: maroon"&gt;"MyConnection"&lt;/span&gt;].ConnectionString);
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
After the required sql infrastructure has been created, you have to configure the
health monitoring system using the web.config. An example of the configuration to
log appliaction lifetime events and errors is:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;healthMonitoring&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;enabled&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;true&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;heartbeatInterval&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;0&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;providers&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;MySqlWebEventProvider&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;type&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;System.Web.Management.SqlWebEventProvider,System.Web,Version=2.0.0.0,
Culture=neutral,PublicKeyToken=b03f5f7f11d50a3a&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;&amp;nbsp;&lt;/span&gt;&lt;span style="COLOR: red"&gt;connectionStringName&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;MyConnection&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;maxEventDetailsLength&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;1073741823&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;buffer&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;true&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;bufferMode&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Notification&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;providers&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;rules&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;clear&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;All
Errors Default&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;eventName&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;All
Errors&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;provider&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;MySqlWebEventProvider&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;profile&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Default&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; /&amp;gt;&amp;nbsp;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;name&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Application
Lifetime Events Default&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;eventName&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Application
Lifetime Events&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;provider&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;MySqlWebEventProvider&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;profile&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;Default&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;rules&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;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;healthMonitoring&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
If you have used another event logging library like log4net or the enterprise library
you may wonder if it is better to use them instead of the health monitoring system.
My advice is that your project has only a web scenario and you don’t have to maintain
legacy code that uses log4net or the enterprise library, just use the health monitoring
system. Otherwise use log4net, the enterprise library or any other logging solutions
that you want.
&lt;/p&gt;
&lt;p&gt;
I think this is enough for an introduction to the health monitoring system. I may
post more in depth information about it in a future if time permits.&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=77dd4e93-e052-4b65-9b9d-81a17f0e2b6e" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,77dd4e93-e052-4b65-9b9d-81a17f0e2b6e.aspx</comments>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=c59facc0-301e-4e30-898d-428038828dcd</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,c59facc0-301e-4e30-898d-428038828dcd.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,c59facc0-301e-4e30-898d-428038828dcd.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=c59facc0-301e-4e30-898d-428038828dcd</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I have started to look at Atlas. The first thing I have played with is the layer to
provide better OOP features for Javascript.
</p>
        <p>
Note: this is based on an early version of the product (July CTP), so this information
can change for the final release.
</p>
        <p>
          <strong>Javascript OOP features</strong>
        </p>
        <p>
Javascript is a prototype-based object oriented language. This means that every object
has a prototype, an object from which it inherits properties and methods. The prototype
is a shared property of the class that can be accessed like this:
</p>
        <p>
myClass.prototype
</p>
        <p>
As Javascript is an interpreted language, when the interpreter founds an expression
like:
</p>
        <p>
myObject.myProperty
</p>
        <p>
first it checks if the object instance “myObject” has a property called “myProperty”.
If not, then it tries to find that property in the prototype object of that class
(myClass.prototype.myProperty). This prototype relationship is recursive, because
the prototype is an object that can have a prototype, so this recursion ends only
when Object is reached, the superclass of all objects.
</p>
        <p>
In Javascript, a class is defined by a function (the constructor) and its prototype
(that defines the properties and methods that each object instance has by default,
because of how the interpreter evaluates the expressions).
</p>
        <p>
So, to define a class in Javascript we have to do this:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
TestClass = <span style="COLOR: blue">function</span>() {
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
If we want to add a method to the class we can do it like this:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
TestClass = <span style="COLOR: blue">function</span>() {
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>.method1 = <span style="COLOR: blue">function</span>(){
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
Or like this:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
TestClass = <span style="COLOR: blue">function</span>() {
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
TestClass.prototype.method2 = <span style="COLOR: blue">function</span>(){
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
What's the difference? Consider the following class:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
TestClass = <span style="COLOR: blue">function</span>() {
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>.method1 = <span style="COLOR: blue">function</span>(){
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
TestClass.prototype.method2 = <span style="COLOR: blue">function</span>(){
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <p>
If we instantiate two objects of the class TestClass, we can see the difference:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">var</span> objTestClass1 = <span style="COLOR: blue">new</span> TestClass();
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">var</span> objTestClass2 = <span style="COLOR: blue">new</span> TestClass();
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
This diagram shows the internal representation of the object:
</p>
        <p>
          <img src="http://www.manuelabadia.com/blog/content/binary/javascriptOO.png" border="0" />
        </p>
        <p>
          <br />
As you can see, the method declared using the prototype is shared between instances
of the class. However, the method added in the constructor is created for each instance.
So:
</p>
        <p>
objTestClass1.method1 != objTestClass2.method1 
<br />
and 
<br />
objTestClass1.method2 == objTestClass2.method2
</p>
        <p>
Basically, the prototype is the only “object oriented mechanism” present in Javascript.
As you can see it is not an usual object oriented language. Using the prototype
you can come up with your own solution to simulate a more complete object oriented
language (inheritance, virtual methods, calling the base method, etc).
</p>
        <p>
          <strong>Atlas OOP features</strong>
        </p>
        <p>
Atlas adds some valuable features to provide a more natural object oriented programming
models. What Atlas offers is:<br />
• namespaces<br />
• inheritance<br />
• properties<br />
• defining virtual methods<br />
• calling base methods<br />
• interfaces<br />
• enumerations<br />
• attributes<br />
• reflection
</p>
        <p>
          <strong>Namespaces</strong>
        </p>
        <p>
To create a namespace in Atlas you have to write something like:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
Type.registerNamespace(<span style="COLOR: maroon">'Manu.Atlas.Tests'</span>);
</p>
        </div>
        <!--EndFragment-->
        <p>
          <br />
Internally Atlas adds a Type property to the window object (the default Javascript
context), and assigns it the Function built-in type. Atlas adds a lot of methods and
properties to Function, as we’ll see later.
</p>
        <p>
The registerNamespace function splits the namespace by the dots and creates a hierarchy
of objects in the window object that resemble the namespace. For example, for the
namespace Manu.Atlas.Tests the following properties are created:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
window.Manu = <span style="COLOR: blue">new</span> Object();
</p>
          <p style="MARGIN: 0px">
window.Manu.Atlas = <span style="COLOR: blue">new</span> Object();
</p>
          <p style="MARGIN: 0px">
window.Manu.Atlas.Tests = <span style="COLOR: blue">new</span> Object();
</p>
        </div>
        <p>
          <!--EndFragment-->
          <br />
          <strong>Inheritance</strong>
        </p>
        <p>
Atlas theorically supports multiple inheritance, but in the July release it isn’t
working properly. Anyway, multiple inheritance support will be removed before the
final version, so don't count on it.
</p>
        <p>
A class in Atlas has to be registered to work properly. The syntax to register a class
is:
</p>
        <p>
FullClassName.registerClass(typeName, baseTypes, interfaces)
</p>
        <p>
Only the first parameter is mandatory. The second parameter specifies the base class
or base classes if multiple inheritance is used. The second parameter could be a reference
to the base class or an array of type names for the base class (or classes). The third
parameter is the interface implemented by the class (if any). A class can implement
multiple interfaces so you can call registerClass with more than 3 parameters. Any
extra parameter should be an interface that is being implemented by the class.
</p>
        <p>
Atlas adds some information to each class type it creates to provide the necessary
machinery for the object oriented features:
</p>
        <p>
• _typeName field: with the name of the type (the function getTypeName returns
it).<br />
• _baseType field: a reference to the parent type (the function getBaseType returns.<br />
• _basePrototypePending property: a boolean that is used to know if the class
has been initialized (more on this later).<br />
• _interfaces: an array with references to the interfaces implemented by the
class.<br />
• bases: an array with references to the parent classes.<br />
• _interface, _sealed and _abstract boolean properties to give information about
the type.<br />
• _baseMethods: a hash table where methods that can be called by child classes
are stored.
</p>
        <p>
The core of the inheritance mechanism is handled by the initializeBase function that
has to be called in the constructor of a derived class. The syntax is:
</p>
        <p>
FullClassName.initializeBase(instance, baseArguments)
</p>
        <p>
Where the first parameter is the instance to be initialized and the second parameter
is an array of arguments to pass to the base constructor.
</p>
        <p>
The initializeBase method starts calling the constructor for each interface in the
class (stored in the _interfaces collection). Then calls the _setBases method and
finally calls the _callBaseConstructors method.
</p>
        <p>
The _setBases method does an important job. If the class inherits from another class,
the method iterates through all the base classes, filling the bases collection, and
recursively calling the _setBases method on the base classes. After the _setBases
method has been called for a base class, the _copyProps method is called. The _copyProps
method iterates through all properties and methods stored in the prototype of the
base class and stores them in them in the prototype of the subclass. So, after the
call to _copyProps, the subclass also has the properties and methods specified in
the prototype of the base class.
</p>
        <p>
The _callBaseConstructors method iterates through the bases array, calling the base
constructor with the current object instance.
</p>
        <p>
So, after calling the initializeBase method, the object has all the properties and
methods of the base classes, giving the illusion of inheritance.
</p>
        <p>
If we declare the methods and properties in the prototype, they will be created in
the child classes in the _copyProps method. If we create the properties and methods
in the constructor, they will be created in the child classes in the _callBaseConstructors
method.
</p>
        <p>
An example of a class B that inherits from A is:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
Type.registerNamespace(<span style="COLOR: maroon">'Manu.Atlas.Tests'</span>);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.A = <span style="COLOR: blue">function</span> (a1, a2) {
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>._a1 = a1;
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>._a2 = a2;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.A.prototype._a1 = 0;
</p>
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.A.prototype._a2 = 0;
</p>
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.A.prototype.get_a1 = <span style="COLOR: blue">function</span> ()
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">return</span><span style="COLOR: blue">this</span>._a1;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.A.prototype.set_a1 = <span style="COLOR: blue">function</span>(value)
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>._a1 = value;
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">return</span> value;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.A.prototype.get_a2 = <span style="COLOR: blue">function</span> ()
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">return</span><span style="COLOR: blue">this</span>._a2;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.A.prototype.set_a2 = <span style="COLOR: blue">function</span>(value)
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>._a2 = value;
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">return</span> value;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.B = <span style="COLOR: blue">function</span> (a1, a2, b1) {
</p>
          <p style="MARGIN: 0px">
    Manu.Atlas.Tests.B.initializeBase(<span style="COLOR: blue">this</span>,
[ a1, a2 ]);
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>._b1 = b1;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.B.prototype._b1 = 0;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.B.prototype.get_b1 = <span style="COLOR: blue">function</span> ()
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">return</span><span style="COLOR: blue">this</span>._b1;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.B.prototype.set_b1 = <span style="COLOR: blue">function</span>(value)
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>._b1 = value;
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">return</span> value;
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.A.registerClass(<span style="COLOR: maroon">'Manu.Atlas.Tests.A'</span>, <span style="COLOR: blue">null</span>);
</p>
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.B.registerClass(<span style="COLOR: maroon">'Manu.Atlas.Tests.B'</span>,
Manu.Atlas.Tests.A);
</p>
        </div>
        <!--EndFragment-->
        <p>
          <br />
Note that we have created the properties and methods using the prototype in order
to save memory. We can declare the A class like this:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.A = <span style="COLOR: blue">function</span> (a1, a2) {
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>._a1 = a1;
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>._a2 = a2;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>.get_a1 = <span style="COLOR: blue">function</span> ()
{
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">return</span><span style="COLOR: blue">this</span>._a1;
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>.set_a1 = <span style="COLOR: blue">function</span> (value)
{
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">this</span>._a1 =
value;
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>.get_a2 = <span style="COLOR: blue">function</span> ()
{
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">return</span><span style="COLOR: blue">this</span>._a2;
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">this</span>.set_a2 = <span style="COLOR: blue">function</span> (value)
{
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">this</span>._a2 =
value;
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <!--EndFragment-->
        <p>
          <br />
And it will be functionally equivalent although it will be more expensive in memory
terms as each object instance will have 4 methods instead of sharing them (as
explained before). This mode of creating a class is called the closure model. The
previous one is called the prototype mode.
</p>
        <p>
If we create an object of type B, we can call the base properties. In the following
sample, the last line evaluates to 3:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">var</span> objA = <span style="COLOR: blue">new</span> Manu.Atlas.Tests.A(2,
7);
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">var</span> objB = <span style="COLOR: blue">new</span> Manu.Atlas.Tests.B(1,
3, 5);
</p>
          <p style="MARGIN: 0px">
objB.get_a2();
</p>
        </div>
        <p>
          <!--EndFragment-->
          <br />
          <br />
There are more functions to register a class, depending on the behaviour of the class:<br />
registerSealedClass and registerAbstractClass. The name clearly shows when to use
them although they just set a property and call to the registerClass method. If a
class is registered using registerSealedClass any class inheriting from it will not
have its members copied because the _setBases method will not be called although no
error will appear.
</p>
        <p>
The Function built in type is also extended with some methods to check interface implementation,
inheritance and type:<br />
• implementsInterface<br />
• isImplementedBy<br />
• inheritsFrom<br />
• isInstanceOfType
</p>
        <p>
          <strong>Properties</strong>
        </p>
        <p>
As javascript doesn't have properties like C#, the recommended approach (and what
is used in the atlas library) is to provide a getter and a setter method for properties
with the signature get_propertyName set_propertyName as we did earlier for the Manu.Atlas.Tests.A
class. It is really important that the getter starts with "get_" and the setter with
"set_" as this is mandatory for integrating our custom components into the Atlas framework
as we will see in a future. 
</p>
        <p>
          <strong>Methods</strong>
        </p>
        <p>
The initializeBase method provided most of the machinery for the OOP with Atlas, but
there is something missing: how to call a base method from an overridden method.
</p>
        <p>
Atlas provides 3 methods related to this problem:<br />
• registerBaseMethod<br />
• callBaseMethod<br />
• getBaseMethod
</p>
        <p>
The first one is saves a method in the _baseMethods hash table, in order for a child
class to call to the base class implementation. The child class has to call to the
callBaseMethod for this, and the implementation of callBaseMethod uses the getBaseMethod
method in order to obtain a reference to the base method.
</p>
        <p>
There is no need to call to the registerBaseMethod if we define our methods using
the prototype because the getBaseMethod searchs the method in the prototype if it
isn’t found in the _baseMethods hash table. 
</p>
        <p>
An example of a class with a method that calls the base method follows:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.C = <span style="COLOR: blue">function</span> (a1, a2, b1) {
</p>
          <p style="MARGIN: 0px">
    Manu.Atlas.Tests.C.initializeBase(<span style="COLOR: blue">this</span>,
[ a1, a2, b1 ]);
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.C.prototype.get_b1 = <span style="COLOR: blue">function</span> ()
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">return</span> Manu.Atlas.Tests.C.callBaseMethod(<span style="COLOR: blue">this</span>, <span style="COLOR: maroon">'get_b1'</span>);
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.C.prototype.set_b1 = <span style="COLOR: blue">function</span> (value)
{
</p>
          <p style="MARGIN: 0px">
    Manu.Atlas.Tests.C.callBaseMethod(<span style="COLOR: blue">this</span>, <span style="COLOR: maroon">'set_b1'</span>,
[ value ]);
</p>
          <p style="MARGIN: 0px">
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
Manu.Atlas.Tests.C.registerClass(<span style="COLOR: maroon">'Manu.Atlas.Tests.C'</span>,
Manu.Atlas.Tests.B);
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
The Function built in type is extended with two static functions to help when creating
a class or an interface:<br />
• abstractMethod: method that throws an exception if called.<br />
• emptyFunction: the name says it all.
</p>
        <p>
I’m running out of time now so in another post I’ll finish talking about the OO features
of Atlas.
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=c59facc0-301e-4e30-898d-428038828dcd" />
      </body>
      <title>Microsoft AJAX Library (Atlas) – Javascript OOP enhancements (Part 1)</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,c59facc0-301e-4e30-898d-428038828dcd.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,c59facc0-301e-4e30-898d-428038828dcd.aspx</link>
      <pubDate>Tue, 26 Sep 2006 22:34:38 GMT</pubDate>
      <description>&lt;p&gt;
I have started to look at Atlas. The first thing I have played with is the layer to
provide better OOP features for Javascript.
&lt;/p&gt;
&lt;p&gt;
Note: this is based on an early version of the product (July CTP), so this information
can change for the final release.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Javascript OOP features&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Javascript is a prototype-based object oriented language. This means that every object
has a prototype, an object from which it inherits properties and methods. The prototype
is a shared property of the class that can be accessed like this:
&lt;/p&gt;
&lt;p&gt;
myClass.prototype
&lt;/p&gt;
&lt;p&gt;
As Javascript is an interpreted language, when the interpreter founds an expression
like:
&lt;/p&gt;
&lt;p&gt;
myObject.myProperty
&lt;/p&gt;
&lt;p&gt;
first it checks if the object instance “myObject” has a property called “myProperty”.
If not, then it tries to find that property in the prototype object of that class
(myClass.prototype.myProperty). This prototype relationship is recursive, because
the prototype is an object that can have a prototype, so this recursion ends only
when Object is reached, the superclass of all objects.
&lt;/p&gt;
&lt;p&gt;
In Javascript, a class is defined by a function (the constructor) and its prototype
(that defines the properties and methods that each object instance has by default,
because of how the interpreter evaluates the expressions).
&lt;/p&gt;
&lt;p&gt;
So, to define a class in Javascript we have to do this:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
TestClass = &lt;span style="COLOR: blue"&gt;function&lt;/span&gt;() {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
If we want to add a method to the class we can do it like this:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
TestClass = &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;this&lt;/span&gt;.method1 = &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;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
Or like this:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
TestClass = &lt;span style="COLOR: blue"&gt;function&lt;/span&gt;() {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
TestClass.prototype.method2 = &lt;span style="COLOR: blue"&gt;function&lt;/span&gt;(){
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
What's the difference? Consider the following class:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
TestClass = &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;this&lt;/span&gt;.method1 = &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;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
TestClass.prototype.method2 = &lt;span style="COLOR: blue"&gt;function&lt;/span&gt;(){
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;p&gt;
If we instantiate two objects of the class TestClass, we can see the difference:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; objTestClass1 = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; TestClass();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; objTestClass2 = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; TestClass();
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
This diagram shows the internal representation of the object:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/javascriptOO.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
As you can see, the method declared using the prototype is shared between instances
of the class. However, the method added in the constructor is created for each instance.
So:
&lt;/p&gt;
&lt;p&gt;
objTestClass1.method1 != objTestClass2.method1 
&lt;br&gt;
and 
&lt;br&gt;
objTestClass1.method2 == objTestClass2.method2
&lt;/p&gt;
&lt;p&gt;
Basically, the prototype is the only “object oriented mechanism” present in Javascript.
As you can see it is not an usual object oriented&amp;nbsp;language. Using the prototype
you can come up with your own solution to simulate a more complete object oriented
language (inheritance, virtual methods, calling the base method, etc).
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Atlas OOP features&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Atlas adds some valuable features to provide a more natural object oriented programming
models. What Atlas offers is:&lt;br&gt;
•&amp;nbsp;namespaces&lt;br&gt;
•&amp;nbsp;inheritance&lt;br&gt;
•&amp;nbsp;properties&lt;br&gt;
•&amp;nbsp;defining virtual methods&lt;br&gt;
•&amp;nbsp;calling base methods&lt;br&gt;
•&amp;nbsp;interfaces&lt;br&gt;
•&amp;nbsp;enumerations&lt;br&gt;
•&amp;nbsp;attributes&lt;br&gt;
•&amp;nbsp;reflection
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Namespaces&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
To create a namespace in Atlas you have to write something like:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
Type.registerNamespace(&lt;span style="COLOR: maroon"&gt;'Manu.Atlas.Tests'&lt;/span&gt;);
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&lt;br&gt;
Internally Atlas adds a Type property to the window object (the default Javascript
context), and assigns it the Function built-in type. Atlas adds a lot of methods and
properties to Function, as we’ll see later.
&lt;/p&gt;
&lt;p&gt;
The registerNamespace function splits the namespace by the dots and creates a hierarchy
of objects in the window object that resemble the namespace. For example, for the
namespace Manu.Atlas.Tests the following properties are created:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
window.Manu = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; Object();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
window.Manu.Atlas = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; Object();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
window.Manu.Atlas.Tests = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; Object();
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;br&gt;
&lt;strong&gt;Inheritance&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
Atlas theorically supports multiple inheritance, but in the July release it isn’t
working properly. Anyway, multiple inheritance support will be removed before the
final version, so don't count on it.
&lt;/p&gt;
&lt;p&gt;
A class in Atlas has to be registered to work properly. The syntax to register a class
is:
&lt;/p&gt;
&lt;p&gt;
FullClassName.registerClass(typeName, baseTypes, interfaces)
&lt;/p&gt;
&lt;p&gt;
Only the first parameter is mandatory. The second parameter specifies the base class
or base classes if multiple inheritance is used. The second parameter could be a reference
to the base class or an array of type names for the base class (or classes). The third
parameter is the interface implemented by the class (if any). A class can implement
multiple interfaces so you can call registerClass with more than 3 parameters. Any
extra parameter should be an interface that is being implemented by the class.
&lt;/p&gt;
&lt;p&gt;
Atlas adds some information to each class type it creates to provide the necessary
machinery for the object oriented features:
&lt;/p&gt;
&lt;p&gt;
•&amp;nbsp;_typeName field: with the name of the type (the function getTypeName returns
it).&lt;br&gt;
•&amp;nbsp;_baseType field: a reference to the parent type (the function getBaseType returns.&lt;br&gt;
•&amp;nbsp;_basePrototypePending property: a boolean that is used to know if the class
has been initialized (more on this later).&lt;br&gt;
•&amp;nbsp;_interfaces: an array with references to the interfaces implemented by the
class.&lt;br&gt;
•&amp;nbsp;bases: an array with references to the parent classes.&lt;br&gt;
•&amp;nbsp;_interface, _sealed and _abstract boolean properties to give information about
the type.&lt;br&gt;
•&amp;nbsp;_baseMethods: a hash table where methods that can be called by child classes
are stored.
&lt;/p&gt;
&lt;p&gt;
The core of the inheritance mechanism is handled by the initializeBase function that
has to be called in the constructor of a derived class. The syntax is:
&lt;/p&gt;
&lt;p&gt;
FullClassName.initializeBase(instance, baseArguments)
&lt;/p&gt;
&lt;p&gt;
Where the first parameter is the instance to be initialized and the second parameter
is an array of arguments to pass to the base constructor.
&lt;/p&gt;
&lt;p&gt;
The initializeBase method starts calling the constructor for each interface in the
class (stored in the _interfaces collection). Then calls the _setBases method and
finally calls the _callBaseConstructors method.
&lt;/p&gt;
&lt;p&gt;
The _setBases method does an important job. If the class inherits from another class,
the method iterates through all the base classes, filling the bases collection, and
recursively calling the _setBases method on the base classes. After the _setBases
method has been called for a base class, the _copyProps method is called. The _copyProps
method iterates through all properties and methods stored in the prototype of the
base class and stores them in them in the prototype of the subclass. So, after the
call to _copyProps, the subclass also has the properties and methods specified in
the prototype of the base class.
&lt;/p&gt;
&lt;p&gt;
The _callBaseConstructors method iterates through the bases array, calling the base
constructor with the current object instance.
&lt;/p&gt;
&lt;p&gt;
So, after calling the initializeBase method, the object has all the properties and
methods of the base classes, giving the illusion of inheritance.
&lt;/p&gt;
&lt;p&gt;
If we declare the methods and properties in the prototype, they will be created in
the child classes in the _copyProps method. If we create the properties and methods
in the constructor, they will be created in the child classes in the _callBaseConstructors
method.
&lt;/p&gt;
&lt;p&gt;
An example of a class B that inherits from A is:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
Type.registerNamespace(&lt;span style="COLOR: maroon"&gt;'Manu.Atlas.Tests'&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.A = &lt;span style="COLOR: blue"&gt;function&lt;/span&gt; (a1, a2) {
&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;._a1 = a1;
&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;._a2 = a2;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.A.prototype._a1 = 0;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.A.prototype._a2 = 0;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.A.prototype.get_a1 = &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; &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;._a1;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.A.prototype.set_a1 = &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;this&lt;/span&gt;._a1 = value;
&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; value;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.A.prototype.get_a2 = &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; &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;._a2;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.A.prototype.set_a2 = &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;this&lt;/span&gt;._a2 = value;
&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; value;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.B = &lt;span style="COLOR: blue"&gt;function&lt;/span&gt; (a1, a2, b1) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Manu.Atlas.Tests.B.initializeBase(&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;,
[ a1, a2 ]);
&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;._b1 = b1;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.B.prototype._b1 = 0;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.B.prototype.get_b1 = &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; &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;._b1;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.B.prototype.set_b1 = &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;this&lt;/span&gt;._b1 = value;
&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; value;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.A.registerClass(&lt;span style="COLOR: maroon"&gt;'Manu.Atlas.Tests.A'&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.B.registerClass(&lt;span style="COLOR: maroon"&gt;'Manu.Atlas.Tests.B'&lt;/span&gt;,
Manu.Atlas.Tests.A);
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&lt;br&gt;
Note that we have created the properties and methods using the prototype in order
to save memory. We can declare the A class like this:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.A = &lt;span style="COLOR: blue"&gt;function&lt;/span&gt; (a1, a2) {
&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;._a1 = a1;
&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;._a2 = a2;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&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;.get_a1 = &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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;._a1;
&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;this&lt;/span&gt;.set_a1 = &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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;._a1 =
value;
&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;this&lt;/span&gt;.get_a2 = &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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;._a2;
&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;this&lt;/span&gt;.set_a2 = &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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;._a2 =
value;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&lt;br&gt;
And it will be functionally equivalent although it will be more expensive in memory
terms as each object instance will have&amp;nbsp;4 methods instead of sharing them (as
explained before). This mode of creating a class is called the closure model. The
previous one is called the prototype mode.
&lt;/p&gt;
&lt;p&gt;
If we create an object of type B, we can call the base properties. In the following
sample, the last line evaluates to 3:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; objA = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; Manu.Atlas.Tests.A(2,
7);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;var&lt;/span&gt; objB = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; Manu.Atlas.Tests.B(1,
3, 5);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
objB.get_a2();
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;br&gt;
&lt;br&gt;
There are more functions to register a class, depending on the behaviour of the class:&lt;br&gt;
registerSealedClass and registerAbstractClass. The name clearly shows when to use
them although they just set a property and call to the registerClass method. If a
class is registered using registerSealedClass any class inheriting from it will not
have its members copied because the _setBases method will not be called although no
error will appear.
&lt;/p&gt;
&lt;p&gt;
The Function built in type is also extended with some methods to check interface implementation,
inheritance and type:&lt;br&gt;
•&amp;nbsp;implementsInterface&lt;br&gt;
•&amp;nbsp;isImplementedBy&lt;br&gt;
•&amp;nbsp;inheritsFrom&lt;br&gt;
•&amp;nbsp;isInstanceOfType
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Properties&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
As javascript doesn't have properties like C#, the recommended approach (and what
is used in the atlas library) is to provide a getter and a setter method for properties
with the signature get_propertyName set_propertyName as we did earlier for the Manu.Atlas.Tests.A
class. It is really important that the getter starts with "get_" and the setter with
"set_" as this is mandatory for integrating our custom components into the Atlas framework
as we will see in a future. 
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Methods&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The initializeBase method provided most of the machinery for the OOP with Atlas, but
there is something missing: how to call a base method from an overridden method.
&lt;/p&gt;
&lt;p&gt;
Atlas provides 3 methods related to this problem:&lt;br&gt;
•&amp;nbsp;registerBaseMethod&lt;br&gt;
•&amp;nbsp;callBaseMethod&lt;br&gt;
•&amp;nbsp;getBaseMethod
&lt;/p&gt;
&lt;p&gt;
The first one is saves a method in the _baseMethods hash table, in order for a child
class to call to the base class implementation. The child class has to call to the
callBaseMethod for this, and the implementation of callBaseMethod uses the getBaseMethod
method in order to obtain a reference to the base method.
&lt;/p&gt;
&lt;p&gt;
There is no need to call to the registerBaseMethod if we define our methods using
the prototype because the getBaseMethod searchs the method in the prototype if it
isn’t found in the _baseMethods hash table. 
&lt;/p&gt;
&lt;p&gt;
An example of a class with a method that calls the base method follows:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.C = &lt;span style="COLOR: blue"&gt;function&lt;/span&gt; (a1, a2, b1) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; Manu.Atlas.Tests.C.initializeBase(&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;,
[ a1, a2, b1 ]);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.C.prototype.get_b1 = &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; Manu.Atlas.Tests.C.callBaseMethod(&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;, &lt;span style="COLOR: maroon"&gt;'get_b1'&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.C.prototype.set_b1 = &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; Manu.Atlas.Tests.C.callBaseMethod(&lt;span style="COLOR: blue"&gt;this&lt;/span&gt;, &lt;span style="COLOR: maroon"&gt;'set_b1'&lt;/span&gt;,
[ value ]);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
Manu.Atlas.Tests.C.registerClass(&lt;span style="COLOR: maroon"&gt;'Manu.Atlas.Tests.C'&lt;/span&gt;,
Manu.Atlas.Tests.B);
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The Function built in type is extended with two static functions to help when creating
a class or an interface:&lt;br&gt;
•&amp;nbsp;abstractMethod: method that throws an exception if called.&lt;br&gt;
•&amp;nbsp;emptyFunction: the name says it all.
&lt;/p&gt;
&lt;p&gt;
I’m running out of time now so in another post I’ll finish talking about the OO features
of Atlas.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=c59facc0-301e-4e30-898d-428038828dcd" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,c59facc0-301e-4e30-898d-428038828dcd.aspx</comments>
      <category>Ajax;ASP.NET;JavaScript</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=fa7fe597-9b45-40be-b200-7a30b2f1bdea</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,fa7fe597-9b45-40be-b200-7a30b2f1bdea.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,fa7fe597-9b45-40be-b200-7a30b2f1bdea.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=fa7fe597-9b45-40be-b200-7a30b2f1bdea</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I was going to start posting about Atlas, but as you have probably read <a href="http://weblogs.asp.net/scottgu/archive/2006/09/11/_2200_Atlas_2200_-1.0-Naming-and-Roadmap.aspx">here</a>,
now Atlas has a new name and the next version will have some changes to reflect the
new product name.
</p>
        <p>
I think it is better to wait for a few days to see if a new Atlas version gets released
in order to create samples that work with the latest version. If the next version
does not get released soon I'll start posting about atlas anyway so stay tunned.
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=fa7fe597-9b45-40be-b200-7a30b2f1bdea" />
      </body>
      <title>Atlas stuff</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,fa7fe597-9b45-40be-b200-7a30b2f1bdea.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,fa7fe597-9b45-40be-b200-7a30b2f1bdea.aspx</link>
      <pubDate>Mon, 18 Sep 2006 22:43:29 GMT</pubDate>
      <description>&lt;p&gt;
I was going to start posting about Atlas, but as you have probably read &lt;a href="http://weblogs.asp.net/scottgu/archive/2006/09/11/_2200_Atlas_2200_-1.0-Naming-and-Roadmap.aspx"&gt;here&lt;/a&gt;,
now Atlas has a new name and the next version will have some changes to reflect the
new product name.
&lt;/p&gt;
&lt;p&gt;
I think it is better to wait for a few days to see if a new Atlas version gets released
in order to create samples that work with the latest version. If the next version
does not get released soon I'll start posting about atlas anyway so stay tunned.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=fa7fe597-9b45-40be-b200-7a30b2f1bdea" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,fa7fe597-9b45-40be-b200-7a30b2f1bdea.aspx</comments>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=3579b743-cecb-46a6-9d15-424f3eb971c0</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,3579b743-cecb-46a6-9d15-424f3eb971c0.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,3579b743-cecb-46a6-9d15-424f3eb971c0.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=3579b743-cecb-46a6-9d15-424f3eb971c0</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The NDoc creators where spending a lot of time with the project with very little (if
any) economic reward as it is happening in most open source projects (my personal
experience with <a href="http://www.mame.net/">M.A.M.E.</a> was even worse, because
us (the developers) didn’t get a buck but a lot of people outside the team were getting
tons of money, illegally selling it in cabinets or creating commercial console (or
computer) arcade packs using the MAME source code without permission…) So, they have
discontinued NDoc. 
</p>
        <p>
As Visual Studio 2005 didn’t come with a documentation generator (as Visual Studio
2003 had) this was a big problem for the dot net community, but Microsoft reacted
quickly and created SandCastle, a cool documentation project. The problem is that
SandCastle is in beta stage and it doesn’t have any GUI yet so you have to run several
executables one after another to get the documentation. You can download the current
version here: 
</p>
        <p>
          <a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=E82EA71D-DA89-42EE-A715-696E3A4873B2&amp;displaylang=en">http://www.microsoft.com/downloads/details.aspx?FamilyId=E82EA71D-DA89-42EE-A715-696E3A4873B2&amp;displaylang=en</a>
        </p>
        <p>
And there is a nice blog about information in how to use the executables to get the
documentation done here: 
</p>
        <p>
          <a href="http://blogs.msdn.com/sandcastle">http://blogs.msdn.com/sandcastle</a>
        </p>
        <p>
As most people (myself included) don’t want to spent a lot of time and neurons in
order to build a CHM documentation file, Eric Woodruff has provided a nice GUI that
makes using SandCastle straightforward (and it’s very similar to the one provided
by NDoc): 
</p>
        <p>
          <a href="http://www.codeproject.com/useritems/SandcastleBuilder.asp">http://www.codeproject.com/useritems/SandcastleBuilder.asp</a>
        </p>
        <p>
If you are curious, here you have a screenshot of the generated CHM file using the
most common settings: 
</p>
        <p>
 <img height="549" alt="SandCastle documentation" src="http://www.manuelabadia.com/blog/content/binary/sandcastlesample.jpg" width="792" border="0" /></p>
        <p>
And talking about sandcastles… here are two from my visit to <a href="http://maps.google.com/maps?f=q&amp;hl=en&amp;ie=UTF8&amp;z=16&amp;ll=37.975631,-0.674018&amp;spn=0.011789,0.019784&amp;t=k&amp;om=1">Torrevieja
(Spain) </a>this summer: 
</p>
        <table>
          <tbody>
            <tr>
              <td>
                <img alt="sandcastle" src="http://www.manuelabadia.com/blog/content/binary/sandcastle2.jpg" border="0" />
              </td>
            </tr>
            <tr>
            </tr>
            <img alt="Sandcastle" src="http://www.manuelabadia.com/blog/content/binary/sandcastle1.jpg" border="0" />
            <td>
            </td>
          </tbody>
        </table>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=3579b743-cecb-46a6-9d15-424f3eb971c0" />
      </body>
      <title>NDoc has died… long live to SandCastle! </title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,3579b743-cecb-46a6-9d15-424f3eb971c0.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,3579b743-cecb-46a6-9d15-424f3eb971c0.aspx</link>
      <pubDate>Mon, 04 Sep 2006 22:58:49 GMT</pubDate>
      <description>&lt;p&gt;
The NDoc creators where spending a lot of time with the project with very little (if
any) economic reward as it is happening in most open source projects (my personal
experience with &lt;a href="http://www.mame.net/"&gt;M.A.M.E.&lt;/a&gt; was even worse, because
us (the developers) didn’t get a buck but a lot of people outside the team were getting
tons of money, illegally selling it in cabinets or creating commercial console (or
computer) arcade packs using the MAME source code without permission…) So, they have
discontinued NDoc. 
&lt;/p&gt;
&lt;p&gt;
As Visual Studio 2005 didn’t come with a documentation generator (as Visual Studio
2003 had) this was a big problem for the dot net community, but Microsoft reacted
quickly and created SandCastle, a cool documentation project. The problem is that
SandCastle is in beta stage and it doesn’t have any GUI yet so you have to run several
executables one after another to get the documentation. You can download the current
version here: 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=E82EA71D-DA89-42EE-A715-696E3A4873B2&amp;amp;displaylang=en"&gt;http://www.microsoft.com/downloads/details.aspx?FamilyId=E82EA71D-DA89-42EE-A715-696E3A4873B2&amp;amp;displaylang=en&lt;/a&gt; 
&lt;/p&gt;
&lt;p&gt;
And there is a nice blog about information in how to use the executables to get the
documentation done here: 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.msdn.com/sandcastle"&gt;http://blogs.msdn.com/sandcastle&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
As most people (myself included) don’t want to spent a lot of time and neurons in
order to build a CHM documentation file, Eric Woodruff has provided a nice GUI that
makes using SandCastle straightforward (and it’s very similar to the one provided
by NDoc): 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.codeproject.com/useritems/SandcastleBuilder.asp"&gt;http://www.codeproject.com/useritems/SandcastleBuilder.asp&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
If you are curious, here you have a screenshot of the generated CHM file using the
most common settings: 
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;&lt;img height=549 alt="SandCastle documentation" src="http://www.manuelabadia.com/blog/content/binary/sandcastlesample.jpg" width=792 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
And talking about sandcastles… here are two from my visit to &lt;a href="http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;ie=UTF8&amp;amp;z=16&amp;amp;ll=37.975631,-0.674018&amp;amp;spn=0.011789,0.019784&amp;amp;t=k&amp;amp;om=1"&gt;Torrevieja
(Spain) &lt;/a&gt;this summer: 
&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;img alt=sandcastle src="http://www.manuelabadia.com/blog/content/binary/sandcastle2.jpg" border=0&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&gt;
&lt;img alt=Sandcastle src="http://www.manuelabadia.com/blog/content/binary/sandcastle1.jpg" border=0&gt; 
&lt;td&gt;
&lt;/td&gt;
&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=3579b743-cecb-46a6-9d15-424f3eb971c0" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,3579b743-cecb-46a6-9d15-424f3eb971c0.aspx</comments>
      <category>ASP.NET;General;Microsoft .NET Framework</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=86675dda-afec-4a20-b983-6585b875396f</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,86675dda-afec-4a20-b983-6585b875396f.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,86675dda-afec-4a20-b983-6585b875396f.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=86675dda-afec-4a20-b983-6585b875396f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
As always the holidays seem to be too short, especially after the incident with my
ankle that made me lost 2 weeks. This situation made me spent a lot of time reading
some books I didn’t expect to read until the end of the year or beginning of 2007.
The books I read were related to the new business intelligence features of SQL Server
2005:
</p>
        <table>
          <tbody>
            <tr>
              <td>
                <iframe style="WIDTH: 120px; HEIGHT: 240px" marginwidth="0" marginheight="0" src="http://rcm.amazon.com/e/cm?t=manuelabadias-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0764584359&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000ff&amp;bc1=000000&amp;bg1=ffffff&amp;f=ifr" frameborder="0" scrolling="no">
                </iframe>
              </td>
              <td>
                <iframe style="WIDTH: 120px; HEIGHT: 240px" marginwidth="0" marginheight="0" src="http://rcm.amazon.com/e/cm?t=manuelabadias-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0764584979&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000ff&amp;bc1=000000&amp;bg1=ffffff&amp;f=ifr" frameborder="0" scrolling="no">
                </iframe>
              </td>
              <td>
                <iframe style="WIDTH: 120px; HEIGHT: 240px" marginwidth="0" marginheight="0" src="http://rcm.amazon.com/e/cm?t=manuelabadias-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0764579185&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000ff&amp;bc1=000000&amp;bg1=ffffff&amp;f=ifr" frameborder="0" scrolling="no">
                </iframe>
              </td>
            </tr>
          </tbody>
        </table>
        <p>
In general terms the books were good, although in my opinion the part that talks about
creating custom integration services components was too short. I haven’t finished
the book about analysis services (I only read the first 9 chapters) and will not do
it yet. The books assumes that you have a data warehouse to use as a base for analysis
services but it didn’t explain how to build one so I think I’ll have to buy a good
book about that. I have been told that The Microsoft Data Warehouse Toolkit does a
good job so I’ll be purchasing it as soon as possible. 
</p>
        <table>
          <tbody>
            <tr>
              <td>
                <iframe style="WIDTH: 120px; HEIGHT: 240px" marginwidth="0" marginheight="0" src="http://rcm.amazon.com/e/cm?t=manuelabadias-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0471267155&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000ff&amp;bc1=000000&amp;bg1=ffffff&amp;f=ifr" frameborder="0" scrolling="no">
                </iframe>
              </td>
            </tr>
          </tbody>
        </table>
        <p>
Something that I’m still thinking is how easily Reporting Services has become a better
product than Crystal Reports even the second one has a lot of years in the market. 
</p>
        <p>
I’m interested in seeing what comes up when I put everything to work in a real project…
</p>
        <p>
I’ll start to look deeply into Atlas this month so I hope I can find some free time
to post some detailed posts about it.
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=86675dda-afec-4a20-b983-6585b875396f" />
      </body>
      <title>Back to work...</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,86675dda-afec-4a20-b983-6585b875396f.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,86675dda-afec-4a20-b983-6585b875396f.aspx</link>
      <pubDate>Fri, 01 Sep 2006 21:19:56 GMT</pubDate>
      <description>&lt;p&gt;
As always the holidays seem to be too short, especially after the incident with my
ankle that made me lost 2 weeks. This situation made me spent a lot of time reading
some books I didn’t expect to read until the end of the year or beginning of 2007.
The books I read were related to the new business intelligence features of SQL Server
2005:
&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;iframe style="WIDTH: 120px; HEIGHT: 240px" marginwidth=0 marginheight=0 src="http://rcm.amazon.com/e/cm?t=manuelabadias-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=0764584359&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;lc1=0000ff&amp;amp;bc1=000000&amp;amp;bg1=ffffff&amp;amp;f=ifr" frameborder=0 scrolling=no&gt;
&lt;/iframe&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;iframe style="WIDTH: 120px; HEIGHT: 240px" marginwidth=0 marginheight=0 src="http://rcm.amazon.com/e/cm?t=manuelabadias-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=0764584979&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;lc1=0000ff&amp;amp;bc1=000000&amp;amp;bg1=ffffff&amp;amp;f=ifr" frameborder=0 scrolling=no&gt;
&lt;/iframe&gt;
&lt;/td&gt;
&lt;td&gt;
&lt;iframe style="WIDTH: 120px; HEIGHT: 240px" marginwidth=0 marginheight=0 src="http://rcm.amazon.com/e/cm?t=manuelabadias-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=0764579185&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;lc1=0000ff&amp;amp;bc1=000000&amp;amp;bg1=ffffff&amp;amp;f=ifr" frameborder=0 scrolling=no&gt;
&lt;/iframe&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
In general terms the books were good, although in my opinion the part that talks about
creating custom integration services components was too short. I haven’t finished
the book about analysis services (I only read the first 9 chapters) and will not do
it yet. The books assumes that you have a data warehouse to use as a base for analysis
services but it didn’t explain how to build one so I think I’ll have to buy a good
book about that. I have been told that The Microsoft Data Warehouse Toolkit does a
good job so I’ll be purchasing it as soon as possible. 
&lt;/p&gt;
&lt;table&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;
&lt;iframe style="WIDTH: 120px; HEIGHT: 240px" marginwidth=0 marginheight=0 src="http://rcm.amazon.com/e/cm?t=manuelabadias-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=0471267155&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;lc1=0000ff&amp;amp;bc1=000000&amp;amp;bg1=ffffff&amp;amp;f=ifr" frameborder=0 scrolling=no&gt;
&lt;/iframe&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;
Something that I’m still thinking is how easily Reporting Services has become a better
product than Crystal Reports even the second one has a lot of years in the market. 
&lt;/p&gt;
&lt;p&gt;
I’m interested in seeing what comes up when I put everything to work in a real project…
&lt;/p&gt;
&lt;p&gt;
I’ll start to look deeply into Atlas this month so I hope I can find some free time
to post some detailed posts about it.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=86675dda-afec-4a20-b983-6585b875396f" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,86675dda-afec-4a20-b983-6585b875396f.aspx</comments>
      <category>ASP.NET;General</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=50357538-0c5b-49a0-adcf-519abe293110</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,50357538-0c5b-49a0-adcf-519abe293110.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,50357538-0c5b-49a0-adcf-519abe293110.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=50357538-0c5b-49a0-adcf-519abe293110</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I'm going on vacation until the end of august. 
</p>
        <p>
I'll be <a href="http://maps.google.com/maps?f=q&amp;hl=en&amp;ie=UTF8&amp;om=1&amp;ll=37.914951,-0.727844&amp;spn=0.189057,0.3162&amp;t=h">here</a> and <a href="http://maps.google.com/maps?f=q&amp;hl=en&amp;ie=UTF8&amp;om=1&amp;t=h&amp;ll=37.668875,-0.713768&amp;spn=0.189688,0.3162">here</a> most
of the time.
</p>
        <p>
Unfortunately I don't have internet access available but I'll be checking my email
from time to time.
</p>
        <p>
Of course I take a computer with me so I'll be learning something new this holidays
(maybe Atlas or SSIS). 
</p>
        <p>
If you can understand portuguese I recommend you to take a look at <a href="http://weblogs.pontonetpt.com/luisabreu/">Luis
Abreu's webcasts about Atlas</a>. 
</p>
        <p>
Have a nice month ;-)
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=50357538-0c5b-49a0-adcf-519abe293110" />
      </body>
      <title>The next month</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,50357538-0c5b-49a0-adcf-519abe293110.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,50357538-0c5b-49a0-adcf-519abe293110.aspx</link>
      <pubDate>Mon, 31 Jul 2006 07:59:24 GMT</pubDate>
      <description>&lt;p&gt;
I'm going on vacation until the end of august. 
&lt;/p&gt;
&lt;p&gt;
I'll be &lt;a href="http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;ie=UTF8&amp;amp;om=1&amp;amp;ll=37.914951,-0.727844&amp;amp;spn=0.189057,0.3162&amp;amp;t=h"&gt;here&lt;/a&gt; and &lt;a href="http://maps.google.com/maps?f=q&amp;amp;hl=en&amp;amp;ie=UTF8&amp;amp;om=1&amp;amp;t=h&amp;amp;ll=37.668875,-0.713768&amp;amp;spn=0.189688,0.3162"&gt;here&lt;/a&gt; most
of the time.
&lt;/p&gt;
&lt;p&gt;
Unfortunately I don't have internet access available but I'll be checking my email
from time to time.
&lt;/p&gt;
&lt;p&gt;
Of course I take a computer with me so I'll be learning something new this holidays
(maybe Atlas or SSIS). 
&lt;/p&gt;
&lt;p&gt;
If you can understand portuguese I recommend you to take a look at &lt;a href="http://weblogs.pontonetpt.com/luisabreu/"&gt;Luis
Abreu's webcasts about Atlas&lt;/a&gt;. 
&lt;/p&gt;
&lt;p&gt;
Have a nice month ;-)
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=50357538-0c5b-49a0-adcf-519abe293110" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,50357538-0c5b-49a0-adcf-519abe293110.aspx</comments>
      <category>ASP.NET;General</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=7cef4a16-10ec-44e5-8f3c-36a977b8f00c</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,7cef4a16-10ec-44e5-8f3c-36a977b8f00c.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,7cef4a16-10ec-44e5-8f3c-36a977b8f00c.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=7cef4a16-10ec-44e5-8f3c-36a977b8f00c</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
The last post completed what I wanted to explain about data source controls. 
</p>
        <p>
As a summary, here is a full list of the posts about data source controls of the last
months:
</p>
        <p>
I explained the generalities of data source controls here:<br />
* <a href="http://www.manuelabadia.com/blog/PermaLink,guid,678ed6d8-dce8-40d7-9117-0ffd016fe886.aspx">Data
Source Controls - Under the hood (1/4)</a><br />
* <a href="http://www.manuelabadia.com/blog/PermaLink,guid,eba2bb6b-7006-41ae-a035-532021eb5f42.aspx">Data
Source Controls - Under the hood (2/4)<br /></a>* <a href="http://www.manuelabadia.com/blog/PermaLink,guid,e4f162b4-2adb-46d7-9d31-be32ff9b1347.aspx">Data
Source Controls - Under the hood (3/4)</a><br />
* <a href="http://www.manuelabadia.com/blog/PermaLink,guid,45f5c9da-8a03-423f-b5b6-5882c4bd67e5.aspx">Data
Source Controls - Under the hood (4/4)</a></p>
        <p>
The theory about designers is here:<br />
* <a href="http://www.manuelabadia.com/blog/PermaLink,guid,8ef94d79-dde8-49a0-9656-a61b035545ab.aspx">Introduction
to designers</a><br />
* <a href="http://www.manuelabadia.com/blog/PermaLink,guid,15d02a1d-c53f-48ad-be58-ff442f1faa1e.aspx">ASP.NET
designers. The ControlDesigner class</a><br />
* <a href="http://www.manuelabadia.com/blog/PermaLink,guid,187f0155-1b64-45ea-8138-6105e9cd6295.aspx">ASP.NET
designers. The DataSourceDesigner class</a><br />
* <a href="http://www.manuelabadia.com/blog/PermaLink,guid,e5d64c7a-2380-4708-875b-9e24872d4f83.aspx">DataSourceDesigners...
Non visual controls?</a></p>
        <p>
A custom data source control sample with full design time support:<br />
* <a href="http://www.manuelabadia.com/blog/PermaLink,guid,5a03e8da-fd85-4aed-8c3f-298086f5c153.aspx">A
custom DataSourceControl sample</a><br />
* <a href="http://www.manuelabadia.com/blog/PermaLink,guid,4b487b09-3bdc-498d-ab38-f0eccad54357.aspx">Creating
a custom DataSourceDesigner</a></p>
        <p>
I hope you find them useful.
</p>
        <p>
        </p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=7cef4a16-10ec-44e5-8f3c-36a977b8f00c" />
      </body>
      <title>DataSourceControls summary</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,7cef4a16-10ec-44e5-8f3c-36a977b8f00c.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,7cef4a16-10ec-44e5-8f3c-36a977b8f00c.aspx</link>
      <pubDate>Wed, 26 Jul 2006 16:42:13 GMT</pubDate>
      <description>&lt;p&gt;
The last post completed what I wanted to explain about data source controls. 
&lt;/p&gt;
&lt;p&gt;
As a summary, here is a full list of the posts about data source controls of the last
months:
&lt;/p&gt;
&lt;p&gt;
I explained the generalities of data source controls here:&lt;br&gt;
* &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,678ed6d8-dce8-40d7-9117-0ffd016fe886.aspx"&gt;Data
Source Controls - Under the hood (1/4)&lt;/a&gt;
&lt;br&gt;
* &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,eba2bb6b-7006-41ae-a035-532021eb5f42.aspx"&gt;Data
Source Controls - Under the hood (2/4)&lt;br&gt;
&lt;/a&gt;* &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,e4f162b4-2adb-46d7-9d31-be32ff9b1347.aspx"&gt;Data
Source Controls - Under the hood (3/4)&lt;/a&gt;
&lt;br&gt;
* &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,45f5c9da-8a03-423f-b5b6-5882c4bd67e5.aspx"&gt;Data
Source Controls - Under the hood (4/4)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
The theory about designers is here:&lt;br&gt;
* &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,8ef94d79-dde8-49a0-9656-a61b035545ab.aspx"&gt;Introduction
to designers&lt;/a&gt;
&lt;br&gt;
* &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,15d02a1d-c53f-48ad-be58-ff442f1faa1e.aspx"&gt;ASP.NET
designers. The ControlDesigner class&lt;/a&gt;
&lt;br&gt;
* &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,187f0155-1b64-45ea-8138-6105e9cd6295.aspx"&gt;ASP.NET
designers. The DataSourceDesigner class&lt;/a&gt;
&lt;br&gt;
* &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,e5d64c7a-2380-4708-875b-9e24872d4f83.aspx"&gt;DataSourceDesigners...
Non visual controls?&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
A custom data source control sample with full design time support:&lt;br&gt;
* &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,5a03e8da-fd85-4aed-8c3f-298086f5c153.aspx"&gt;A
custom DataSourceControl sample&lt;/a&gt;
&lt;br&gt;
* &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,4b487b09-3bdc-498d-ab38-f0eccad54357.aspx"&gt;Creating
a custom DataSourceDesigner&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
I hope you find them useful.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=7cef4a16-10ec-44e5-8f3c-36a977b8f00c" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,7cef4a16-10ec-44e5-8f3c-36a977b8f00c.aspx</comments>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=4b487b09-3bdc-498d-ab38-f0eccad54357</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,4b487b09-3bdc-498d-ab38-f0eccad54357.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,4b487b09-3bdc-498d-ab38-f0eccad54357.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=4b487b09-3bdc-498d-ab38-f0eccad54357</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
We will create a designer for the CustomDataSource we created <a href="http://www.manuelabadia.com/blog/PermaLink,guid,5a03e8da-fd85-4aed-8c3f-298086f5c153.aspx">here</a>.
</p>
        <p>
As we explained in a previous post about the <a href="http://www.manuelabadia.com/blog/PermaLink,guid,187f0155-1b64-45ea-8138-6105e9cd6295.aspx">DataSourceDesigner
class</a>, the main tasks that have to be performed by a DataSourceDesigner are:<br />
• configuring the data source<br />
• exposing schema information
</p>
        <p>
Also, we have to expose at least one DesignerDataSourceView (A DataSource control
exposes one or more DataSourceViews and a DataSourceDesigner exposes one or more DesignerDataSourceViews):
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        private</span>
            <span style="COLOR: blue">static</span>
            <span style="COLOR: blue">readonly</span>
            <span style="COLOR: blue">string</span>[]
_views = { <span style="COLOR: maroon">"DefaultView"</span> };
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">public</span><span style="COLOR: blue">override</span><span style="COLOR: teal">DesignerDataSourceView</span> GetView(<span style="COLOR: blue">string</span> viewName)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> ((viewName
== <span style="COLOR: blue">null</span>) || ((viewName.Length != 0) &amp;&amp; (<span style="COLOR: teal">String</span>.Compare(viewName, <span style="COLOR: maroon">"DefaultView"</span>, <span style="COLOR: teal">StringComparison</span>.OrdinalIgnoreCase)
!= 0))){
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">throw</span><span style="COLOR: blue">new</span><span style="COLOR: teal">ArgumentException</span>(<span style="COLOR: maroon">"An
invalid view was requested"</span>, <span style="COLOR: maroon">"viewName"</span>);
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">return</span> View;
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">public</span><span style="COLOR: blue">override</span><span style="COLOR: blue">string</span>[]
GetViewNames()
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">return</span> _views;
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
        </div>
        <!--EndFragment-->
        <p>
As you can see the code is very similar to the one used in the custom data source
to expose the custom data source view. As our data source will only retrieve data,
the default implementation of the DesignerDataSourceView is enough for all CanXXX
properties.
</p>
        <p>
In order to quickly configure our custom DataSource we’ll provide a GUI
that will let us choose the TypeName and the SelectMethod using DropDownLists:
</p>
        <p>
          <img src="http://www.manuelabadia.com/blog/content/binary/ConfigDataSource.png" border="0" />
        </p>
        <p>
In order to be able to show the Configure Data Source dialog we need to override the
CanConfigure property and implement the Configure method:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        public</span>
            <span style="COLOR: blue">override</span>
            <span style="COLOR: blue">bool</span> CanConfigure
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span><span style="COLOR: blue">true</span>;
}
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">public</span><span style="COLOR: blue">override</span><span style="COLOR: blue">void</span> Configure()
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            _inWizard = <span style="COLOR: blue">true</span>;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
generate a transaction to undo changes</span></p>
          <p style="MARGIN: 0px">
            InvokeTransactedChange(Component, <span style="COLOR: blue">new</span><span style="COLOR: teal">TransactedChangeCallback</span>(ConfigureDataSourceCallback), <span style="COLOR: blue">null</span>, <span style="COLOR: maroon">"ConfigureDataSource"</span>);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            _inWizard = <span style="COLOR: blue">false</span>;
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">protected</span><span style="COLOR: blue">virtual</span><span style="COLOR: blue">bool</span> ConfigureDataSourceCallback(<span style="COLOR: blue">object</span> context)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">try</span> {
</p>
          <p style="MARGIN: 0px">
                SuppressDataSourceEvents();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: teal">IServiceProvider</span> provider
= Component.Site;
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">if</span> (provider
== <span style="COLOR: blue">null</span>){
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span><span style="COLOR: blue">false</span>;
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: green">//
get the service needed to show a form</span></p>
          <p style="MARGIN: 0px">
                <span style="COLOR: teal">IUIService</span> UIService
= (<span style="COLOR: teal">IUIService</span>) provider.GetService(<span style="COLOR: blue">typeof</span>(<span style="COLOR: teal">IUIService</span>));
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">if</span> (UIService
== <span style="COLOR: blue">null</span>){
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span><span style="COLOR: blue">false</span>;
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: green">//
shows the form</span></p>
          <p style="MARGIN: 0px">
                <span style="COLOR: teal">ConfigureDataSource</span> configureForm
= <span style="COLOR: blue">new</span><span style="COLOR: teal">ConfigureDataSource</span>(provider, <span style="COLOR: blue">this</span>);
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">if</span> (UIService.ShowDialog(configureForm)
== <span style="COLOR: teal">DialogResult</span>.OK){
</p>
          <p style="MARGIN: 0px">
                   
OnDataSourceChanged(<span style="COLOR: teal">EventArgs</span>.Empty);
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span><span style="COLOR: blue">true</span>;
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            } <span style="COLOR: blue">finally</span> {
</p>
          <p style="MARGIN: 0px">
                ResumeDataSourceEvents();
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">return</span><span style="COLOR: blue">false</span>;
</p>
          <p style="MARGIN: 0px">
        }
</p>
        </div>
        <p>
As the GUI will change several properties at a time we have to create a transacted
change in order to provide undo functionality.
</p>
        <p>
The form fills the first dropdownlist with all available types using the type discovery
service instead of reflection. Why? Because using reflection we can only get all types
of the compiled assemblies. However, we can add more types without having compiled
the project or we can have types that don’t compile and the type discovery service
will also show them, so it is a lot better to use the type discovery service instead
of reflection.
</p>
        <p>
In the code we haven’t removed types that probably will not be candidates for our
TypeName property (generic types, interfaces) in order to keep code as simple as possible:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        private</span>
            <span style="COLOR: blue">void</span> DiscoverTypes()
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
try to get a reference to the type discovery service</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">ITypeDiscoveryService</span> discovery
= <span style="COLOR: blue">null</span>;
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> (_component.Site
!= <span style="COLOR: blue">null</span>) {
</p>
          <p style="MARGIN: 0px">
                discovery
= (<span style="COLOR: teal">ITypeDiscoveryService</span>)_component.Site.GetService(<span style="COLOR: blue">typeof</span>(<span style="COLOR: teal">ITypeDiscoveryService</span>));
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
if the type discovery service is available</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> (discovery
!= <span style="COLOR: blue">null</span>) {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: green">//
saves the cursor and sets the wait cursor</span></p>
          <p style="MARGIN: 0px">
                <span style="COLOR: teal">Cursor</span> previousCursor
= <span style="COLOR: teal">Cursor</span>.Current;
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: teal">Cursor</span>.Current
= <span style="COLOR: teal">Cursors</span>.WaitCursor;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">try</span> {
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: green">//
gets all types using the type discovery service</span></p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: teal">ICollection</span> types
= discovery.GetTypes(<span style="COLOR: blue">typeof</span>(<span style="COLOR: blue">object</span>), <span style="COLOR: blue">true</span>);
</p>
          <p style="MARGIN: 0px">
                   
ddlTypes.BeginUpdate();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                   
ddlTypes.Items.Clear();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: green">//
adds the types to the list</span></p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">foreach</span> (<span style="COLOR: teal">Type</span> type <span style="COLOR: blue">in</span> types)
{
</p>
          <p style="MARGIN: 0px">
                   
    <span style="COLOR: teal">TypeItem</span> typeItem = <span style="COLOR: blue">new</span><span style="COLOR: teal">TypeItem</span>(type);
</p>
          <p style="MARGIN: 0px">
                   
    ddlTypes.Items.Add(typeItem);
</p>
          <p style="MARGIN: 0px">
                   
}
</p>
          <p style="MARGIN: 0px">
                } <span style="COLOR: blue">finally</span> {
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: teal">Cursor</span>.Current
= previousCursor;
</p>
          <p style="MARGIN: 0px">
                   
ddlTypes.EndUpdate();
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
        }
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
The TypeItem class is a class used to store types in the dropdownlist.
</p>
        <p>
When a type is selected from the first dropdownlist, the other dropdownlist gets populated
with the methods of the selected type:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        private</span>
            <span style="COLOR: blue">void</span> FillMethods()
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
saves the cursor and sets the wait cursor</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">Cursor</span> previousCursor
= <span style="COLOR: teal">Cursor</span>.Current;
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">Cursor</span>.Current
= <span style="COLOR: teal">Cursors</span>.WaitCursor;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">try</span> {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
gets all public methods (instance + static)</span></p>
          <p style="MARGIN: 0px">
                <span style="COLOR: teal">MethodInfo</span>[]
methods = <span style="COLOR: teal">CustomDataSourceDesigner</span>.GetType(_component.Site,
TypeName).GetMethods(<span style="COLOR: teal">BindingFlags</span>.Public | <span style="COLOR: teal">BindingFlags</span>.Static
| <span style="COLOR: teal">BindingFlags</span>.Instance | <span style="COLOR: teal">BindingFlags</span>.FlattenHierarchy);
</p>
          <p style="MARGIN: 0px">
                ddlMethods.BeginUpdate();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                ddlMethods.Items.Clear();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: green">//
adds the methods to the dropdownlist</span></p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">foreach</span> (<span style="COLOR: teal">MethodInfo</span> method <span style="COLOR: blue">in</span> methods)
{
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: teal">MethodItem</span> methodItem
= <span style="COLOR: blue">new</span><span style="COLOR: teal">MethodItem</span>(method);
</p>
          <p style="MARGIN: 0px">
                   
ddlMethods.Items.Add(methodItem);
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
            } <span style="COLOR: blue">finally</span> {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: teal">Cursor</span>.Current
= previousCursor;
</p>
          <p style="MARGIN: 0px">
                ddlMethods.EndUpdate();
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
        </div>
        <!--EndFragment-->
        <p>
To quickly get and set the TypeName and the SelectMethod from and to the form we have
defined those properties in the form as follows:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        internal</span>
            <span style="COLOR: blue">string</span> TypeName
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">get</span> {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: green">//
gets the selected type</span></p>
          <p style="MARGIN: 0px">
                <span style="COLOR: teal">TypeItem</span> selectedType
= ddlTypes.SelectedItem <span style="COLOR: blue">as</span><span style="COLOR: teal">TypeItem</span>;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: green">//
return the selected type</span></p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">if</span> (selectedType
!= <span style="COLOR: blue">null</span>){
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span> selectedType.Name;
</p>
          <p style="MARGIN: 0px">
                } <span style="COLOR: blue">else</span> {
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span><span style="COLOR: teal">String</span>.Empty;
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">set</span> {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: green">//
iterate through all the types searching for the requested type</span></p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">foreach</span> (<span style="COLOR: teal">TypeItem</span> item <span style="COLOR: blue">in</span> ddlTypes.Items){
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: green">//
if we have found it, select it</span></p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">if</span> (<span style="COLOR: teal">String</span>.Compare(item.Name, <span style="COLOR: blue">value</span>, <span style="COLOR: blue">true</span>)
== 0) {
</p>
          <p style="MARGIN: 0px">
                   
    ddlTypes.SelectedItem = item;
</p>
          <p style="MARGIN: 0px">
                   
    <span style="COLOR: blue">break</span>;
</p>
          <p style="MARGIN: 0px">
                   
}
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">internal</span><span style="COLOR: blue">string</span> SelectMethod
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">get</span> {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: green">//
gets the select method</span></p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">string</span> methodName
= <span style="COLOR: teal">String</span>.Empty;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">if</span> (MethodInfo
!= <span style="COLOR: blue">null</span>) {
</p>
          <p style="MARGIN: 0px">
                   
methodName = MethodInfo.Name;
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">return</span> methodName;
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">set</span>   
{
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: green">//
iterate through all the types searching for the requested type</span></p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">foreach</span> (<span style="COLOR: teal">MethodItem</span> item <span style="COLOR: blue">in</span> ddlMethods.Items)
{
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: green">//
if we have found it, select it</span></p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">if</span> (<span style="COLOR: teal">String</span>.Compare(item.MethodInfo.Name, <span style="COLOR: blue">value</span>, <span style="COLOR: blue">true</span>)
== 0) {
</p>
          <p style="MARGIN: 0px">
                   
    ddlMethods.SelectedItem = item;
</p>
          <p style="MARGIN: 0px">
                   
    <span style="COLOR: blue">break</span>;
</p>
          <p style="MARGIN: 0px">
                   
}
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">internal</span><span style="COLOR: teal">MethodInfo</span> MethodInfo
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">get</span> {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: teal">MethodItem</span> item
= ddlMethods.SelectedItem <span style="COLOR: blue">as</span><span style="COLOR: teal">MethodItem</span>;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">if</span> (item
== <span style="COLOR: blue">null</span>) {
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span><span style="COLOR: blue">null</span>;
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">return</span> item.MethodInfo;
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
        }
</p>
        </div>
        <!--EndFragment-->
        <p>
          <br />
          <br />
Note that to simplify code when the SelectMethod property is set, the selected method
from the dropdownlist will be the first method with the same name as the SelectMethod
(no parameters are checked to simplify code, but for production code you’ll probably
want to check that the parameters match). 
</p>
        <p>
In the FillMethods method, the type is obtained using the GetType method that used
the resolution service (for the same reasons we specified before for using the type
discovery service). In order to simplify the code we have not removed some methods
that certainly will not be the proper method like property getters and setters or
abstract methods.
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        internal</span>
            <span style="COLOR: blue">static</span>
            <span style="COLOR: teal">Type</span> GetType(<span style="COLOR: teal">IServiceProvider</span> serviceProvider, <span style="COLOR: blue">string</span> typeName)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
try to get a reference to the resolution service</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">ITypeResolutionService</span> resolution
= (<span style="COLOR: teal">ITypeResolutionService</span>)serviceProvider.GetService(<span style="COLOR: blue">typeof</span>(<span style="COLOR: teal">ITypeResolutionService</span>));
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> (resolution
== <span style="COLOR: blue">null</span>) {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">return</span><span style="COLOR: blue">null</span>;
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
try to get the type</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">return</span> resolution.GetType(typeName, <span style="COLOR: blue">false</span>, <span style="COLOR: blue">true</span>);
</p>
          <p style="MARGIN: 0px">
        }
</p>
        </div>
        <!--EndFragment-->
        <p>
When the user clicks the Accept button in the Configure data source form, the code
that gets executed is:<br /></p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        private</span>
            <span style="COLOR: blue">void</span> bOK_Click(<span style="COLOR: blue">object</span> sender, <span style="COLOR: teal">EventArgs</span> e)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
if the type has changed, save it</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> (<span style="COLOR: teal">String</span>.Compare(TypeName,
_component.TypeName, <span style="COLOR: blue">false</span>) != 0) {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: teal">TypeDescriptor</span>.GetProperties(_component)[<span style="COLOR: maroon">"TypeName"</span>].SetValue(_component,
TypeName);
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
if the select method has changed, save it</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> (<span style="COLOR: teal">String</span>.Compare(SelectMethod,
_component.SelectMethod, <span style="COLOR: blue">false</span>) != 0) {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: teal">TypeDescriptor</span>.GetProperties(_component)[<span style="COLOR: maroon">"SelectMethod"</span>].SetValue(_component,
SelectMethod);
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
if there is method selected, refresh the schema</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> (MethodInfo
!= <span style="COLOR: blue">null</span>) {
</p>
          <p style="MARGIN: 0px">
                _designer.RefreshSchemaInternal(MethodInfo.ReflectedType,
MethodInfo.Name, MethodInfo.ReturnType, <span style="COLOR: blue">true</span>);
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
        }
</p>
        </div>
        <!--EndFragment-->
        <p>
We save the Type and the SelectMethod and refresh the schema.
</p>
        <p>
To provide schema information, we have to return true in the CanRefreshSchema method
and we have to implement the RefreshSchema method. When we provide schema information
the controls can provide field pickers (i.e. columns for a GridView) and generate
templates based on the schema information (i.e. a DataList bound to our data source
control). However, we can not return true for the CanRefreshSchema, because we can
return schema information only if the user has configured the data source:<br /></p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        public</span>
            <span style="COLOR: blue">override</span>
            <span style="COLOR: blue">bool</span> CanRefreshSchema
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">get</span>   
{
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: green">//
if a type and the select method have been specified, the schema can be refreshed</span></p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">if</span> (!<span style="COLOR: teal">String</span>.IsNullOrEmpty(TypeName)
&amp;&amp; !<span style="COLOR: teal">String</span>.IsNullOrEmpty(SelectMethod)) {
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span><span style="COLOR: blue">true</span>;
</p>
          <p style="MARGIN: 0px">
                } <span style="COLOR: blue">else</span> {
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span><span style="COLOR: blue">false</span>;
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
        }
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
To implement the RefreshSchema method, we need to extract the schema information and
generate the SchemaRefreshed event. If a data source control can provide schema information,
the schema information will be retrieved from the property Schema from the underlying
DesignerDataSourceView. However, the SchemaRefreshed event doesn’t have to be raised
everytime, only if the data source returns a different schema. To see why this is
important think about this: if the data source is bound to a GridView, every time
the RefreshSchema event is raised, the designer will ask if it has to regenerate the
columns and the data keys. So we’re interested in raising the SchemaRefreshed event
only when the schema changes. We use the designer state to store the previous schema,
and when the RefreshSchema method is called, we will check if the schema has changed,
raising the SchemaRefreshed event only in that case.
</p>
        <p>
The code related to the RefreshSchema method is:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        internal</span>
            <span style="COLOR: teal">IDataSourceViewSchema</span> DataSourceSchema
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> DesignerState[<span style="COLOR: maroon">"DataSourceSchema"</span>] <span style="COLOR: blue">as</span><span style="COLOR: teal">IDataSourceViewSchema</span>;
}
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">set</span> {
DesignerState[<span style="COLOR: maroon">"DataSourceSchema"</span>] = <span style="COLOR: blue">value</span>;
}
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">public</span><span style="COLOR: blue">override</span><span style="COLOR: blue">void</span> RefreshSchema(<span style="COLOR: blue">bool</span> preferSilent)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
saves the old cursor</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">Cursor</span> oldCursor
= <span style="COLOR: teal">Cursor</span>.Current;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">try</span> {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: green">//
ignore data source events while refreshing the schema</span></p>
          <p style="MARGIN: 0px">
                SuppressDataSourceEvents();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">try</span> {
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: teal">Cursor</span>.Current
= <span style="COLOR: teal">Cursors</span>.WaitCursor;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: green">//
gets the Type used in the DataSourceControl</span></p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: teal">Type</span> type
= GetType(Component.Site, TypeName);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: green">//
if we can't find the type, return</span></p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">if</span> (type
== <span style="COLOR: blue">null</span>) {
</p>
          <p style="MARGIN: 0px">
                   
    <span style="COLOR: blue">return</span>;
</p>
          <p style="MARGIN: 0px">
                   
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: green">//
get all the methods that can be used as the select method</span></p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: teal">MethodInfo</span>[]
methods = type.GetMethods(<span style="COLOR: teal">BindingFlags</span>.FlattenHierarchy
| <span style="COLOR: teal">BindingFlags</span>.Static | <span style="COLOR: teal">BindingFlags</span>.Instance
| <span style="COLOR: teal">BindingFlags</span>.Public);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: teal">MethodInfo</span> selectedMethod
= <span style="COLOR: blue">null</span>;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: green">//
iterates through the methods searching for the select method</span></p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">foreach</span> (<span style="COLOR: teal">MethodInfo</span> method <span style="COLOR: blue">in</span> methods)
{
</p>
          <p style="MARGIN: 0px">
                   
    <span style="COLOR: green">// if the method is named as the selected
method, select it</span></p>
          <p style="MARGIN: 0px">
                   
    <span style="COLOR: blue">if</span> (IsMatchingMethod(method, SelectMethod))
{
</p>
          <p style="MARGIN: 0px">
                   
        selectedMethod = method;
</p>
          <p style="MARGIN: 0px">
                   
        <span style="COLOR: blue">break</span>;
</p>
          <p style="MARGIN: 0px">
                   
    }
</p>
          <p style="MARGIN: 0px">
                   
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: green">//
if the SelectMethod was found, save the type information</span></p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">if</span> (selectedMethod
!= <span style="COLOR: blue">null</span>) {
</p>
          <p style="MARGIN: 0px">
                   
    RefreshSchemaInternal(type, selectedMethod.Name, selectedMethod.ReturnType,
preferSilent);
</p>
          <p style="MARGIN: 0px">
                   
}
</p>
          <p style="MARGIN: 0px">
                } <span style="COLOR: blue">finally</span> {
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: green">//
restores the cursor</span></p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: teal">Cursor</span>.Current
= oldCursor;
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
            } <span style="COLOR: blue">finally</span> {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: green">//
resume data source events</span></p>
          <p style="MARGIN: 0px">
                ResumeDataSourceEvents();
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">internal</span><span style="COLOR: blue">void</span> RefreshSchemaInternal(<span style="COLOR: teal">Type</span> typeName, <span style="COLOR: blue">string</span> method, <span style="COLOR: teal">Type</span> returnType, <span style="COLOR: blue">bool</span> preferSilent)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
if all parameters are filled</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> ((typeName
!= <span style="COLOR: blue">null</span>) &amp;&amp; (!<span style="COLOR: teal">String</span>.IsNullOrEmpty(method))
&amp;&amp; (returnType != <span style="COLOR: blue">null</span>)) {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">try</span> {
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: green">//
gets the old schema</span></p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: teal">IDataSourceViewSchema</span> oldSchema
= DataSourceSchema;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: green">//
gets the schema of the return type</span></p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: teal">IDataSourceViewSchema</span>[]
typeSchemas = <span style="COLOR: blue">new</span><span style="COLOR: teal">TypeSchema</span>(returnType).GetViews();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: green">//
if we can't get schema information from the type, exit</span></p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">if</span> ((typeSchemas
== <span style="COLOR: blue">null</span>) || (typeSchemas.Length == 0)){
</p>
          <p style="MARGIN: 0px">
                   
    DataSourceSchema = <span style="COLOR: blue">null</span>;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                   
    <span style="COLOR: blue">return</span>;
</p>
          <p style="MARGIN: 0px">
                   
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: green">//
get a view of the schema</span></p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: teal">IDataSourceViewSchema</span> newSchema
= typeSchemas[0];
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: green">//
if the schema has changed, raise the schema refreshed event</span></p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">if</span> (!<span style="COLOR: teal">DataSourceDesigner</span>.ViewSchemasEquivalent(oldSchema,
newSchema)){
</p>
          <p style="MARGIN: 0px">
                   
    DataSourceSchema = newSchema;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                   
    OnSchemaRefreshed(<span style="COLOR: teal">EventArgs</span>.Empty);
</p>
          <p style="MARGIN: 0px">
                   
}
</p>
          <p style="MARGIN: 0px">
                } <span style="COLOR: blue">catch</span> (<span style="COLOR: teal">Exception</span> e){
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">if</span> (!preferSilent){
</p>
          <p style="MARGIN: 0px">
                   
    ShowError(DataSourceComponent.Site, <span style="COLOR: maroon">"Cannot
retrieve type schema for "</span> + returnType.FullName + <span style="COLOR: maroon">".
"</span> + e.Message);
</p>
          <p style="MARGIN: 0px">
                   
}
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
        }
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
As you can see, we get the MethodInfo for the SelectMethod and get the return type.
All hard work to expose schema information is done by the framework helper class TypeSchema
that was explained in the post about DataSourceDesigners. The DesignerDataSource view
exposes the saved schema:<br /></p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        public</span>
            <span style="COLOR: blue">override</span>
            <span style="COLOR: teal">IDataSourceViewSchema</span> Schema 
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">get</span> { 
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: green">//
if a type and the select method have been specified, the schema information is available</span></p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">if</span> (!<span style="COLOR: teal">String</span>.IsNullOrEmpty(_owner.TypeName)
&amp;&amp; !<span style="COLOR: teal">String</span>.IsNullOrEmpty(_owner.SelectMethod))
{
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span> _owner.DataSourceSchema;
</p>
          <p style="MARGIN: 0px">
                } <span style="COLOR: blue">else</span> {
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span><span style="COLOR: blue">null</span>;
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
        }
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
The last thing that needs clarifying is that we have overridden the PreFilterProperties
method in the CustomDataSourceDesigner class in order to modify how the TypeName and
SelectMethod properties work, because when any of those properties change, the underlying
data source and schema will probably change, so we have to notify it to the associated
designers:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">        protected</span>
            <span style="COLOR: blue">override</span>
            <span style="COLOR: blue">void</span> PreFilterProperties(<span style="COLOR: teal">IDictionary</span> properties)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">base</span>.PreFilterProperties(properties);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
filters the TypeName property</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">PropertyDescriptor</span> typeNameProp
= (<span style="COLOR: teal">PropertyDescriptor</span>)properties[<span style="COLOR: maroon">"TypeName"</span>];
</p>
          <p style="MARGIN: 0px">
            properties[<span style="COLOR: maroon">"TypeName"</span>]
= <span style="COLOR: teal">TypeDescriptor</span>.CreateProperty(<span style="COLOR: blue">base</span>.GetType(),
typeNameProp, <span style="COLOR: blue">new</span><span style="COLOR: teal">Attribute</span>[0]);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
filters the SelectMethod property</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">PropertyDescriptor</span> selectMethodProp
= (<span style="COLOR: teal">PropertyDescriptor</span>)properties[<span style="COLOR: maroon">"SelectMethod"</span>];
</p>
          <p style="MARGIN: 0px">
            properties[<span style="COLOR: maroon">"SelectMethod"</span>]
= <span style="COLOR: teal">TypeDescriptor</span>.CreateProperty(<span style="COLOR: blue">base</span>.GetType(),
selectMethodProp, <span style="COLOR: blue">new</span><span style="COLOR: teal">Attribute</span>[0]);
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">public</span><span style="COLOR: blue">string</span> TypeName
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> DataSourceComponent.TypeName;
}
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">set</span>   
{
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: green">//
if the type has changed</span></p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">if</span> (<span style="COLOR: teal">String</span>.Compare(DataSourceComponent.TypeName, <span style="COLOR: blue">value</span>, <span style="COLOR: blue">false</span>)
!= 0){
</p>
          <p style="MARGIN: 0px">
                   
DataSourceComponent.TypeName = <span style="COLOR: blue">value</span>;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: green">//
notify to the associated designers that this component has changed</span></p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">if</span> (CanRefreshSchema){
</p>
          <p style="MARGIN: 0px">
                   
    RefreshSchema(<span style="COLOR: blue">true</span>);
</p>
          <p style="MARGIN: 0px">
                   
} <span style="COLOR: blue">else</span> {
</p>
          <p style="MARGIN: 0px">
                   
    OnDataSourceChanged(<span style="COLOR: teal">EventArgs</span>.Empty);
</p>
          <p style="MARGIN: 0px">
                   
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                   
UpdateDesignTimeHtml();
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">public</span><span style="COLOR: blue">string</span> SelectMethod
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">get</span> { <span style="COLOR: blue">return</span> DataSourceComponent.SelectMethod;
}
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">set</span>   
{
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: green">//
if the select method has changed</span></p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">if</span> (<span style="COLOR: teal">String</span>.Compare(DataSourceComponent.SelectMethod, <span style="COLOR: blue">value</span>, <span style="COLOR: blue">false</span>)
!= 0){
</p>
          <p style="MARGIN: 0px">
                   
DataSourceComponent.SelectMethod = <span style="COLOR: blue">value</span>;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: green">//
notify to the associated designers that this component has changed</span></p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">if</span> (CanRefreshSchema
&amp;&amp; !_inWizard){
</p>
          <p style="MARGIN: 0px">
                   
    RefreshSchema(<span style="COLOR: blue">true</span>);
</p>
          <p style="MARGIN: 0px">
                   
} <span style="COLOR: blue">else</span> {
</p>
          <p style="MARGIN: 0px">
                   
    OnDataSourceChanged(<span style="COLOR: teal">EventArgs</span>.Empty);
</p>
          <p style="MARGIN: 0px">
                   
}
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                   
UpdateDesignTimeHtml();
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
        }
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
The full source code of the designer and the data source control are in the files
at the end of this post. As you can see, adding design time support to a data source
control is not terribly complicated but you have to write quite a bit of code (1300
lines in this sample) even for simple data sources. The more complex is your data
source, the more code that you will have to write. 
</p>
        <p>
The design time support covered here for this data source is the most common scenario:
the data source control doesn’t render any HTML at run time and it only exposes a
form to configure the data source. However, a data source control can also render
HTML in some cases (take a look at the <a href="http://www.manuelabadia.com/products/PDS_features.aspx">PagerDataSource</a>)
being not only a data provider but also a data consumer. If you want to render HTML
with your data source control you have a lot of work to do as the framework doesn’t
have any base classes for data source controls that also render HTML.
</p>
        <p>
          <a href="http://www.manuelabadia.com/blog/content/binary/CustomDataSourceDesigner.zip">CustomDataSourceDesigner.zip
(13.5 KB)</a>
        </p>
        <p>
          <a href="http://www.manuelabadia.com/blog/content/binary/CustomDataSourceDesigner_sampleweb.zip">CustomDataSourceDesigner_sampleweb.zip
(26.77 KB)</a>
        </p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=4b487b09-3bdc-498d-ab38-f0eccad54357" />
      </body>
      <title>Creating a custom DataSourceDesigner</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,4b487b09-3bdc-498d-ab38-f0eccad54357.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,4b487b09-3bdc-498d-ab38-f0eccad54357.aspx</link>
      <pubDate>Wed, 19 Jul 2006 08:27:16 GMT</pubDate>
      <description>&lt;p&gt;
We will create a designer for the CustomDataSource we created &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,5a03e8da-fd85-4aed-8c3f-298086f5c153.aspx"&gt;here&lt;/a&gt;.
&lt;/p&gt;
&lt;p&gt;
As we explained in a previous post about the &lt;a href="http://www.manuelabadia.com/blog/PermaLink,guid,187f0155-1b64-45ea-8138-6105e9cd6295.aspx"&gt;DataSourceDesigner
class&lt;/a&gt;, the main tasks that&amp;nbsp;have to be performed by a DataSourceDesigner are:&lt;br&gt;
•&amp;nbsp;configuring the data source&lt;br&gt;
•&amp;nbsp;exposing schema information
&lt;/p&gt;
&lt;p&gt;
Also, we have to expose at least one DesignerDataSourceView (A DataSource control
exposes one or more DataSourceViews and a DataSourceDesigner exposes one or more DesignerDataSourceViews):
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;readonly&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;[]
_views = { &lt;span style="COLOR: maroon"&gt;"DefaultView"&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt; &lt;span style="COLOR: teal"&gt;DesignerDataSourceView&lt;/span&gt; GetView(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; viewName)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; ((viewName
== &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) || ((viewName.Length != 0) &amp;amp;&amp;amp; (&lt;span style="COLOR: teal"&gt;String&lt;/span&gt;.Compare(viewName, &lt;span style="COLOR: maroon"&gt;"DefaultView"&lt;/span&gt;, &lt;span style="COLOR: teal"&gt;StringComparison&lt;/span&gt;.OrdinalIgnoreCase)
!= 0))){
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;throw&lt;/span&gt; &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;ArgumentException&lt;/span&gt;(&lt;span style="COLOR: maroon"&gt;"An
invalid view was requested"&lt;/span&gt;, &lt;span style="COLOR: maroon"&gt;"viewName"&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; View;
&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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt;[]
GetViewNames()
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; _views;
&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;!--EndFragment--&gt;
&lt;p&gt;
As you can see the code is very similar to the one used in the custom data source
to expose the custom data source view. As our data source will only retrieve data,
the default implementation of the DesignerDataSourceView is enough for all CanXXX
properties.
&lt;/p&gt;
&lt;p&gt;
In order to quickly configure&amp;nbsp;our custom&amp;nbsp;DataSource we’ll provide a GUI
that will let us choose the TypeName and the SelectMethod using DropDownLists:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/ConfigDataSource.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
In order to be able to show the Configure Data Source dialog we need to override the
CanConfigure property and implement the Configure method:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt; &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; CanConfigure
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &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;&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Configure()
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; _inWizard = &lt;span style="COLOR: blue"&gt;true&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
generate a transaction to undo changes&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; InvokeTransactedChange(Component, &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;TransactedChangeCallback&lt;/span&gt;(ConfigureDataSourceCallback), &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;, &lt;span style="COLOR: maroon"&gt;"ConfigureDataSource"&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; _inWizard = &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; &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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;virtual&lt;/span&gt; &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; ConfigureDataSourceCallback(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; context)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;try&lt;/span&gt; {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; SuppressDataSourceEvents();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;IServiceProvider&lt;/span&gt; provider
= Component.Site;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (provider
== &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;){
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
get the service needed to show a form&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;IUIService&lt;/span&gt; UIService
= (&lt;span style="COLOR: teal"&gt;IUIService&lt;/span&gt;) provider.GetService(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: teal"&gt;IUIService&lt;/span&gt;));
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (UIService
== &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;){
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
shows the form&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;ConfigureDataSource&lt;/span&gt; configureForm
= &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;ConfigureDataSource&lt;/span&gt;(provider, &lt;span style="COLOR: blue"&gt;this&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (UIService.ShowDialog(configureForm)
== &lt;span style="COLOR: teal"&gt;DialogResult&lt;/span&gt;.OK){
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
OnDataSourceChanged(&lt;span style="COLOR: teal"&gt;EventArgs&lt;/span&gt;.Empty);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &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;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;span style="COLOR: blue"&gt;finally&lt;/span&gt; {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ResumeDataSourceEvents();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &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; &amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
As the GUI will change several properties at a time we have to create a transacted
change in order to provide undo functionality.
&lt;/p&gt;
&lt;p&gt;
The form fills the first dropdownlist with all available types using the type discovery
service instead of reflection. Why? Because using reflection we can only get all types
of the compiled assemblies. However, we can add more types without having compiled
the project or we can have types that don’t compile and the type discovery service
will also show them, so it is a lot better to use the type discovery service instead
of reflection.
&lt;/p&gt;
&lt;p&gt;
In the code we haven’t removed types that probably will not be candidates for our
TypeName property (generic types, interfaces) in order to keep code as simple as possible:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; DiscoverTypes()
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
try to get a reference to the type discovery service&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;ITypeDiscoveryService&lt;/span&gt; discovery
= &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (_component.Site
!= &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; discovery
= (&lt;span style="COLOR: teal"&gt;ITypeDiscoveryService&lt;/span&gt;)_component.Site.GetService(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: teal"&gt;ITypeDiscoveryService&lt;/span&gt;));
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
if the type discovery service is available&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (discovery
!= &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
saves the cursor and sets the wait cursor&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Cursor&lt;/span&gt; previousCursor
= &lt;span style="COLOR: teal"&gt;Cursor&lt;/span&gt;.Current;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Cursor&lt;/span&gt;.Current
= &lt;span style="COLOR: teal"&gt;Cursors&lt;/span&gt;.WaitCursor;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;try&lt;/span&gt; {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
gets all types using the type discovery service&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;ICollection&lt;/span&gt; types
= discovery.GetTypes(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;), &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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ddlTypes.BeginUpdate();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ddlTypes.Items.Clear();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
adds the types to the list&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: teal"&gt;Type&lt;/span&gt; type &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; types)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;TypeItem&lt;/span&gt; typeItem = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;TypeItem&lt;/span&gt;(type);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ddlTypes.Items.Add(typeItem);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;span style="COLOR: blue"&gt;finally&lt;/span&gt; {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Cursor&lt;/span&gt;.Current
= previousCursor;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ddlTypes.EndUpdate();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&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;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The TypeItem class is a class used to store types in the dropdownlist.
&lt;/p&gt;
&lt;p&gt;
When a type is selected from the first dropdownlist, the other dropdownlist gets populated
with the methods of the selected type:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; FillMethods()
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
saves the cursor and sets the wait cursor&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Cursor&lt;/span&gt; previousCursor
= &lt;span style="COLOR: teal"&gt;Cursor&lt;/span&gt;.Current;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Cursor&lt;/span&gt;.Current
= &lt;span style="COLOR: teal"&gt;Cursors&lt;/span&gt;.WaitCursor;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;try&lt;/span&gt; {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
gets all public methods (instance + static)&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;MethodInfo&lt;/span&gt;[]
methods = &lt;span style="COLOR: teal"&gt;CustomDataSourceDesigner&lt;/span&gt;.GetType(_component.Site,
TypeName).GetMethods(&lt;span style="COLOR: teal"&gt;BindingFlags&lt;/span&gt;.Public | &lt;span style="COLOR: teal"&gt;BindingFlags&lt;/span&gt;.Static
| &lt;span style="COLOR: teal"&gt;BindingFlags&lt;/span&gt;.Instance | &lt;span style="COLOR: teal"&gt;BindingFlags&lt;/span&gt;.FlattenHierarchy);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ddlMethods.BeginUpdate();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ddlMethods.Items.Clear();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
adds the methods to the dropdownlist&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: teal"&gt;MethodInfo&lt;/span&gt; method &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; methods)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;MethodItem&lt;/span&gt; methodItem
= &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;MethodItem&lt;/span&gt;(method);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ddlMethods.Items.Add(methodItem);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;span style="COLOR: blue"&gt;finally&lt;/span&gt; {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Cursor&lt;/span&gt;.Current
= previousCursor;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ddlMethods.EndUpdate();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
To quickly get and set the TypeName and the SelectMethod from and to the form we have
defined those properties in the form as follows:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; TypeName
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
gets the selected type&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;TypeItem&lt;/span&gt; selectedType
= ddlTypes.SelectedItem &lt;span style="COLOR: blue"&gt;as&lt;/span&gt; &lt;span style="COLOR: teal"&gt;TypeItem&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
return the selected type&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (selectedType
!= &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;){
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; selectedType.Name;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: teal"&gt;String&lt;/span&gt;.Empty;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&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;&amp;nbsp;&amp;nbsp; &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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
iterate through all the types searching for the requested type&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: teal"&gt;TypeItem&lt;/span&gt; item &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; ddlTypes.Items){
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
if we have found it, select it&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (&lt;span style="COLOR: teal"&gt;String&lt;/span&gt;.Compare(item.Name, &lt;span style="COLOR: blue"&gt;value&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;true&lt;/span&gt;)
== 0) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ddlTypes.SelectedItem = item;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;break&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&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;&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; SelectMethod
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
gets the select method&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; methodName
= &lt;span style="COLOR: teal"&gt;String&lt;/span&gt;.Empty;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (MethodInfo
!= &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
methodName = MethodInfo.Name;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; methodName;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;set&lt;/span&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
iterate through all the types searching for the requested type&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: teal"&gt;MethodItem&lt;/span&gt; item &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; ddlMethods.Items)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
if we have found it, select it&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (&lt;span style="COLOR: teal"&gt;String&lt;/span&gt;.Compare(item.MethodInfo.Name, &lt;span style="COLOR: blue"&gt;value&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;true&lt;/span&gt;)
== 0) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ddlMethods.SelectedItem = item;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;break&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&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;&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: teal"&gt;MethodInfo&lt;/span&gt; MethodInfo
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;MethodItem&lt;/span&gt; item
= ddlMethods.SelectedItem &lt;span style="COLOR: blue"&gt;as&lt;/span&gt; &lt;span style="COLOR: teal"&gt;MethodItem&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (item
== &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; item.MethodInfo;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&lt;br&gt;
&lt;br&gt;
Note that to simplify code when the SelectMethod property is set, the selected method
from the dropdownlist will be the first method with the same name as the SelectMethod
(no parameters are checked to simplify code, but for production code you’ll probably
want to check that the parameters match). 
&lt;/p&gt;
&lt;p&gt;
In the FillMethods method, the type is obtained using the GetType method that used
the resolution service (for the same reasons we specified before for using the type
discovery service). In order to simplify the code we have not removed some methods
that certainly will not be the proper method like property getters and setters or
abstract methods.
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: teal"&gt;Type&lt;/span&gt; GetType(&lt;span style="COLOR: teal"&gt;IServiceProvider&lt;/span&gt; serviceProvider, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; typeName)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
try to get a reference to the resolution service&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;ITypeResolutionService&lt;/span&gt; resolution
= (&lt;span style="COLOR: teal"&gt;ITypeResolutionService&lt;/span&gt;)serviceProvider.GetService(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: teal"&gt;ITypeResolutionService&lt;/span&gt;));
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (resolution
== &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
try to get the type&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; resolution.GetType(typeName, &lt;span style="COLOR: blue"&gt;false&lt;/span&gt;, &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;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
When the user clicks the Accept button in the Configure data source form, the code
that gets executed is:&lt;br&gt;
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; bOK_Click(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; sender, &lt;span style="COLOR: teal"&gt;EventArgs&lt;/span&gt; e)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
if the type has changed, save it&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (&lt;span style="COLOR: teal"&gt;String&lt;/span&gt;.Compare(TypeName,
_component.TypeName, &lt;span style="COLOR: blue"&gt;false&lt;/span&gt;) != 0) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;TypeDescriptor&lt;/span&gt;.GetProperties(_component)[&lt;span style="COLOR: maroon"&gt;"TypeName"&lt;/span&gt;].SetValue(_component,
TypeName);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
if the select method has changed, save it&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (&lt;span style="COLOR: teal"&gt;String&lt;/span&gt;.Compare(SelectMethod,
_component.SelectMethod, &lt;span style="COLOR: blue"&gt;false&lt;/span&gt;) != 0) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;TypeDescriptor&lt;/span&gt;.GetProperties(_component)[&lt;span style="COLOR: maroon"&gt;"SelectMethod"&lt;/span&gt;].SetValue(_component,
SelectMethod);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
if there is method selected, refresh the schema&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (MethodInfo
!= &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; _designer.RefreshSchemaInternal(MethodInfo.ReflectedType,
MethodInfo.Name, MethodInfo.ReturnType, &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;&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;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
We save the Type and the SelectMethod and refresh the schema.
&lt;/p&gt;
&lt;p&gt;
To provide schema information, we have to return true in the CanRefreshSchema method
and we have to implement the RefreshSchema method. When we provide schema information
the controls can provide field pickers (i.e. columns for a GridView) and generate
templates based on the schema information (i.e. a DataList bound to our data source
control). However, we can not return true for the CanRefreshSchema, because we can
return schema information only if the user has configured the data source:&lt;br&gt;
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt; &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; CanRefreshSchema
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;get&lt;/span&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
if a type and the select method have been specified, the schema can be refreshed&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (!&lt;span style="COLOR: teal"&gt;String&lt;/span&gt;.IsNullOrEmpty(TypeName)
&amp;amp;&amp;amp; !&lt;span style="COLOR: teal"&gt;String&lt;/span&gt;.IsNullOrEmpty(SelectMethod)) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&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;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
To implement the RefreshSchema method, we need to extract the schema information and
generate the SchemaRefreshed event. If a data source control can provide schema information,
the schema information will be retrieved from the property Schema from the underlying
DesignerDataSourceView. However, the SchemaRefreshed event doesn’t have to be raised
everytime, only if the data source returns a different schema. To see why this is
important think about this: if the data source is bound to a GridView, every time
the RefreshSchema event is raised, the designer will ask if it has to regenerate the
columns and the data keys. So we’re interested in raising the SchemaRefreshed event
only when the schema changes. We use the designer state to store the previous schema,
and when the RefreshSchema method is called, we will check if the schema has changed,
raising the SchemaRefreshed event only in that case.
&lt;/p&gt;
&lt;p&gt;
The code related to the RefreshSchema method is:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; internal&lt;/span&gt; &lt;span style="COLOR: teal"&gt;IDataSourceViewSchema&lt;/span&gt; DataSourceSchema
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; DesignerState[&lt;span style="COLOR: maroon"&gt;"DataSourceSchema"&lt;/span&gt;] &lt;span style="COLOR: blue"&gt;as&lt;/span&gt; &lt;span style="COLOR: teal"&gt;IDataSourceViewSchema&lt;/span&gt;;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;set&lt;/span&gt; {
DesignerState[&lt;span style="COLOR: maroon"&gt;"DataSourceSchema"&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; &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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; RefreshSchema(&lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; preferSilent)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
saves the old cursor&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Cursor&lt;/span&gt; oldCursor
= &lt;span style="COLOR: teal"&gt;Cursor&lt;/span&gt;.Current;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;try&lt;/span&gt; {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
ignore data source events while refreshing the schema&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; SuppressDataSourceEvents();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;try&lt;/span&gt; {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Cursor&lt;/span&gt;.Current
= &lt;span style="COLOR: teal"&gt;Cursors&lt;/span&gt;.WaitCursor;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
gets the Type used in the DataSourceControl&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Type&lt;/span&gt; type
= GetType(Component.Site, TypeName);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
if we can't find the type, return&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (type
== &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
get all the methods that can be used as the select method&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;MethodInfo&lt;/span&gt;[]
methods = type.GetMethods(&lt;span style="COLOR: teal"&gt;BindingFlags&lt;/span&gt;.FlattenHierarchy
| &lt;span style="COLOR: teal"&gt;BindingFlags&lt;/span&gt;.Static | &lt;span style="COLOR: teal"&gt;BindingFlags&lt;/span&gt;.Instance
| &lt;span style="COLOR: teal"&gt;BindingFlags&lt;/span&gt;.Public);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;MethodInfo&lt;/span&gt; selectedMethod
= &lt;span style="COLOR: blue"&gt;null&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
iterates through the methods searching for the select method&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: teal"&gt;MethodInfo&lt;/span&gt; method &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; methods)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// if the method is named as the selected
method, select it&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (IsMatchingMethod(method, SelectMethod))
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; selectedMethod = method;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;break&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
if the SelectMethod was found, save the type information&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (selectedMethod
!= &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; RefreshSchemaInternal(type, selectedMethod.Name, selectedMethod.ReturnType,
preferSilent);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;span style="COLOR: blue"&gt;finally&lt;/span&gt; {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
restores the cursor&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Cursor&lt;/span&gt;.Current
= oldCursor;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;span style="COLOR: blue"&gt;finally&lt;/span&gt; {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
resume data source events&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ResumeDataSourceEvents();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;internal&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; RefreshSchemaInternal(&lt;span style="COLOR: teal"&gt;Type&lt;/span&gt; typeName, &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; method, &lt;span style="COLOR: teal"&gt;Type&lt;/span&gt; returnType, &lt;span style="COLOR: blue"&gt;bool&lt;/span&gt; preferSilent)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
if all parameters are filled&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; ((typeName
!= &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) &amp;amp;&amp;amp; (!&lt;span style="COLOR: teal"&gt;String&lt;/span&gt;.IsNullOrEmpty(method))
&amp;amp;&amp;amp; (returnType != &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;)) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;try&lt;/span&gt; {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
gets the old schema&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;IDataSourceViewSchema&lt;/span&gt; oldSchema
= DataSourceSchema;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
gets the schema of the return type&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;IDataSourceViewSchema&lt;/span&gt;[]
typeSchemas = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;TypeSchema&lt;/span&gt;(returnType).GetViews();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
if we can't get schema information from the type, exit&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; ((typeSchemas
== &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;) || (typeSchemas.Length == 0)){
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; DataSourceSchema = &lt;span style="COLOR: blue"&gt;null&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
get a view of the schema&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;IDataSourceViewSchema&lt;/span&gt; newSchema
= typeSchemas[0];
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
if the schema has changed, raise the schema refreshed event&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (!&lt;span style="COLOR: teal"&gt;DataSourceDesigner&lt;/span&gt;.ViewSchemasEquivalent(oldSchema,
newSchema)){
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; DataSourceSchema = newSchema;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; OnSchemaRefreshed(&lt;span style="COLOR: teal"&gt;EventArgs&lt;/span&gt;.Empty);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;span style="COLOR: blue"&gt;catch&lt;/span&gt; (&lt;span style="COLOR: teal"&gt;Exception&lt;/span&gt; e){
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (!preferSilent){
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ShowError(DataSourceComponent.Site, &lt;span style="COLOR: maroon"&gt;"Cannot
retrieve type schema for "&lt;/span&gt; + returnType.FullName + &lt;span style="COLOR: maroon"&gt;".
"&lt;/span&gt; + e.Message);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&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;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
As you can see, we get the MethodInfo for the SelectMethod and get the return type.
All hard work to expose schema information is done by the framework helper class TypeSchema
that was explained in the post about DataSourceDesigners. The DesignerDataSource view
exposes the saved schema:&lt;br&gt;
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt; &lt;span style="COLOR: teal"&gt;IDataSourceViewSchema&lt;/span&gt; Schema 
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
if a type and the select method have been specified, the schema information is available&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (!&lt;span style="COLOR: teal"&gt;String&lt;/span&gt;.IsNullOrEmpty(_owner.TypeName)
&amp;amp;&amp;amp; !&lt;span style="COLOR: teal"&gt;String&lt;/span&gt;.IsNullOrEmpty(_owner.SelectMethod))
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; _owner.DataSourceSchema;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&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;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The last thing that needs clarifying is that we have overridden the PreFilterProperties
method in the CustomDataSourceDesigner class in order to modify how the TypeName and
SelectMethod properties work, because when any of those properties change, the underlying
data source and schema will probably change, so we have to notify it to the associated
designers:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; PreFilterProperties(&lt;span style="COLOR: teal"&gt;IDictionary&lt;/span&gt; properties)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;base&lt;/span&gt;.PreFilterProperties(properties);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
filters the TypeName property&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;PropertyDescriptor&lt;/span&gt; typeNameProp
= (&lt;span style="COLOR: teal"&gt;PropertyDescriptor&lt;/span&gt;)properties[&lt;span style="COLOR: maroon"&gt;"TypeName"&lt;/span&gt;];
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; properties[&lt;span style="COLOR: maroon"&gt;"TypeName"&lt;/span&gt;]
= &lt;span style="COLOR: teal"&gt;TypeDescriptor&lt;/span&gt;.CreateProperty(&lt;span style="COLOR: blue"&gt;base&lt;/span&gt;.GetType(),
typeNameProp, &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;Attribute&lt;/span&gt;[0]);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
filters the SelectMethod property&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;PropertyDescriptor&lt;/span&gt; selectMethodProp
= (&lt;span style="COLOR: teal"&gt;PropertyDescriptor&lt;/span&gt;)properties[&lt;span style="COLOR: maroon"&gt;"SelectMethod"&lt;/span&gt;];
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; properties[&lt;span style="COLOR: maroon"&gt;"SelectMethod"&lt;/span&gt;]
= &lt;span style="COLOR: teal"&gt;TypeDescriptor&lt;/span&gt;.CreateProperty(&lt;span style="COLOR: blue"&gt;base&lt;/span&gt;.GetType(),
selectMethodProp, &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;Attribute&lt;/span&gt;[0]);
&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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; TypeName
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; DataSourceComponent.TypeName;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;set&lt;/span&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
if the type has changed&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (&lt;span style="COLOR: teal"&gt;String&lt;/span&gt;.Compare(DataSourceComponent.TypeName, &lt;span style="COLOR: blue"&gt;value&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;false&lt;/span&gt;)
!= 0){
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
DataSourceComponent.TypeName = &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;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
notify to the associated designers that this component has changed&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (CanRefreshSchema){
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; RefreshSchema(&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; OnDataSourceChanged(&lt;span style="COLOR: teal"&gt;EventArgs&lt;/span&gt;.Empty);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
UpdateDesignTimeHtml();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&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;&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; SelectMethod
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;get&lt;/span&gt; { &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; DataSourceComponent.SelectMethod;
}
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;set&lt;/span&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
if the select method has changed&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (&lt;span style="COLOR: teal"&gt;String&lt;/span&gt;.Compare(DataSourceComponent.SelectMethod, &lt;span style="COLOR: blue"&gt;value&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;false&lt;/span&gt;)
!= 0){
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
DataSourceComponent.SelectMethod = &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;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
notify to the associated designers that this component has changed&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (CanRefreshSchema
&amp;amp;&amp;amp; !_inWizard){
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; RefreshSchema(&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; OnDataSourceChanged(&lt;span style="COLOR: teal"&gt;EventArgs&lt;/span&gt;.Empty);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
UpdateDesignTimeHtml();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&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;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The full source code of the designer and the data source control are in the files
at the end of this post. As you can see, adding design time support to a data source
control is not terribly complicated but you have to write quite a bit of code (1300
lines in this sample) even for simple data sources. The more complex is your data
source, the more code that you will have to write. 
&lt;/p&gt;
&lt;p&gt;
The design time support covered here for this data source is the most common scenario:
the data source control doesn’t render any HTML at run time and it only exposes a
form to configure the data source. However, a data source control can also render
HTML in some cases (take a look at the &lt;a href="http://www.manuelabadia.com/products/PDS_features.aspx"&gt;PagerDataSource&lt;/a&gt;)
being not only a data provider but also a data consumer. If you want to render HTML
with your data source control you have a lot of work to do as the framework doesn’t
have any base classes for data source controls that also render HTML.
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.manuelabadia.com/blog/content/binary/CustomDataSourceDesigner.zip"&gt;CustomDataSourceDesigner.zip
(13.5 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.manuelabadia.com/blog/content/binary/CustomDataSourceDesigner_sampleweb.zip"&gt;CustomDataSourceDesigner_sampleweb.zip
(26.77 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=4b487b09-3bdc-498d-ab38-f0eccad54357" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,4b487b09-3bdc-498d-ab38-f0eccad54357.aspx</comments>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=8e348d54-3885-48df-b491-3b0a039fb63e</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,8e348d54-3885-48df-b491-3b0a039fb63e.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,8e348d54-3885-48df-b491-3b0a039fb63e.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=8e348d54-3885-48df-b491-3b0a039fb63e</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
Here are some common questions and answers about the ObjectDataSource.
</p>
        <p>
          <strong>Why my SelectCountMethod needs a StartRowIndex and MaximumRows parameters
in order to work properly?</strong>
        </p>
        <p>
The answer is that they are not needed. However, the ObjectDataSource will call the
SelectCountMethod with all the parameters present in the SelectParameters collection.
If you have enabled paging in the ObjectDataSource, the StartRowIndex and MaximumRows
parameters will be added to the signature of the SelectMethod even if they are not
in the SelectParameters collection. Usually the StartRowIndex and MaximumRows parameters
will be set automatically by the control bound to the ObjectDataSource so there is
no need to have them in the SelectParameters collection so if you remove them the
SelectCountMethod will not need them. The same happens to the SortParameter. Most
examples take the StartRowIndex and MaximumRows because when the method is selected
in design time, all the parameters are persisted as parameters in the SelectParameters
collection.
</p>
        <p>
          <strong>Can I use an interface as the TypeName in the ObjectDataSource?</strong>
        </p>
        <p>
The ObjectDataSource designer will not let you choose an interface in the first step
of the wizard, and if you have specified the TypeName in the ASPX and you then run
the designer, the methods associated to the interface will not be shown, so if you
want to use interfaces with the ObjectDataSource you lost design time support. If
you configure the ObjectDataSource to use the methods from an interface a runtime
error will happen:
</p>
        <p>
          <em>Cannot create an instance of an interface.</em>
        </p>
        <p>
because the ObjectDataSource will try to create an instance of the Type specified
in the TypeName property (if the method to call is an instance method). However if
you handle the ObjectCreating event, you can create an instance of an object that
implements the interface specified by the TypeName property and assign it to the ObjectInstance
property of the event arguments. That will make everything will work as expected.
</p>
        <p>
          <strong>I have a GridView bound to an ObjectDataSource. I have a SelectParameter for
the sorting with a DefaultValue specified. However, when the page initially loads
the DefaultValue is never used. Why?</strong>
        </p>
        <p>
When the GridView needs data, a select operation is performed in the underlying data
source control. Before this operation is performed, a method called CreateDataSourceSelectArguments
is called on the GridView. This method creates the arguments that will be passed to
the Select method of the ObjectDataSource, which in turns calls the method specified
by the property SelectMethod. In the CreateDataSourceSelectArguments method, the SortExpression
is set based on the GridView’s state and the ObjectDataSource just assign that value
to the sort parameter. So, as you can see, the DefaultValue is never used for the
sort parameter.<br /></p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=8e348d54-3885-48df-b491-3b0a039fb63e" />
      </body>
      <title>Some questions and answers about the ObjectDataSource</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,8e348d54-3885-48df-b491-3b0a039fb63e.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,8e348d54-3885-48df-b491-3b0a039fb63e.aspx</link>
      <pubDate>Sun, 16 Jul 2006 15:30:25 GMT</pubDate>
      <description>&lt;p&gt;
Here are some common questions and answers about the ObjectDataSource.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Why my SelectCountMethod needs a StartRowIndex and MaximumRows parameters
in order to work properly?&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The answer is that they are not needed. However, the ObjectDataSource will call the
SelectCountMethod with all the parameters present in the SelectParameters collection.
If you have enabled paging in the ObjectDataSource, the StartRowIndex and MaximumRows
parameters will be added to the signature of the SelectMethod even if they are not
in the SelectParameters collection. Usually the StartRowIndex and MaximumRows parameters
will be set automatically by the control bound to the ObjectDataSource so there is
no need to have them in the SelectParameters collection so if you remove them the
SelectCountMethod will not need them. The same happens to the SortParameter. Most
examples take the StartRowIndex and MaximumRows because when the method is selected
in design time, all the parameters are persisted as parameters in the SelectParameters
collection.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;Can I use an interface as the TypeName in the ObjectDataSource?&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
The ObjectDataSource designer will not let you choose an interface in the first step
of the wizard, and if you have specified the TypeName in the ASPX and you then run
the designer, the methods associated to the interface will not be shown, so if you
want to use interfaces with the ObjectDataSource you lost design time support. If
you configure the ObjectDataSource to use the methods from an interface a runtime
error will happen:
&lt;/p&gt;
&lt;p&gt;
&lt;em&gt;Cannot create an instance of an interface.&lt;/em&gt;
&lt;/p&gt;
&lt;p&gt;
because the ObjectDataSource will try to create an instance of the Type specified
in the TypeName property (if the method to call is an instance method). However if
you handle the ObjectCreating event, you can create an instance of an object that
implements the interface specified by the TypeName property and assign it to the ObjectInstance
property of the event arguments. That will make everything will work as expected.
&lt;/p&gt;
&lt;p&gt;
&lt;strong&gt;I have a GridView bound to an ObjectDataSource. I have a SelectParameter for
the sorting with a DefaultValue specified. However, when the page initially loads
the DefaultValue is never used. Why?&lt;/strong&gt;
&lt;/p&gt;
&lt;p&gt;
When the GridView needs data, a select operation is performed in the underlying data
source control. Before this operation is performed, a method called CreateDataSourceSelectArguments
is called on the GridView. This method creates the arguments that will be passed to
the Select method of the ObjectDataSource, which in turns calls the method specified
by the property SelectMethod. In the CreateDataSourceSelectArguments method, the SortExpression
is set based on the GridView’s state and the ObjectDataSource just assign that value
to the sort parameter. So, as you can see, the DefaultValue is never used for the
sort parameter.&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=8e348d54-3885-48df-b491-3b0a039fb63e" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,8e348d54-3885-48df-b491-3b0a039fb63e.aspx</comments>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=dc72b235-1381-4c91-8706-e36216f49b94</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,dc72b235-1381-4c91-8706-e36216f49b94.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,dc72b235-1381-4c91-8706-e36216f49b94.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=dc72b235-1381-4c91-8706-e36216f49b94</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
        </p>
        <p>
Being able to dynamically call an arbitrary method on an object or the ability to
get/set any arbitrary property by name at run time is very important when it comes
to do some generic stuff. In .NET Framework 1.x the only way to do that was using
reflection and that means to do it slow. For simple things or if we don’t have a lot
of concurrent users we can live with it, but sometimes the performance is important
and reflection isn’t an acceptable solution.
</p>
        <p>
Fortunately, the .NET Framework 2.0 introduces a new class that let us to quickly
call an arbitrary method without the overhead of a reflection call. How? Well, the
idea is to generate the same MSIL as the compiler generates when calling a function
but on the fly, and then we obtain a delegate that when called will execute the MSIL
we have just created. This is really useful in a lot of scenarios!
</p>
        <p>
I read something about this in Marc’s blog (<a href="http://musingmarc.blogspot.com/">http://musingmarc.blogspot.com/</a>)
but I didn’t have time to look at it in more detail in that moment. Today I read an
article at codeproject that talked about this (<a href="http://www.codeproject.com/useritems/FastMethodInvoker.asp">http://www.codeproject.com/useritems/FastMethodInvoker.asp</a>)
so I finally forced myself to spend some time playing with dynamic MSIL code generation
and I’m quite impressed with the possibilities.
</p>
        <p>
If you want to play with this you should download an excellent debugger visualizer
that will let you show the MSIL generated by a DynamicMethod:
</p>
        <p>
          <a href="http://blogs.msdn.com/haibo_luo/archive/2005/10/25/484861.aspx">http://blogs.msdn.com/haibo_luo/archive/2005/10/25/484861.aspx</a>
        </p>
        <p>
I have made a little helper class (based on the codeproject article) that can be used
to replace MethodInfo.Invoke, PropertyInfo.GetValue, PropertyInfo.SetValue and Activator.CreateInstance
that are the reflection methods that I use most often. In order to use it in your
own projects, remember to cache the delegates obtained because every time you call
the CreateDelegate the MSIL generation takes place and that takes some time.
</p>
        <p>
I have also created a simple test to show a comparison between direct calls, reflection
calls and dynamic method calls. The results are here:
</p>
        <p>
------ Object Creation ------<br />
direct - object creation: 63ms<br />
dynamic method - object creation: 86ms<br />
reflection - object creation: 391ms<br />
------ Property Get ------<br />
direct - property get: 21ms<br />
dynamic method - property get: 81ms<br />
reflection - property get: 1849ms<br />
------ Property Set ------<br />
direct - property set: 21ms<br />
dynamic method - property set: 67ms<br />
reflection - property set: 2476ms<br />
------ Instance Method Call ------<br />
direct - instance method call: 24ms<br />
dynamic method - instance method call: 154ms<br />
reflection - instance method call: 3266ms<br />
------ Static Method Call ------<br />
direct - static method call: 36ms<br />
dynamic method - static method call: 157ms<br />
reflection - static method call: 3139ms
</p>
        <p>
To summarize: 
<br />
• For object creation, using reflection is 6.2 times slower than direct object
creation. With DynamicMethods is only 1.3 times slower than direct object creation.
Using DynamicMethods is about 4.5 times faster than using reflection.<br />
• To get a property using reflection is 90.1 times slower than direct property
access. With DynamicMethods is only 3.8 times slower than direct property access.
Using DynamicMethods is nearly 23 times faster than using reflection.<br />
• To set a property using reflection is 117.9 times slower than direct property
set. With DynamicMethods is only 3.2 times slower than direct property set. Using
DynamicMethods is about 37 times faster than using reflection.<br />
• For instance method invocation, using reflection is 136.1 times slower than
direct method call. With DynamicMethods is only 6.4 times slower than direct method
call. Using DynamicMethods is about 21 times faster than using reflection.<br />
• For static method invocation, using reflection is 87.2 times slower than direct
method call. With DynamicMethods is only 4.3 times slower than direct method call.
Using DynamicMethods is about 20 times faster than using reflection.
</p>
        <p>
I’m going to modify my <a href="http://www.manuelabadia.com/products/EODS_features.aspx">ExtendedObjectDataSource</a> to
use DynamicMethods in order to gain a 20x speed increase compared to reflection calls.
</p>
        <p>
The code used for the tests and the helper class for the DynamicMethods are shown
here and can be downloaded at the end of this post:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">using</span> System;
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">using</span> System.Reflection;
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">using</span> System.Reflection.Emit;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">namespace</span> Manu.Utils
</p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;summary&gt;</span><span style="COLOR: green">Delegate
for calling a method that is not known at runtime.</span><span style="COLOR: gray">&lt;/summary&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;param
name="target"&gt;</span><span style="COLOR: green">the object to be called or null
if the call is to a static method.</span><span style="COLOR: gray">&lt;/param&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;param
name="paramters"&gt;</span><span style="COLOR: green">the parameters to the method.</span><span style="COLOR: gray">&lt;/param&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;returns&gt;</span><span style="COLOR: green">the
return value for the method or null if it doesn't return anything.</span><span style="COLOR: gray">&lt;/returns&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">delegate</span><span style="COLOR: blue">object</span><span style="COLOR: teal">FastInvokeHandler</span>(<span style="COLOR: blue">object</span> target, <span style="COLOR: blue">object</span>[]
parameters);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;summary&gt;</span><span style="COLOR: green">Delegate
for creating and object at runtime using the default constructor.</span><span style="COLOR: gray">&lt;/summary&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;returns&gt;</span><span style="COLOR: green">the
newly created object.</span><span style="COLOR: gray">&lt;/returns&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">delegate</span><span style="COLOR: blue">object</span><span style="COLOR: teal">FastCreateInstanceHandler</span>();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;summary&gt;</span><span style="COLOR: green">Delegate
to get an arbitraty property at runtime.</span><span style="COLOR: gray">&lt;/summary&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;param
name="target"&gt;</span><span style="COLOR: green">the object instance whose property
will be obtained.</span><span style="COLOR: gray">&lt;/param&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;returns&gt;</span><span style="COLOR: green">the
property value.</span><span style="COLOR: gray">&lt;/returns&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">delegate</span><span style="COLOR: blue">object</span><span style="COLOR: teal">FastPropertyGetHandler</span>(<span style="COLOR: blue">object</span> target);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;summary&gt;</span><span style="COLOR: green">Delegate
to set an arbitrary property at runtime.</span><span style="COLOR: gray">&lt;/summary&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;param
name="target"&gt;</span><span style="COLOR: green">the object instance whose property
will be modified.</span><span style="COLOR: gray">&lt;/param&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;param
name="parameter"&gt;&lt;/param&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">delegate</span><span style="COLOR: blue">void</span><span style="COLOR: teal">FastPropertySetHandler</span>(<span style="COLOR: blue">object</span> target, <span style="COLOR: blue">object</span> parameter);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;summary&gt;</span><span style="COLOR: green">Class
with helper methods for dynamic invocation generating IL on the fly.</span><span style="COLOR: gray">&lt;/summary&gt;</span></p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">static</span><span style="COLOR: blue">class</span><span style="COLOR: teal">DynamicCalls</span></p>
          <p style="MARGIN: 0px">
    {
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">public</span><span style="COLOR: blue">static</span><span style="COLOR: teal">FastInvokeHandler</span> GetMethodInvoker(<span style="COLOR: teal">MethodInfo</span> methodInfo)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
generates a dynamic method to generate a FastInvokeHandler delegate</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">DynamicMethod</span> dynamicMethod
= <span style="COLOR: blue">new</span><span style="COLOR: teal">DynamicMethod</span>(<span style="COLOR: blue">string</span>.Empty, <span style="COLOR: blue">typeof</span>(<span style="COLOR: blue">object</span>), <span style="COLOR: blue">new</span><span style="COLOR: teal">Type</span>[]
{ <span style="COLOR: blue">typeof</span>(<span style="COLOR: blue">object</span>), <span style="COLOR: blue">typeof</span>(<span style="COLOR: blue">object</span>[])
}, methodInfo.DeclaringType.Module);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">ILGenerator</span> ilGenerator
= dynamicMethod.GetILGenerator();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">ParameterInfo</span>[]
parameters = methodInfo.GetParameters();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">Type</span>[]
paramTypes = <span style="COLOR: blue">new</span><span style="COLOR: teal">Type</span>[parameters.Length];
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
copies the parameter types to an array</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">for</span> (<span style="COLOR: blue">int</span> i
= 0; i &lt; paramTypes.Length; i++) {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">if</span> (parameters[i].ParameterType.IsByRef)
</p>
          <p style="MARGIN: 0px">
                   
paramTypes[i] = parameters[i].ParameterType.GetElementType();
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">else</span></p>
          <p style="MARGIN: 0px">
                   
paramTypes[i] = parameters[i].ParameterType;
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">LocalBuilder</span>[]
locals = <span style="COLOR: blue">new</span><span style="COLOR: teal">LocalBuilder</span>[paramTypes.Length];
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
generates a local variable for each parameter</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">for</span> (<span style="COLOR: blue">int</span> i
= 0; i &lt; paramTypes.Length; i++) {
</p>
          <p style="MARGIN: 0px">
                locals[i]
= ilGenerator.DeclareLocal(paramTypes[i], <span style="COLOR: blue">true</span>);
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
creates code to copy the parameters to the local variables</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">for</span> (<span style="COLOR: blue">int</span> i
= 0; i &lt; paramTypes.Length; i++) {
</p>
          <p style="MARGIN: 0px">
                ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldarg_1);
</p>
          <p style="MARGIN: 0px">
                EmitFastInt(ilGenerator,
i);
</p>
          <p style="MARGIN: 0px">
                ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldelem_Ref);
</p>
          <p style="MARGIN: 0px">
                EmitCastToReference(ilGenerator,
paramTypes[i]);
</p>
          <p style="MARGIN: 0px">
                ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Stloc,
locals[i]);
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> (!methodInfo.IsStatic)
{
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: green">//
loads the object into the stack</span></p>
          <p style="MARGIN: 0px">
                ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldarg_0);
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
loads the parameters copied to the local variables into the stack</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">for</span> (<span style="COLOR: blue">int</span> i
= 0; i &lt; paramTypes.Length; i++) {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">if</span> (parameters[i].ParameterType.IsByRef)
</p>
          <p style="MARGIN: 0px">
                   
ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldloca_S, locals[i]);
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">else</span></p>
          <p style="MARGIN: 0px">
                   
ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldloc, locals[i]);
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
calls the method</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> (!methodInfo.IsStatic)
{
</p>
          <p style="MARGIN: 0px">
                ilGenerator.EmitCall(<span style="COLOR: teal">OpCodes</span>.Callvirt,
methodInfo, <span style="COLOR: blue">null</span>);
</p>
          <p style="MARGIN: 0px">
            } <span style="COLOR: blue">else</span> {
</p>
          <p style="MARGIN: 0px">
                ilGenerator.EmitCall(<span style="COLOR: teal">OpCodes</span>.Call,
methodInfo, <span style="COLOR: blue">null</span>);
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
creates code for handling the return value</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> (methodInfo.ReturnType
== <span style="COLOR: blue">typeof</span>(<span style="COLOR: blue">void</span>))
{
</p>
          <p style="MARGIN: 0px">
                ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldnull);
</p>
          <p style="MARGIN: 0px">
            } <span style="COLOR: blue">else</span> {
</p>
          <p style="MARGIN: 0px">
                EmitBoxIfNeeded(ilGenerator,
methodInfo.ReturnType);
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
iterates through the parameters updating the parameters passed by ref</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">for</span> (<span style="COLOR: blue">int</span> i
= 0; i &lt; paramTypes.Length; i++) {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">if</span> (parameters[i].ParameterType.IsByRef)
{
</p>
          <p style="MARGIN: 0px">
                   
ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldarg_1);
</p>
          <p style="MARGIN: 0px">
                   
EmitFastInt(ilGenerator, i);
</p>
          <p style="MARGIN: 0px">
                   
ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldloc, locals[i]);
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">if</span> (locals[i].LocalType.IsValueType)
</p>
          <p style="MARGIN: 0px">
                   
    ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Box,
locals[i].LocalType);
</p>
          <p style="MARGIN: 0px">
                   
ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Stelem_Ref);
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
returns the value to the caller</span></p>
          <p style="MARGIN: 0px">
            ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ret);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
converts the DynamicMethod to a FastInvokeHandler delegate to call to the method</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">FastInvokeHandler</span> invoker
= (<span style="COLOR: teal">FastInvokeHandler</span>)dynamicMethod.CreateDelegate(<span style="COLOR: blue">typeof</span>(<span style="COLOR: teal">FastInvokeHandler</span>));
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">return</span> invoker;
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;summary&gt;</span><span style="COLOR: green">Gets
the instance creator delegate that can be use to create instances of the specified
type.</span><span style="COLOR: gray">&lt;/summary&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;param
name="type"&gt;</span><span style="COLOR: green">The type of the objects we want to
create.</span><span style="COLOR: gray">&lt;/param&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;returns&gt;</span><span style="COLOR: green">A
delegate that can be used to create the objects.</span><span style="COLOR: gray">&lt;/returns&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">public</span><span style="COLOR: blue">static</span><span style="COLOR: teal">FastCreateInstanceHandler</span> GetInstanceCreator(<span style="COLOR: teal">Type</span> type)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
generates a dynamic method to generate a FastCreateInstanceHandler delegate</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">DynamicMethod</span> dynamicMethod
= <span style="COLOR: blue">new</span><span style="COLOR: teal">DynamicMethod</span>(<span style="COLOR: blue">string</span>.Empty,
type, <span style="COLOR: blue">new</span><span style="COLOR: teal">Type</span>[0], <span style="COLOR: blue">typeof</span>(<span style="COLOR: teal">DynamicCalls</span>).Module);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">ILGenerator</span> ilGenerator
= dynamicMethod.GetILGenerator();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
generates code to create a new object of the specified type using the default constructor</span></p>
          <p style="MARGIN: 0px">
            ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Newobj,
type.GetConstructor(<span style="COLOR: teal">Type</span>.EmptyTypes));
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
returns the value to the caller</span></p>
          <p style="MARGIN: 0px">
            ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ret);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
converts the DynamicMethod to a FastCreateInstanceHandler delegate to create the object</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">FastCreateInstanceHandler</span> creator
= (<span style="COLOR: teal">FastCreateInstanceHandler</span>)dynamicMethod.CreateDelegate(<span style="COLOR: blue">typeof</span>(<span style="COLOR: teal">FastCreateInstanceHandler</span>));
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">return</span> creator;
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">public</span><span style="COLOR: blue">static</span><span style="COLOR: teal">FastPropertyGetHandler</span> GetPropertyGetter(<span style="COLOR: teal">PropertyInfo</span> propInfo)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
generates a dynamic method to generate a FastPropertyGetHandler delegate</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">DynamicMethod</span> dynamicMethod
= <span style="COLOR: blue">new</span><span style="COLOR: teal">DynamicMethod</span>(<span style="COLOR: blue">string</span>.Empty, <span style="COLOR: blue">typeof</span>(<span style="COLOR: blue">object</span>), <span style="COLOR: blue">new</span><span style="COLOR: teal">Type</span>[]
{ <span style="COLOR: blue">typeof</span>(<span style="COLOR: blue">object</span>)
}, propInfo.DeclaringType.Module);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">ILGenerator</span> ilGenerator
= dynamicMethod.GetILGenerator();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
loads the object into the stack</span></p>
          <p style="MARGIN: 0px">
            ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldarg_0);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
calls the getter</span></p>
          <p style="MARGIN: 0px">
            ilGenerator.EmitCall(<span style="COLOR: teal">OpCodes</span>.Callvirt,
propInfo.GetGetMethod(), <span style="COLOR: blue">null</span>);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
creates code for handling the return value</span></p>
          <p style="MARGIN: 0px">
            EmitBoxIfNeeded(ilGenerator,
propInfo.PropertyType);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
returns the value to the caller</span></p>
          <p style="MARGIN: 0px">
            ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ret);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
converts the DynamicMethod to a FastPropertyGetHandler delegate to get the property</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">FastPropertyGetHandler</span> getter
= (<span style="COLOR: teal">FastPropertyGetHandler</span>)dynamicMethod.CreateDelegate(<span style="COLOR: blue">typeof</span>(<span style="COLOR: teal">FastPropertyGetHandler</span>));
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">return</span> getter;
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">public</span><span style="COLOR: blue">static</span><span style="COLOR: teal">FastPropertySetHandler</span> GetPropertySetter(<span style="COLOR: teal">PropertyInfo</span> propInfo)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
generates a dynamic method to generate a FastPropertySetHandler delegate</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">DynamicMethod</span> dynamicMethod
= <span style="COLOR: blue">new</span><span style="COLOR: teal">DynamicMethod</span>(<span style="COLOR: blue">string</span>.Empty, <span style="COLOR: blue">null</span>, <span style="COLOR: blue">new</span><span style="COLOR: teal">Type</span>[]
{ <span style="COLOR: blue">typeof</span>(<span style="COLOR: blue">object</span>), <span style="COLOR: blue">typeof</span>(<span style="COLOR: blue">object</span>)
}, propInfo.DeclaringType.Module);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">ILGenerator</span> ilGenerator
= dynamicMethod.GetILGenerator();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
loads the object into the stack</span></p>
          <p style="MARGIN: 0px">
            ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldarg_0);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
loads the parameter from the stack</span></p>
          <p style="MARGIN: 0px">
            ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldarg_1);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
cast to the proper type (unboxing if needed)</span></p>
          <p style="MARGIN: 0px">
            EmitCastToReference(ilGenerator,
propInfo.PropertyType);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
calls the setter</span></p>
          <p style="MARGIN: 0px">
            ilGenerator.EmitCall(<span style="COLOR: teal">OpCodes</span>.Callvirt,
propInfo.GetSetMethod(), <span style="COLOR: blue">null</span>);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
terminates the call</span></p>
          <p style="MARGIN: 0px">
            ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ret);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
converts the DynamicMethod to a FastPropertyGetHandler delegate to get the property</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">FastPropertySetHandler</span> setter
= (<span style="COLOR: teal">FastPropertySetHandler</span>)dynamicMethod.CreateDelegate(<span style="COLOR: blue">typeof</span>(<span style="COLOR: teal">FastPropertySetHandler</span>));
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">return</span> setter;
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;summary&gt;</span><span style="COLOR: green">Emits
the cast to a reference, unboxing if needed.</span><span style="COLOR: gray">&lt;/summary&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;param
name="il"&gt;</span><span style="COLOR: green">The MSIL generator.</span><span style="COLOR: gray">&lt;/param&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;param
name="type"&gt;</span><span style="COLOR: green">The type to cast.</span><span style="COLOR: gray">&lt;/param&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">private</span><span style="COLOR: blue">static</span><span style="COLOR: blue">void</span> EmitCastToReference(<span style="COLOR: teal">ILGenerator</span> ilGenerator,
System.<span style="COLOR: teal">Type</span> type)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> (type.IsValueType)
{
</p>
          <p style="MARGIN: 0px">
                ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Unbox_Any,
type);
</p>
          <p style="MARGIN: 0px">
            } <span style="COLOR: blue">else</span> {
</p>
          <p style="MARGIN: 0px">
                ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Castclass,
type);
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;summary&gt;</span><span style="COLOR: green">Boxes
a type if needed.</span><span style="COLOR: gray">&lt;/summary&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;param
name="ilGenerator"&gt;</span><span style="COLOR: green">The MSIL generator.</span><span style="COLOR: gray">&lt;/param&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;param
name="type"&gt;</span><span style="COLOR: green">The type.</span><span style="COLOR: gray">&lt;/param&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">private</span><span style="COLOR: blue">static</span><span style="COLOR: blue">void</span> EmitBoxIfNeeded(<span style="COLOR: teal">ILGenerator</span> ilGenerator,
System.<span style="COLOR: teal">Type</span> type)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> (type.IsValueType)
{
</p>
          <p style="MARGIN: 0px">
                ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Box,
type);
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;summary&gt;</span><span style="COLOR: green">Emits
code to save an integer to the evaluation stack.</span><span style="COLOR: gray">&lt;/summary&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;param
name="ilGeneartor"&gt;</span><span style="COLOR: green">The MSIL generator.</span><span style="COLOR: gray">&lt;/param&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: gray">///</span><span style="COLOR: green"></span><span style="COLOR: gray">&lt;param
name="value"&gt;</span><span style="COLOR: green">The value to push.</span><span style="COLOR: gray">&lt;/param&gt;</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">private</span><span style="COLOR: blue">static</span><span style="COLOR: blue">void</span> EmitFastInt(<span style="COLOR: teal">ILGenerator</span> ilGenerator, <span style="COLOR: blue">int</span> value)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
for small integers, emit the proper opcode</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">switch</span> (value)
{
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">case</span> -1:
</p>
          <p style="MARGIN: 0px">
                   
ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldc_I4_M1);
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span>;
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">case</span> 0:
</p>
          <p style="MARGIN: 0px">
                   
ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldc_I4_0);
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span>;
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">case</span> 1:
</p>
          <p style="MARGIN: 0px">
                   
ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldc_I4_1);
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span>;
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">case</span> 2:
</p>
          <p style="MARGIN: 0px">
                   
ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldc_I4_2);
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span>;
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">case</span> 3:
</p>
          <p style="MARGIN: 0px">
                   
ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldc_I4_3);
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span>;
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">case</span> 4:
</p>
          <p style="MARGIN: 0px">
                   
ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldc_I4_4);
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span>;
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">case</span> 5:
</p>
          <p style="MARGIN: 0px">
                   
ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldc_I4_5);
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span>;
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">case</span> 6:
</p>
          <p style="MARGIN: 0px">
                   
ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldc_I4_6);
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span>;
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">case</span> 7:
</p>
          <p style="MARGIN: 0px">
                   
ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldc_I4_7);
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span>;
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">case</span> 8:
</p>
          <p style="MARGIN: 0px">
                   
ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldc_I4_8);
</p>
          <p style="MARGIN: 0px">
                    <span style="COLOR: blue">return</span>;
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
for bigger values emit the short or long opcode</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> (value
&gt; -129 &amp;&amp; value &lt; 128) {
</p>
          <p style="MARGIN: 0px">
                ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldc_I4_S,
(<span style="COLOR: teal">SByte</span>)value);
</p>
          <p style="MARGIN: 0px">
            } <span style="COLOR: blue">else</span> {
</p>
          <p style="MARGIN: 0px">
                ilGenerator.Emit(<span style="COLOR: teal">OpCodes</span>.Ldc_I4,
value);
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <p>
          <!--EndFragment-->
        </p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">using</span> System;
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">using</span> System.Reflection;
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">using</span> System.Reflection.Emit;
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">using</span> System.Collections.Generic;
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">using</span> System.Diagnostics;
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">using</span> Manu.Utils;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">namespace</span> DynamicMethods
</p>
          <p style="MARGIN: 0px">
{
</p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">public</span><span style="COLOR: blue">class</span><span style="COLOR: teal">Program</span></p>
          <p style="MARGIN: 0px">
    {
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">public</span><span style="COLOR: blue">static</span><span style="COLOR: blue">void</span> Main(<span style="COLOR: blue">string</span>[]
args)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
object creation</span></p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">Console</span>.WriteLine(<span style="COLOR: maroon">"------
Object Creation ------"</span>);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            EvaluateMethod(<span style="COLOR: maroon">"direct
- object creation"</span>, <span style="COLOR: blue">delegate</span>() {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: teal">TestClass</span> p
= <span style="COLOR: blue">new</span><span style="COLOR: teal">TestClass</span>();
</p>
          <p style="MARGIN: 0px">
            }, 1000000);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">FastCreateInstanceHandler</span> creator
= <span style="COLOR: teal">DynamicCalls</span>.GetInstanceCreator(<span style="COLOR: blue">typeof</span>(<span style="COLOR: teal">TestClass</span>));
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            EvaluateMethod(<span style="COLOR: maroon">"dynamic
method - object creation"</span>, <span style="COLOR: blue">delegate</span>() {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: teal">TestClass</span> p
= (<span style="COLOR: teal">TestClass</span>)creator.Invoke();
</p>
          <p style="MARGIN: 0px">
            }, 1000000);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            EvaluateMethod(<span style="COLOR: maroon">"reflection
- object creation"</span>, <span style="COLOR: blue">delegate</span>() {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: teal">TestClass</span> p
= (<span style="COLOR: teal">TestClass</span>)<span style="COLOR: teal">Activator</span>.CreateInstance(<span style="COLOR: blue">typeof</span>(<span style="COLOR: teal">TestClass</span>));
</p>
          <p style="MARGIN: 0px">
            }, 1000000);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
property get</span></p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">Console</span>.WriteLine(<span style="COLOR: maroon">"------
Property Get ------"</span>);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">TestClass</span> prod
= <span style="COLOR: blue">new</span><span style="COLOR: teal">TestClass</span>();
</p>
          <p style="MARGIN: 0px">
            prod.Num = 123;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            EvaluateMethod(<span style="COLOR: maroon">"direct
- property get"</span>, <span style="COLOR: blue">delegate</span>() {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">int</span> num
= prod.Num;
</p>
          <p style="MARGIN: 0px">
            }, 1000000);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">PropertyInfo</span> propInfo
= <span style="COLOR: blue">typeof</span>(<span style="COLOR: teal">TestClass</span>).GetProperty(<span style="COLOR: maroon">"Num"</span>);
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">FastPropertyGetHandler</span> getter
= <span style="COLOR: teal">DynamicCalls</span>.GetPropertyGetter(propInfo);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            EvaluateMethod(<span style="COLOR: maroon">"dynamic
method - property get"</span>, <span style="COLOR: blue">delegate</span>() {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">int</span> num
= (<span style="COLOR: blue">int</span>)getter(prod);
</p>
          <p style="MARGIN: 0px">
            }, 1000000);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            EvaluateMethod(<span style="COLOR: maroon">"reflection
- property get"</span>, <span style="COLOR: blue">delegate</span>() {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">int</span> num
= (<span style="COLOR: blue">int</span>)propInfo.GetValue(prod, <span style="COLOR: blue">null</span>);
</p>
          <p style="MARGIN: 0px">
            }, 1000000);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
property set</span></p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">Console</span>.WriteLine(<span style="COLOR: maroon">"------
Property Set ------"</span>);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            EvaluateMethod(<span style="COLOR: maroon">"direct
- property set"</span>, <span style="COLOR: blue">delegate</span>() {
</p>
          <p style="MARGIN: 0px">
                prod.Num
= 33;
</p>
          <p style="MARGIN: 0px">
            }, 1000000);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">FastPropertySetHandler</span> setter
= <span style="COLOR: teal">DynamicCalls</span>.GetPropertySetter(propInfo);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            EvaluateMethod(<span style="COLOR: maroon">"dynamic
method - property set"</span>, <span style="COLOR: blue">delegate</span>() {
</p>
          <p style="MARGIN: 0px">
                setter(prod,
32);
</p>
          <p style="MARGIN: 0px">
            }, 1000000);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            EvaluateMethod(<span style="COLOR: maroon">"reflection
- property set"</span>, <span style="COLOR: blue">delegate</span>() {
</p>
          <p style="MARGIN: 0px">
                propInfo.SetValue(prod,
31, <span style="COLOR: blue">null</span>);
</p>
          <p style="MARGIN: 0px">
            }, 1000000);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
instance method call</span></p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">Console</span>.WriteLine(<span style="COLOR: maroon">"------
Instance Method Call ------"</span>);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            EvaluateMethod(<span style="COLOR: maroon">"direct
- instance method call"</span>, <span style="COLOR: blue">delegate</span>() {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">int</span> result
= prod.Multiply(3, 5);
</p>
          <p style="MARGIN: 0px">
            }, 1000000);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">MethodInfo</span> methodInfo1
= <span style="COLOR: blue">typeof</span>(<span style="COLOR: teal">TestClass</span>).GetMethod(<span style="COLOR: maroon">"Multiply"</span>);
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">FastInvokeHandler</span> fastInvoker1
= <span style="COLOR: teal">DynamicCalls</span>.GetMethodInvoker(methodInfo1);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            EvaluateMethod(<span style="COLOR: maroon">"dynamic
method - instance method call"</span>, <span style="COLOR: blue">delegate</span>()
{
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">int</span> result
= (<span style="COLOR: blue">int</span>)fastInvoker1(prod, <span style="COLOR: blue">new</span><span style="COLOR: blue">object</span>[]
{ 3, 5 });
</p>
          <p style="MARGIN: 0px">
            }, 1000000);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            EvaluateMethod(<span style="COLOR: maroon">"reflection
- instance method call"</span>, <span style="COLOR: blue">delegate</span>() {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">int</span> result
= (<span style="COLOR: blue">int</span>)methodInfo1.Invoke(prod, <span style="COLOR: blue">new</span><span style="COLOR: blue">object</span>[]
{ 3, 5 });
</p>
          <p style="MARGIN: 0px">
            }, 1000000);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
static method call</span></p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">Console</span>.WriteLine(<span style="COLOR: maroon">"------
Static Method Call ------"</span>);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            EvaluateMethod(<span style="COLOR: maroon">"direct
- static method call"</span>, <span style="COLOR: blue">delegate</span>() {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">int</span> result
= <span style="COLOR: teal">TestClass</span>.StaticMultiply(3, 5);
</p>
          <p style="MARGIN: 0px">
            }, 1000000);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">MethodInfo</span> methodInfo2
= <span style="COLOR: blue">typeof</span>(<span style="COLOR: teal">TestClass</span>).GetMethod(<span style="COLOR: maroon">"StaticMultiply"</span>);
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">FastInvokeHandler</span> fastInvoker2
= <span style="COLOR: teal">DynamicCalls</span>.GetMethodInvoker(methodInfo2);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            EvaluateMethod(<span style="COLOR: maroon">"dynamic
method - static method call"</span>, <span style="COLOR: blue">delegate</span>() {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">int</span> result
= (<span style="COLOR: blue">int</span>)fastInvoker2(<span style="COLOR: blue">null</span>, <span style="COLOR: blue">new</span><span style="COLOR: blue">object</span>[]
{ 3, 5 });
</p>
          <p style="MARGIN: 0px">
            }, 1000000);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            EvaluateMethod(<span style="COLOR: maroon">"reflection
- static method call"</span>, <span style="COLOR: blue">delegate</span>() {
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">int</span> result
= (<span style="COLOR: blue">int</span>)methodInfo2.Invoke(<span style="COLOR: blue">null</span>, <span style="COLOR: blue">new</span><span style="COLOR: blue">object</span>[]
{ 3, 5 });
</p>
          <p style="MARGIN: 0px">
            }, 1000000);
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">Console</span>.ReadLine();
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">delegate</span><span style="COLOR: blue">void</span><span style="COLOR: teal">MethodToEvaluate</span>();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
        <span style="COLOR: green">// evaluates a method
the specified number of times and print performance information</span></p>
          <p style="MARGIN: 0px">
        <span style="COLOR: blue">static</span><span style="COLOR: blue">void</span> EvaluateMethod(<span style="COLOR: blue">string</span> testName, <span style="COLOR: teal">MethodToEvaluate</span> method, <span style="COLOR: blue">long</span> times)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">Stopwatch</span> watch
= <span style="COLOR: blue">new</span><span style="COLOR: teal">Stopwatch</span>();
</p>
          <p style="MARGIN: 0px">
            watch.Start();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">for</span> (<span style="COLOR: blue">long</span> i
= 0; i &lt; times; i++) {
</p>
          <p style="MARGIN: 0px">
                method();
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            watch.Stop();
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: teal">Console</span>.WriteLine(testName
+ <span style="COLOR: maroon">": "</span> + watch.ElapsedMilliseconds + <span style="COLOR: maroon">"ms"</span>);
</p>
          <p style="MARGIN: 0px">
        }
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
}
</p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
          <a href="http://www.manuelabadia.com/blog/content/binary/DynamicMethods.zip">DynamicMethods.zip
(5.01 KB)</a>
        </p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=dc72b235-1381-4c91-8706-e36216f49b94" />
      </body>
      <title>Generic method invocation at runtime without using reflection – DynamicMethods</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,dc72b235-1381-4c91-8706-e36216f49b94.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,dc72b235-1381-4c91-8706-e36216f49b94.aspx</link>
      <pubDate>Tue, 04 Jul 2006 23:47:29 GMT</pubDate>
      <description>&lt;p&gt;
&lt;/p&gt;
&lt;p&gt;
Being able to dynamically call an arbitrary method on an object or the ability to
get/set any arbitrary property by name at run time is very important when it comes
to do some generic stuff. In .NET Framework 1.x the only way to do that was using
reflection and that means to do it slow. For simple things or if we don’t have a lot
of concurrent users we can live with it, but sometimes the performance is important
and reflection isn’t an acceptable solution.
&lt;/p&gt;
&lt;p&gt;
Fortunately, the .NET Framework 2.0 introduces a new class that let us to quickly
call an arbitrary method without the overhead of a reflection call. How? Well, the
idea is to generate the same MSIL as the compiler generates when calling a function
but on the fly, and then we obtain a delegate that when called will execute the MSIL
we have just created. This is really useful in a lot of scenarios!
&lt;/p&gt;
&lt;p&gt;
I read something about this in Marc’s blog (&lt;a href="http://musingmarc.blogspot.com/"&gt;http://musingmarc.blogspot.com/&lt;/a&gt;)
but I didn’t have time to look at it in more detail in that moment. Today I read an
article at codeproject that talked about this (&lt;a href="http://www.codeproject.com/useritems/FastMethodInvoker.asp"&gt;http://www.codeproject.com/useritems/FastMethodInvoker.asp&lt;/a&gt;)
so I finally forced myself to spend some time playing with dynamic MSIL code generation
and I’m quite impressed with the possibilities.
&lt;/p&gt;
&lt;p&gt;
If you want to play with this you should download an excellent debugger visualizer
that will let you show the MSIL generated by a DynamicMethod:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blogs.msdn.com/haibo_luo/archive/2005/10/25/484861.aspx"&gt;http://blogs.msdn.com/haibo_luo/archive/2005/10/25/484861.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
I have made a little helper class (based on the codeproject article) that can be used
to replace MethodInfo.Invoke, PropertyInfo.GetValue, PropertyInfo.SetValue and Activator.CreateInstance
that are the reflection methods that I use most often. In order to use it in your
own projects, remember to cache the delegates obtained because every time you call
the CreateDelegate the MSIL generation takes place and that takes some time.
&lt;/p&gt;
&lt;p&gt;
I have also created a simple test to show a comparison between direct calls, reflection
calls and dynamic method calls. The results are here:
&lt;/p&gt;
&lt;p&gt;
------ Object Creation ------&lt;br&gt;
direct - object creation: 63ms&lt;br&gt;
dynamic method - object creation: 86ms&lt;br&gt;
reflection - object creation: 391ms&lt;br&gt;
------ Property Get ------&lt;br&gt;
direct - property get: 21ms&lt;br&gt;
dynamic method - property get: 81ms&lt;br&gt;
reflection - property get: 1849ms&lt;br&gt;
------ Property Set ------&lt;br&gt;
direct - property set: 21ms&lt;br&gt;
dynamic method - property set: 67ms&lt;br&gt;
reflection - property set: 2476ms&lt;br&gt;
------ Instance Method Call ------&lt;br&gt;
direct - instance method call: 24ms&lt;br&gt;
dynamic method - instance method call: 154ms&lt;br&gt;
reflection - instance method call: 3266ms&lt;br&gt;
------ Static Method Call ------&lt;br&gt;
direct - static method call: 36ms&lt;br&gt;
dynamic method - static method call: 157ms&lt;br&gt;
reflection - static method call: 3139ms
&lt;/p&gt;
&lt;p&gt;
To summarize: 
&lt;br&gt;
•&amp;nbsp;For object creation, using reflection is 6.2 times slower than direct object
creation. With DynamicMethods is only 1.3 times slower than direct object creation.
Using DynamicMethods is about 4.5 times faster than using reflection.&lt;br&gt;
•&amp;nbsp;To get a property using reflection is 90.1 times slower than direct property
access. With DynamicMethods is only 3.8 times slower than direct property access.
Using DynamicMethods is nearly 23 times faster than using reflection.&lt;br&gt;
•&amp;nbsp;To set a property using reflection is 117.9 times slower than direct property
set. With DynamicMethods is only 3.2 times slower than direct property set. Using
DynamicMethods is about 37 times faster than using reflection.&lt;br&gt;
•&amp;nbsp;For instance method invocation, using reflection is 136.1 times slower than
direct method call. With DynamicMethods is only 6.4 times slower than direct method
call. Using DynamicMethods is about 21 times faster than using reflection.&lt;br&gt;
•&amp;nbsp;For static method invocation, using reflection is 87.2 times slower than direct
method call. With DynamicMethods is only 4.3 times slower than direct method call.
Using DynamicMethods is about 20 times faster than using reflection.
&lt;/p&gt;
&lt;p&gt;
I’m going to modify my &lt;a href="http://www.manuelabadia.com/products/EODS_features.aspx"&gt;ExtendedObjectDataSource&lt;/a&gt; to
use DynamicMethods in order to gain a 20x speed increase compared to reflection calls.
&lt;/p&gt;
&lt;p&gt;
The code used for the tests and the helper class for the DynamicMethods are shown
here and can be downloaded at the end of this post:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System.Reflection;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System.Reflection.Emit;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;namespace&lt;/span&gt; Manu.Utils
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;span style="COLOR: green"&gt;Delegate
for calling a method that is not known at runtime.&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;&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;param
name="target"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;the object to be called or null
if the call is to a static method.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;param
name="paramters"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;the parameters to the method.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;returns&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;the
return value for the method or null if it doesn't return anything.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/returns&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;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt; &lt;span style="COLOR: blue"&gt;object&lt;/span&gt; &lt;span style="COLOR: teal"&gt;FastInvokeHandler&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; target, &lt;span style="COLOR: blue"&gt;object&lt;/span&gt;[]
parameters);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;span style="COLOR: green"&gt;Delegate
for creating and object at runtime using the default constructor.&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;&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;returns&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;the
newly created object.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/returns&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;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt; &lt;span style="COLOR: blue"&gt;object&lt;/span&gt; &lt;span style="COLOR: teal"&gt;FastCreateInstanceHandler&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;&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;span style="COLOR: green"&gt;Delegate
to get an arbitraty property at runtime.&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;&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;param
name="target"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;the object instance whose property
will be obtained.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;returns&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;the
property value.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/returns&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;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt; &lt;span style="COLOR: blue"&gt;object&lt;/span&gt; &lt;span style="COLOR: teal"&gt;FastPropertyGetHandler&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; target);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;span style="COLOR: green"&gt;Delegate
to set an arbitrary property at runtime.&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;&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;param
name="target"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;the object instance whose property
will be modified.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;param
name="parameter"&amp;gt;&amp;lt;/param&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;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; &lt;span style="COLOR: teal"&gt;FastPropertySetHandler&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt; target, &lt;span style="COLOR: blue"&gt;object&lt;/span&gt; parameter);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&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;span style="COLOR: green"&gt;Class
with helper methods for dynamic invocation generating IL on the fly.&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;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;class&lt;/span&gt; &lt;span style="COLOR: teal"&gt;DynamicCalls&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;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: teal"&gt;FastInvokeHandler&lt;/span&gt; GetMethodInvoker(&lt;span style="COLOR: teal"&gt;MethodInfo&lt;/span&gt; methodInfo)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
generates a dynamic method to generate a FastInvokeHandler delegate&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;DynamicMethod&lt;/span&gt; dynamicMethod
= &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;DynamicMethod&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;.Empty, &lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;), &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;Type&lt;/span&gt;[]
{ &lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;), &lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;[])
}, methodInfo.DeclaringType.Module);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;ILGenerator&lt;/span&gt; ilGenerator
= dynamicMethod.GetILGenerator();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;ParameterInfo&lt;/span&gt;[]
parameters = methodInfo.GetParameters();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Type&lt;/span&gt;[]
paramTypes = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;Type&lt;/span&gt;[parameters.Length];
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
copies the parameter types to an array&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;for&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;int&lt;/span&gt; i
= 0; i &amp;lt; paramTypes.Length; i++) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (parameters[i].ParameterType.IsByRef)
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
paramTypes[i] = parameters[i].ParameterType.GetElementType();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
paramTypes[i] = parameters[i].ParameterType;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;LocalBuilder&lt;/span&gt;[]
locals = &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;LocalBuilder&lt;/span&gt;[paramTypes.Length];
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
generates a local variable for each parameter&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;for&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;int&lt;/span&gt; i
= 0; i &amp;lt; paramTypes.Length; i++) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; locals[i]
= ilGenerator.DeclareLocal(paramTypes[i], &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;&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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
creates code to copy the parameters to the local variables&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;for&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;int&lt;/span&gt; i
= 0; i &amp;lt; paramTypes.Length; i++) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldarg_1);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EmitFastInt(ilGenerator,
i);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldelem_Ref);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EmitCastToReference(ilGenerator,
paramTypes[i]);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Stloc,
locals[i]);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (!methodInfo.IsStatic)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
loads the object into the stack&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldarg_0);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
loads the parameters copied to the local variables into the stack&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;for&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;int&lt;/span&gt; i
= 0; i &amp;lt; paramTypes.Length; i++) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (parameters[i].ParameterType.IsByRef)
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldloca_S, locals[i]);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldloc, locals[i]);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
calls the method&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (!methodInfo.IsStatic)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.EmitCall(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Callvirt,
methodInfo, &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.EmitCall(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Call,
methodInfo, &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
creates code for handling the return value&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (methodInfo.ReturnType
== &lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;void&lt;/span&gt;))
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldnull);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EmitBoxIfNeeded(ilGenerator,
methodInfo.ReturnType);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
iterates through the parameters updating the parameters passed by ref&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;for&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;int&lt;/span&gt; i
= 0; i &amp;lt; paramTypes.Length; i++) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (parameters[i].ParameterType.IsByRef)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldarg_1);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
EmitFastInt(ilGenerator, i);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldloc, locals[i]);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (locals[i].LocalType.IsValueType)
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
&amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Box,
locals[i].LocalType);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Stelem_Ref);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
returns the value to the caller&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ret);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
converts the DynamicMethod to a FastInvokeHandler delegate to call to the method&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;FastInvokeHandler&lt;/span&gt; invoker
= (&lt;span style="COLOR: teal"&gt;FastInvokeHandler&lt;/span&gt;)dynamicMethod.CreateDelegate(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: teal"&gt;FastInvokeHandler&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; invoker;
&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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;span style="COLOR: green"&gt;Gets
the instance creator delegate that can be use to create instances of the specified
type.&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;&amp;nbsp; &amp;nbsp;&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;param
name="type"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;The type of the objects we want to
create.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;returns&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;A
delegate that can be used to create the objects.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/returns&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: teal"&gt;FastCreateInstanceHandler&lt;/span&gt; GetInstanceCreator(&lt;span style="COLOR: teal"&gt;Type&lt;/span&gt; type)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
generates a dynamic method to generate a FastCreateInstanceHandler delegate&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;DynamicMethod&lt;/span&gt; dynamicMethod
= &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;DynamicMethod&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;.Empty,
type, &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;Type&lt;/span&gt;[0], &lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: teal"&gt;DynamicCalls&lt;/span&gt;).Module);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;ILGenerator&lt;/span&gt; ilGenerator
= dynamicMethod.GetILGenerator();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
generates code to create a new object of the specified type using the default constructor&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Newobj,
type.GetConstructor(&lt;span style="COLOR: teal"&gt;Type&lt;/span&gt;.EmptyTypes));
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
returns the value to the caller&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ret);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
converts the DynamicMethod to a FastCreateInstanceHandler delegate to create the object&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;FastCreateInstanceHandler&lt;/span&gt; creator
= (&lt;span style="COLOR: teal"&gt;FastCreateInstanceHandler&lt;/span&gt;)dynamicMethod.CreateDelegate(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: teal"&gt;FastCreateInstanceHandler&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; creator;
&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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: teal"&gt;FastPropertyGetHandler&lt;/span&gt; GetPropertyGetter(&lt;span style="COLOR: teal"&gt;PropertyInfo&lt;/span&gt; propInfo)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
generates a dynamic method to generate a FastPropertyGetHandler delegate&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;DynamicMethod&lt;/span&gt; dynamicMethod
= &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;DynamicMethod&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;.Empty, &lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;), &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;Type&lt;/span&gt;[]
{ &lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;)
}, propInfo.DeclaringType.Module);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;ILGenerator&lt;/span&gt; ilGenerator
= dynamicMethod.GetILGenerator();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
loads the object into the stack&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldarg_0);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
calls the getter&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.EmitCall(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Callvirt,
propInfo.GetGetMethod(), &lt;span style="COLOR: blue"&gt;null&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
creates code for handling the return value&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EmitBoxIfNeeded(ilGenerator,
propInfo.PropertyType);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
returns the value to the caller&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ret);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
converts the DynamicMethod to a FastPropertyGetHandler delegate to get the property&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;FastPropertyGetHandler&lt;/span&gt; getter
= (&lt;span style="COLOR: teal"&gt;FastPropertyGetHandler&lt;/span&gt;)dynamicMethod.CreateDelegate(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: teal"&gt;FastPropertyGetHandler&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; getter;
&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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: teal"&gt;FastPropertySetHandler&lt;/span&gt; GetPropertySetter(&lt;span style="COLOR: teal"&gt;PropertyInfo&lt;/span&gt; propInfo)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
generates a dynamic method to generate a FastPropertySetHandler delegate&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;DynamicMethod&lt;/span&gt; dynamicMethod
= &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;DynamicMethod&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;.Empty, &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;Type&lt;/span&gt;[]
{ &lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;), &lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: blue"&gt;object&lt;/span&gt;)
}, propInfo.DeclaringType.Module);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;ILGenerator&lt;/span&gt; ilGenerator
= dynamicMethod.GetILGenerator();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
loads the object into the stack&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldarg_0);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
loads the parameter from the stack&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldarg_1);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
cast to the proper type (unboxing if needed)&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EmitCastToReference(ilGenerator,
propInfo.PropertyType);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
calls the setter&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.EmitCall(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Callvirt,
propInfo.GetSetMethod(), &lt;span style="COLOR: blue"&gt;null&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
terminates the call&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ret);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
converts the DynamicMethod to a FastPropertyGetHandler delegate to get the property&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;FastPropertySetHandler&lt;/span&gt; setter
= (&lt;span style="COLOR: teal"&gt;FastPropertySetHandler&lt;/span&gt;)dynamicMethod.CreateDelegate(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: teal"&gt;FastPropertySetHandler&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;return&lt;/span&gt; setter;
&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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;span style="COLOR: green"&gt;Emits
the cast to a reference, unboxing if needed.&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;&amp;nbsp; &amp;nbsp;&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;param
name="il"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;The MSIL generator.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;param
name="type"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;The type to cast.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; EmitCastToReference(&lt;span style="COLOR: teal"&gt;ILGenerator&lt;/span&gt; ilGenerator,
System.&lt;span style="COLOR: teal"&gt;Type&lt;/span&gt; type)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (type.IsValueType)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Unbox_Any,
type);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Castclass,
type);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&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;&amp;nbsp; &amp;nbsp;&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;span style="COLOR: green"&gt;Boxes
a type if needed.&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;&amp;nbsp; &amp;nbsp;&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;param
name="ilGenerator"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;The MSIL generator.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;param
name="type"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;The type.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; EmitBoxIfNeeded(&lt;span style="COLOR: teal"&gt;ILGenerator&lt;/span&gt; ilGenerator,
System.&lt;span style="COLOR: teal"&gt;Type&lt;/span&gt; type)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (type.IsValueType)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Box,
type);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&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;&amp;nbsp; &amp;nbsp;&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;span style="COLOR: green"&gt;Emits
code to save an integer to the evaluation stack.&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;&amp;nbsp; &amp;nbsp;&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;param
name="ilGeneartor"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;The MSIL generator.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;param
name="value"&amp;gt;&lt;/span&gt;&lt;span style="COLOR: green"&gt;The value to push.&lt;/span&gt;&lt;span style="COLOR: gray"&gt;&amp;lt;/param&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;private&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; EmitFastInt(&lt;span style="COLOR: teal"&gt;ILGenerator&lt;/span&gt; ilGenerator, &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; value)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
for small integers, emit the proper opcode&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;switch&lt;/span&gt; (value)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;case&lt;/span&gt; -1:
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldc_I4_M1);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;case&lt;/span&gt; 0:
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldc_I4_0);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;case&lt;/span&gt; 1:
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldc_I4_1);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;case&lt;/span&gt; 2:
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldc_I4_2);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;case&lt;/span&gt; 3:
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldc_I4_3);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;case&lt;/span&gt; 4:
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldc_I4_4);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;case&lt;/span&gt; 5:
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldc_I4_5);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;case&lt;/span&gt; 6:
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldc_I4_6);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;case&lt;/span&gt; 7:
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldc_I4_7);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&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; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;case&lt;/span&gt; 8:
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldc_I4_8);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&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; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
for bigger values emit the short or long opcode&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (value
&amp;gt; -129 &amp;amp;&amp;amp; value &amp;lt; 128) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldc_I4_S,
(&lt;span style="COLOR: teal"&gt;SByte&lt;/span&gt;)value);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ilGenerator.Emit(&lt;span style="COLOR: teal"&gt;OpCodes&lt;/span&gt;.Ldc_I4,
value);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System.Reflection;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System.Reflection.Emit;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; System.Diagnostics;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;using&lt;/span&gt; Manu.Utils;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;namespace&lt;/span&gt; DynamicMethods
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;Program&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;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;public&lt;/span&gt; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; Main(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt;[]
args)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
object creation&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="COLOR: maroon"&gt;"------
Object Creation ------"&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EvaluateMethod(&lt;span style="COLOR: maroon"&gt;"direct
- object creation"&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt;() {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;TestClass&lt;/span&gt; p
= &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;TestClass&lt;/span&gt;();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }, 1000000);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;FastCreateInstanceHandler&lt;/span&gt; creator
= &lt;span style="COLOR: teal"&gt;DynamicCalls&lt;/span&gt;.GetInstanceCreator(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: teal"&gt;TestClass&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EvaluateMethod(&lt;span style="COLOR: maroon"&gt;"dynamic
method - object creation"&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt;() {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;TestClass&lt;/span&gt; p
= (&lt;span style="COLOR: teal"&gt;TestClass&lt;/span&gt;)creator.Invoke();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }, 1000000);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EvaluateMethod(&lt;span style="COLOR: maroon"&gt;"reflection
- object creation"&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt;() {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;TestClass&lt;/span&gt; p
= (&lt;span style="COLOR: teal"&gt;TestClass&lt;/span&gt;)&lt;span style="COLOR: teal"&gt;Activator&lt;/span&gt;.CreateInstance(&lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: teal"&gt;TestClass&lt;/span&gt;));
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }, 1000000);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
property 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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="COLOR: maroon"&gt;"------
Property 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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;TestClass&lt;/span&gt; prod
= &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;TestClass&lt;/span&gt;();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; prod.Num = 123;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EvaluateMethod(&lt;span style="COLOR: maroon"&gt;"direct
- property get"&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt;() {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; num
= prod.Num;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }, 1000000);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;PropertyInfo&lt;/span&gt; propInfo
= &lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: teal"&gt;TestClass&lt;/span&gt;).GetProperty(&lt;span style="COLOR: maroon"&gt;"Num"&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;FastPropertyGetHandler&lt;/span&gt; getter
= &lt;span style="COLOR: teal"&gt;DynamicCalls&lt;/span&gt;.GetPropertyGetter(propInfo);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EvaluateMethod(&lt;span style="COLOR: maroon"&gt;"dynamic
method - property get"&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt;() {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; num
= (&lt;span style="COLOR: blue"&gt;int&lt;/span&gt;)getter(prod);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }, 1000000);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EvaluateMethod(&lt;span style="COLOR: maroon"&gt;"reflection
- property get"&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt;() {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; num
= (&lt;span style="COLOR: blue"&gt;int&lt;/span&gt;)propInfo.GetValue(prod, &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }, 1000000);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
property 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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="COLOR: maroon"&gt;"------
Property 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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EvaluateMethod(&lt;span style="COLOR: maroon"&gt;"direct
- property set"&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt;() {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; prod.Num
= 33;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }, 1000000);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;FastPropertySetHandler&lt;/span&gt; setter
= &lt;span style="COLOR: teal"&gt;DynamicCalls&lt;/span&gt;.GetPropertySetter(propInfo);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EvaluateMethod(&lt;span style="COLOR: maroon"&gt;"dynamic
method - property set"&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt;() {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; setter(prod,
32);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }, 1000000);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EvaluateMethod(&lt;span style="COLOR: maroon"&gt;"reflection
- property set"&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt;() {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; propInfo.SetValue(prod,
31, &lt;span style="COLOR: blue"&gt;null&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }, 1000000);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
instance method call&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="COLOR: maroon"&gt;"------
Instance Method Call ------"&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EvaluateMethod(&lt;span style="COLOR: maroon"&gt;"direct
- instance method call"&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt;() {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; result
= prod.Multiply(3, 5);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }, 1000000);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;MethodInfo&lt;/span&gt; methodInfo1
= &lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: teal"&gt;TestClass&lt;/span&gt;).GetMethod(&lt;span style="COLOR: maroon"&gt;"Multiply"&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;FastInvokeHandler&lt;/span&gt; fastInvoker1
= &lt;span style="COLOR: teal"&gt;DynamicCalls&lt;/span&gt;.GetMethodInvoker(methodInfo1);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EvaluateMethod(&lt;span style="COLOR: maroon"&gt;"dynamic
method - instance method call"&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt;()
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; result
= (&lt;span style="COLOR: blue"&gt;int&lt;/span&gt;)fastInvoker1(prod, &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: blue"&gt;object&lt;/span&gt;[]
{ 3, 5 });
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }, 1000000);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EvaluateMethod(&lt;span style="COLOR: maroon"&gt;"reflection
- instance method call"&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt;() {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; result
= (&lt;span style="COLOR: blue"&gt;int&lt;/span&gt;)methodInfo1.Invoke(prod, &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: blue"&gt;object&lt;/span&gt;[]
{ 3, 5 });
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }, 1000000);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
static method call&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Console&lt;/span&gt;.WriteLine(&lt;span style="COLOR: maroon"&gt;"------
Static Method Call ------"&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EvaluateMethod(&lt;span style="COLOR: maroon"&gt;"direct
- static method call"&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt;() {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; result
= &lt;span style="COLOR: teal"&gt;TestClass&lt;/span&gt;.StaticMultiply(3, 5);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }, 1000000);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;MethodInfo&lt;/span&gt; methodInfo2
= &lt;span style="COLOR: blue"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: teal"&gt;TestClass&lt;/span&gt;).GetMethod(&lt;span style="COLOR: maroon"&gt;"StaticMultiply"&lt;/span&gt;);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;FastInvokeHandler&lt;/span&gt; fastInvoker2
= &lt;span style="COLOR: teal"&gt;DynamicCalls&lt;/span&gt;.GetMethodInvoker(methodInfo2);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EvaluateMethod(&lt;span style="COLOR: maroon"&gt;"dynamic
method - static method call"&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt;() {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; result
= (&lt;span style="COLOR: blue"&gt;int&lt;/span&gt;)fastInvoker2(&lt;span style="COLOR: blue"&gt;null&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: blue"&gt;object&lt;/span&gt;[]
{ 3, 5 });
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }, 1000000);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; EvaluateMethod(&lt;span style="COLOR: maroon"&gt;"reflection
- static method call"&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt;() {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;int&lt;/span&gt; result
= (&lt;span style="COLOR: blue"&gt;int&lt;/span&gt;)methodInfo2.Invoke(&lt;span style="COLOR: blue"&gt;null&lt;/span&gt;, &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: blue"&gt;object&lt;/span&gt;[]
{ 3, 5 });
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }, 1000000);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Console&lt;/span&gt;.ReadLine();
&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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;delegate&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; &lt;span style="COLOR: teal"&gt;MethodToEvaluate&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;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;// evaluates a method
the specified number of times and print performance information&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;static&lt;/span&gt; &lt;span style="COLOR: blue"&gt;void&lt;/span&gt; EvaluateMethod(&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; testName, &lt;span style="COLOR: teal"&gt;MethodToEvaluate&lt;/span&gt; method, &lt;span style="COLOR: blue"&gt;long&lt;/span&gt; times)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Stopwatch&lt;/span&gt; watch
= &lt;span style="COLOR: blue"&gt;new&lt;/span&gt; &lt;span style="COLOR: teal"&gt;Stopwatch&lt;/span&gt;();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; watch.Start();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;for&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;long&lt;/span&gt; i
= 0; i &amp;lt; times; i++) {
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; method();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &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;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; watch.Stop();
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;Console&lt;/span&gt;.WriteLine(testName
+ &lt;span style="COLOR: maroon"&gt;": "&lt;/span&gt; + watch.ElapsedMilliseconds + &lt;span style="COLOR: maroon"&gt;"ms"&lt;/span&gt;);
&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;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.manuelabadia.com/blog/content/binary/DynamicMethods.zip"&gt;DynamicMethods.zip
(5.01 KB)&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=dc72b235-1381-4c91-8706-e36216f49b94" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,dc72b235-1381-4c91-8706-e36216f49b94.aspx</comments>
      <category>ASP.NET;Microsoft .NET Framework</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=9f82b3ce-616a-4bda-a4b5-4bd59a2448a7</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,9f82b3ce-616a-4bda-a4b5-4bd59a2448a7.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,9f82b3ce-616a-4bda-a4b5-4bd59a2448a7.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=9f82b3ce-616a-4bda-a4b5-4bd59a2448a7</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
A friend recommended me to read the book “POJOs in action: Developing Enterprise Applications
with Lightweight Frameworks”. In case you haven’t heard what a POJO is, it’s an acronym
that stands for Plain Old Java Objects. Of course, my first reaction was that it was
a Java book not a .net book but he told me that the book is about generic concepts
that could be used in .net without much trouble so I purchased the book:
</p>
        <br />
        <iframe style="WIDTH: 120px; HEIGHT: 240px" marginwidth="0" marginheight="0" src="http://rcm.amazon.com/e/cm?t=manuelabadias-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=1932394583&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000ff&amp;bc1=000000&amp;bg1=ffffff&amp;f=ifr" frameborder="0" scrolling="no">
        </iframe>
        <br />
        <p>
This book complements Fowler’s Enterprise Architectural Patterns[1] as it is more
practical and it has a lot of samples. The author (Chris Richardson) explains his
methodology to build enterprise applications using test driven development.
</p>
        <p>
I haven’t used Java since 2001 and I didn’t have any problem following the book. If
you are not a Java expert you can still read the book ignoring the comments about
EJB. A little of background of JSP and Servlets is usefull when talking about the
presentation layer but you can understand most of the content without it. The author
uses a lot of Java tools/frameworks that have an equivalent counterpart in the .net
world (NUnit, NMock, NHibernate, Spring Framework .net, etc) so even if there are
some differences between the Java and the .net versions the information provided is
useful.
</p>
        <p>
The first pages of the book are about the decisions to make when building an
application (organizing the business logic, encapsulating the business logic, accessing
the database, handling concurrency in database transactions and handling concurrency
in long transactions), and the rest of the book elaborates more on the usual strategies
chosen in the design (OO domain model with O/R mapping) and some variations (transaction
scripts, exposed domain model). When the author explains a topic it provides useful
samples and the pros and cons of using one approach versus other approaches.
</p>
        <p>
The O/R mapping material is very good and details the inner workings of JDO (AFAIK
a Java only O/R mapper so I skipped most sections about it) and Hibernate. Also there
is a chapter about complex search forms and how to make dynamic paged queries in order
to retrieve data as fast as possible and integrate those queries with Hibernate.
</p>
        <p>
The last part of the book is about concurrency in short and long transactions and
I found it quite useful as in most applications I’ve seen don’t do anything about
concurrency conflicts in long running transactions and the book has code explaining
how to implement it where other books only give guidelines.
</p>
        <p>
After reading the book I have added to my long TODO list to take a look to the spring
framework so if somebody that reads this wants to share his experiences with it feel
free to send me an email or post a comment.
</p>
        <p>
        </p>
        <br />
[1] Fowler's book<br /><iframe style="WIDTH: 120px; HEIGHT: 240px" marginwidth="0" marginheight="0" src="http://rcm.amazon.com/e/cm?t=manuelabadias-20&amp;o=1&amp;p=8&amp;l=as1&amp;asins=0321127420&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000ff&amp;bc1=000000&amp;bg1=ffffff&amp;f=ifr" frameborder="0" scrolling="no"></iframe><img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=9f82b3ce-616a-4bda-a4b5-4bd59a2448a7" /></body>
      <title>Review of POJOs in action: Developing Enterprise Applications with Lightweight Frameworks</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,9f82b3ce-616a-4bda-a4b5-4bd59a2448a7.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,9f82b3ce-616a-4bda-a4b5-4bd59a2448a7.aspx</link>
      <pubDate>Wed, 28 Jun 2006 12:16:47 GMT</pubDate>
      <description>&lt;p&gt;
A friend recommended me to read the book “POJOs in action: Developing Enterprise Applications
with Lightweight Frameworks”. In case you haven’t heard what a POJO is, it’s an acronym
that stands for Plain Old Java Objects. Of course, my first reaction was that it was
a Java book not a .net book but he told me that the book is about generic concepts
that could be used in .net without much trouble so I purchased the book:
&lt;/p&gt;
&lt;br&gt;
&lt;iframe style="WIDTH: 120px; HEIGHT: 240px" marginwidth=0 marginheight=0 src="http://rcm.amazon.com/e/cm?t=manuelabadias-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=1932394583&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;lc1=0000ff&amp;amp;bc1=000000&amp;amp;bg1=ffffff&amp;amp;f=ifr" frameborder=0 scrolling=no&gt;
&lt;/iframe&gt;
&lt;br&gt;
&lt;p&gt;
This book complements Fowler’s Enterprise Architectural Patterns[1] as it is more
practical and it has a lot of samples. The author (Chris Richardson) explains his
methodology to build enterprise applications using test driven development.
&lt;/p&gt;
&lt;p&gt;
I haven’t used Java since 2001 and I didn’t have any problem following the book. If
you are not a Java expert you can still read the book ignoring the comments about
EJB. A little of background of JSP and Servlets is usefull when talking about the
presentation layer but you can understand most of the content without it. The author
uses a lot of Java tools/frameworks that have an equivalent counterpart in the .net
world (NUnit, NMock, NHibernate, Spring Framework .net, etc) so even if there are
some differences between the Java and the .net versions the information provided is
useful.
&lt;/p&gt;
&lt;p&gt;
The first pages of the book&amp;nbsp;are about the decisions to make when building an
application (organizing the business logic, encapsulating the business logic, accessing
the database, handling concurrency in database transactions and handling concurrency
in long transactions), and the rest of the book elaborates more on the usual strategies
chosen in the design (OO domain model with O/R mapping) and some variations (transaction
scripts, exposed domain model). When the author explains a topic it provides useful
samples and the pros and cons of using one approach versus other approaches.
&lt;/p&gt;
&lt;p&gt;
The O/R mapping material is very good and details the inner workings of JDO (AFAIK
a Java only O/R mapper so I skipped most sections about it) and Hibernate. Also there
is a chapter about complex search forms and how to make dynamic paged queries in order
to retrieve data as fast as possible and integrate those queries with Hibernate.
&lt;/p&gt;
&lt;p&gt;
The last part of the book is about concurrency in short and long transactions and
I found it quite useful as in most applications I’ve seen don’t do anything about
concurrency conflicts in long running transactions and the book has code explaining
how to implement it where other books only give guidelines.
&lt;/p&gt;
&lt;p&gt;
After reading the book I have added to my long TODO list to take a look to the spring
framework so if somebody that reads this wants to share his experiences with it feel
free to send me an email or post a comment.
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;br&gt;
[1] Fowler's book&lt;br&gt;
&lt;iframe style="WIDTH: 120px; HEIGHT: 240px" marginwidth=0 marginheight=0 src="http://rcm.amazon.com/e/cm?t=manuelabadias-20&amp;amp;o=1&amp;amp;p=8&amp;amp;l=as1&amp;amp;asins=0321127420&amp;amp;fc1=000000&amp;amp;IS2=1&amp;amp;lt1=_blank&amp;amp;lc1=0000ff&amp;amp;bc1=000000&amp;amp;bg1=ffffff&amp;amp;f=ifr" frameborder=0 scrolling=no&gt;
&lt;/iframe&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=9f82b3ce-616a-4bda-a4b5-4bd59a2448a7" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,9f82b3ce-616a-4bda-a4b5-4bd59a2448a7.aspx</comments>
      <category>ASP.NET;Microsoft .NET Framework</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=e8e0c020-f9d3-4174-a0e0-2f55ff29f565</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,e8e0c020-f9d3-4174-a0e0-2f55ff29f565.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,e8e0c020-f9d3-4174-a0e0-2f55ff29f565.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=e8e0c020-f9d3-4174-a0e0-2f55ff29f565</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
First I have to apologize for not posting anything in nearly two weeks, but a lot
of things have happened lately: I did a quick work (a week) for Namco Mobile; I have
been two days in bed with temperature; I did a Reiki first degree course; too much
work in the last days and a lot more to come until august…
</p>
        <p>
I read somewhere that Microsoft .NET Framework 3.0 will be released at the end of
the year. Even if it is not a complete change of the .NET Framework 2.0 and can be
seen as .NET Framework 2.0 + Windows Presentation Foundation (WPF) + Windows Communication
Foundation (WCF) + Windows Workflow Foundation (WF) + Windows CardSpace (WCS) it is
kind of a pain to be learning version 2.0 and have a new release before mastering
.NET Framework 2.0. If you add Atlas to the mix the conclusion is: “Too many things
to learn and no time to do it!”. I hope we can live with .NET Framework 3.0 for a
few years. 
</p>
        <p>
I don’t know what happens in other cities/countries but most of the companies here
are still using .NET 1.x and probably a lot of them will still be using it when .NET
3.0 is released…
</p>
        <p>
Talking about other things, I have started to add full design time support to the
ExtendedObjectDataSource package and this is what I have at the moment:
</p>
        <p>
          <img height="451" alt="Design time wizard" src="http://www.manuelabadia.com/blog/content/binary/CODS_designtime1.gif" width="581" border="0" />
        </p>
        <p>
          <img height="451" alt="Design time wizard" src="http://www.manuelabadia.com/blog/content/binary/CODS_designtime2.gif" width="581" border="0" />
        </p>
        <p>
          <br />
As you can see I have added more options that are not present in the standard ObjectDataSource
like being able to configure paging in the wizard and also being able to choose also
the SelectCountMethod (for the CompatObjectDataSource. The ExtendedObjectDataSource
can extract the total row count in the SelectMethod).
</p>
        <p>
If somebody misses something in the wizard let me know ASAP so I can think of including
it.
</p>
        <p>
Every time I have to use Winforms I really hate the poor control set that is available
(at least in version 2.0 you have a menu that does not look like it was made for windows
95 :-P). I can’t believe that the framework didn’t ship with a wizard control so I
had to waste my time coding one.
</p>
        <p>
To finish this post, I’ll tell you a cool tip to debug design time stuff. Forget everything
that you did to set up the project to debug design time classes. You’ll have a debugger
attached to the current Visual Studio instance and awaiting your orders if you add
this line of code where you want the debugger to show up:
</p>
        <p>
System.Diagnostics.Debugger.Launch();
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=e8e0c020-f9d3-4174-a0e0-2f55ff29f565" />
      </body>
      <title>Microsoft .NET Framework 3.0, Design time stuff and more</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,e8e0c020-f9d3-4174-a0e0-2f55ff29f565.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,e8e0c020-f9d3-4174-a0e0-2f55ff29f565.aspx</link>
      <pubDate>Sun, 18 Jun 2006 22:49:35 GMT</pubDate>
      <description>&lt;p&gt;
First I have to apologize for not posting anything in nearly two weeks, but a lot
of things have happened lately: I did a quick work (a week) for Namco Mobile; I have
been two days in bed with temperature; I did a Reiki first degree course; too much
work in the last days and a lot more to come until august…
&lt;/p&gt;
&lt;p&gt;
I read somewhere that Microsoft .NET Framework 3.0 will be released at the end of
the year. Even if it is not a complete change of the .NET Framework 2.0 and can be
seen as .NET Framework 2.0 + Windows Presentation Foundation (WPF) + Windows Communication
Foundation (WCF) + Windows Workflow Foundation (WF) + Windows CardSpace (WCS) it is
kind of a pain to be learning version 2.0 and have a new release before mastering
.NET Framework 2.0. If you add Atlas to the mix the conclusion is: “Too many things
to learn and no time to do it!”. I hope we can live with .NET Framework 3.0 for a
few years. 
&lt;/p&gt;
&lt;p&gt;
I don’t know what happens in other cities/countries but most of the companies here
are still using .NET 1.x and probably a lot of them will still be using it when .NET
3.0 is released…
&lt;/p&gt;
&lt;p&gt;
Talking about other things, I have started to add full design time support to the
ExtendedObjectDataSource package and this is what I have at the moment:
&lt;/p&gt;
&lt;p&gt;
&lt;img height=451 alt="Design time wizard" src="http://www.manuelabadia.com/blog/content/binary/CODS_designtime1.gif" width=581 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img height=451 alt="Design time wizard" src="http://www.manuelabadia.com/blog/content/binary/CODS_designtime2.gif" width=581 border=0&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;br&gt;
As you can see I have added more options that are not present in the standard ObjectDataSource
like being able to configure paging in the wizard and also being able to choose also
the SelectCountMethod (for the CompatObjectDataSource. The ExtendedObjectDataSource
can extract the total row count in the SelectMethod).
&lt;/p&gt;
&lt;p&gt;
If somebody misses something in the wizard let me know ASAP so I can think of including
it.
&lt;/p&gt;
&lt;p&gt;
Every time I have to use Winforms I really hate the poor control set that is available
(at least in version 2.0 you have a menu that does not look like it was made for windows
95 :-P). I can’t believe that the framework didn’t ship with a wizard control so I
had to waste my time coding one.
&lt;/p&gt;
&lt;p&gt;
To finish this post, I’ll tell you a cool tip to debug design time stuff. Forget everything
that you did to set up the project to debug design time classes. You’ll have a debugger
attached to the current Visual Studio instance and awaiting your orders if you add
this line of code where you want the debugger to show up:
&lt;/p&gt;
&lt;p&gt;
System.Diagnostics.Debugger.Launch();
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=e8e0c020-f9d3-4174-a0e0-2f55ff29f565" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,e8e0c020-f9d3-4174-a0e0-2f55ff29f565.aspx</comments>
      <category>ASP.NET;General;Microsoft .NET Framework</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=e5d64c7a-2380-4708-875b-9e24872d4f83</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,e5d64c7a-2380-4708-875b-9e24872d4f83.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,e5d64c7a-2380-4708-875b-9e24872d4f83.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=e5d64c7a-2380-4708-875b-9e24872d4f83</wfw:commentRss>
      <slash:comments>2</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
When I started learning ASP.NET 2.0 I noticed that the component tray was taken out
of the designer and somewhat the concept of component (in ASP.NET 1.x) was obsolete
and did not apply in ASP.NET 2.0.
</p>
        <p>
I was very angry with the new direction taken about this when I found this post by
Nikhil Kothari’s (an ASP.NET dev. team member):
</p>
        <p>
          <a href="http://www.nikhilk.net/NonVisualControlsAndComponents.aspx">http://www.nikhilk.net/NonVisualControlsAndComponents.aspx</a>
        </p>
        <p>
that explains some of the problems found when implementing the new data source controls
in asp.net 2.0. Even they do not render any mark-up, they need to participate in the
page life cycle, so the old concept of component and the old model of persisting components
in the code behind file wasn’t working for this. Anyway, I had the idea that data
source controls should not appear with the rest of the controls in the page and I
didn’t liked the current implementation that shows the data source controls located
anywhere on the page.
</p>
        <p>
Some months later, I have changed my mind and I have to congratulate Microsoft for
this decision. IMHO, the best is to have an attribute that lets the designer know
which control produces html output and which one doesn’t. That way the developer has
the final decision and the designer doesn’t restrict developer’s imagination.
</p>
        <p>
For example, I was converting to ASP.NET 2.0 an old pager I have been using in a lot
of projects but when I was doing the conversion I thought: a pager has user interface
but also is a data source for another control… hmm
</p>
        <p>
I rewrote the control from scratch in order to see if I can come up with a pager that
can act as a data source control, and finally, after sorting out very subtle problems
and complex relationships with the binding infrastructure and data source controls
I finally had something working. I’m very impressed with what I obtained because I
was able to add paging to a control with no code at all thanks to the magic of the
data source controls! I think this was a very good idea so I worked hard on making
my pager a fully customizable control with a lot of features like page links that
are search engine friendly and full design time support for interacting with data
source controls:
</p>
        <p>
          <img src="http://www.manuelabadia.com/blog/content/binary/PDS_customization.png" border="0" />
        </p>
        <p>
          <img src="http://www.manuelabadia.com/blog/content/binary/PDS_designtime.gif" border="0" />
          <br />
        </p>
        <p>
I made a sample web site that shows some scenarios with the different features of
the PagerDataSource and also redesigned the main website (let me know what you think
about the new design). There is an evaluation version if you want to try it.
</p>
        <p>
PagerDataSource Live demo: <a href="http://www.manuelabadia.com/livedemo/pagerdatasource">http://www.manuelabadia.com/livedemo/pagerdatasource</a><br />
Main site: <a href="http://www.manuelabadia.com/">http://www.manuelabadia.com/</a></p>
        <p>
I hope you find the control useful…
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=e5d64c7a-2380-4708-875b-9e24872d4f83" />
      </body>
      <title>DataSourceControls… Non visual controls?</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,e5d64c7a-2380-4708-875b-9e24872d4f83.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,e5d64c7a-2380-4708-875b-9e24872d4f83.aspx</link>
      <pubDate>Wed, 07 Jun 2006 15:33:18 GMT</pubDate>
      <description>&lt;p&gt;
When I started learning ASP.NET 2.0 I noticed that the component tray was taken out
of the designer and somewhat the concept of component (in ASP.NET 1.x) was obsolete
and did not apply in ASP.NET 2.0.
&lt;/p&gt;
&lt;p&gt;
I was very angry with the new direction taken about this when I found this post by
Nikhil Kothari’s (an ASP.NET dev. team member):
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.nikhilk.net/NonVisualControlsAndComponents.aspx"&gt;http://www.nikhilk.net/NonVisualControlsAndComponents.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
that explains some of the problems found when implementing the new data source controls
in asp.net 2.0. Even they do not render any mark-up, they need to participate in the
page life cycle, so the old concept of component and the old model of persisting components
in the code behind file wasn’t working for this. Anyway, I had the idea that data
source controls should not appear with the rest of the controls in the page and I
didn’t liked the current implementation that shows the data source controls located
anywhere on the page.
&lt;/p&gt;
&lt;p&gt;
Some months later, I have changed my mind and I have to congratulate Microsoft for
this decision. IMHO, the best is to have an attribute that lets the designer know
which control produces html output and which one doesn’t. That way the developer has
the final decision and the designer doesn’t restrict developer’s imagination.
&lt;/p&gt;
&lt;p&gt;
For example, I was converting to ASP.NET 2.0 an old pager I have been using in a lot
of projects but when I was doing the conversion I thought: a pager has user interface
but also is a data source for another control… hmm
&lt;/p&gt;
&lt;p&gt;
I rewrote the control from scratch in order to see if I can come up with a pager that
can act as a data source control, and finally, after sorting out very subtle problems
and complex relationships with the binding infrastructure and data source controls
I finally had something working. I’m very impressed with what I obtained because I
was able to add paging to a control with no code at all thanks to the magic of the
data source controls! I think this was a very good idea so I worked hard on making
my pager a fully customizable control with a lot of features like page links that
are search engine friendly and full design time support for interacting with data
source controls:
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/PDS_customization.png" border=0&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/PDS_designtime.gif" border=0&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
I made a sample web site that shows some scenarios with the different features of
the PagerDataSource and also redesigned the main website (let me know what you think
about the new design). There is an evaluation version if you want to try it.
&lt;/p&gt;
&lt;p&gt;
PagerDataSource Live demo: &lt;a href="http://www.manuelabadia.com/livedemo/pagerdatasource"&gt;http://www.manuelabadia.com/livedemo/pagerdatasource&lt;/a&gt;
&lt;br&gt;
Main site: &lt;a href="http://www.manuelabadia.com/"&gt;http://www.manuelabadia.com/&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
I hope you find the control useful…
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=e5d64c7a-2380-4708-875b-9e24872d4f83" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,e5d64c7a-2380-4708-875b-9e24872d4f83.aspx</comments>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=dc8614ea-bd9c-4c43-8ff2-f57aac7b59fb</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,dc8614ea-bd9c-4c43-8ff2-f57aac7b59fb.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,dc8614ea-bd9c-4c43-8ff2-f57aac7b59fb.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=dc8614ea-bd9c-4c43-8ff2-f57aac7b59fb</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I had some very specific things to do in my last project that required coding a few
things in MSIL and injecting it into an assembly. I did the job with ILASM, ILDASM
and notepad. I was in a hurry so I wasn’t able to search for a better or more elegant
way to do it. However, a few days later, I searched for low level tools that could
help me in the future with MSIL related tasks for the Microsoft.NET Framework. I found
some interesting things:
</p>
        <p>
* ILIDE#: a complete IDE to compile MSIL assembler to an assembly. It even has debugging
support!
</p>
        <p>
You can read more about it here:<br /><br /><a href="http://geekswithblogs.net/kakaiya/archive/2005/06/16/43953.aspx">http://geekswithblogs.net/kakaiya/archive/2005/06/16/43953.aspx</a><br /><br />
* Mike Stall’s tool to allow inline MSIL in C#: the MSIL code is injected between
#if #endif directives and then injected in the resulting assembly using a post-build
step.<br /><br />
For more information visit:<br /><br /><a href="http://blogs.msdn.com/jmstall/archive/2005/02/21/377806.aspx">http://blogs.msdn.com/jmstall/archive/2005/02/21/377806.aspx</a><br /><br />
* Craig Skibo’s Visual IL language service project with source code! He provides the
full source code to integrate IL support in visual studio.<br /><br />
Here is the post with more information about it:<br /><br /><a href="http://blogs.msdn.com/craigskibo/archive/2005/12/07/501208.aspx">http://blogs.msdn.com/craigskibo/archive/2005/12/07/501208.aspx</a><br /><br />
* Deblector: a plugin for reflector to support debugging an assembly. For example,
you can attach to a running process and set a breakpoint in a framework method in
order to see what really happens. Awesome stuff even if it’s in alpha stage.<br /><br />
More information about deblector here:<br /><br /><a href="http://www.felicepollano.com/CategoryView,category,Deblector.aspx">http://www.felicepollano.com/CategoryView,category,Deblector.aspx</a><br /><br />
I tried it but it didn’t work here. Maybe it was because the current version of reflector
is newer than the one used to test the latest version of deblector but definitely
I’ll keep an eye on this project!
</p>
        <img src="http://www.manuelabadia.com/blog/content/binary/DeblectorAlpha.png" border="0" />
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=dc8614ea-bd9c-4c43-8ff2-f57aac7b59fb" />
      </body>
      <title>Low level tools (MSIL related) for .Net Framework</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,dc8614ea-bd9c-4c43-8ff2-f57aac7b59fb.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,dc8614ea-bd9c-4c43-8ff2-f57aac7b59fb.aspx</link>
      <pubDate>Fri, 02 Jun 2006 08:50:52 GMT</pubDate>
      <description>&lt;p&gt;
I had some very specific things to do in my last project that required coding a few
things in MSIL and injecting it into an assembly. I did the job with ILASM, ILDASM
and notepad. I was in a hurry so I wasn’t able to search for a better or more elegant
way to do it. However, a few days later, I searched for low level tools that could
help me in the future with MSIL related tasks for the Microsoft.NET Framework. I found
some interesting things:
&lt;/p&gt;
&lt;p&gt;
* ILIDE#: a complete IDE to compile MSIL assembler to an assembly. It even has debugging
support!
&lt;/p&gt;
&lt;p&gt;
You can read more about it here:&lt;br&gt;
&lt;br&gt;
&lt;a href="http://geekswithblogs.net/kakaiya/archive/2005/06/16/43953.aspx"&gt;http://geekswithblogs.net/kakaiya/archive/2005/06/16/43953.aspx&lt;/a&gt; 
&lt;br&gt;
&lt;br&gt;
* Mike Stall’s tool to allow inline MSIL in C#: the MSIL code is injected between
#if #endif directives and then injected in the resulting assembly using a post-build
step.&lt;br&gt;
&lt;br&gt;
For more information visit:&lt;br&gt;
&lt;br&gt;
&lt;a href="http://blogs.msdn.com/jmstall/archive/2005/02/21/377806.aspx"&gt;http://blogs.msdn.com/jmstall/archive/2005/02/21/377806.aspx&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;
* Craig Skibo’s Visual IL language service project with source code! He provides the
full source code to integrate IL support in visual studio.&lt;br&gt;
&lt;br&gt;
Here is the post with more information about it:&lt;br&gt;
&lt;br&gt;
&lt;a href="http://blogs.msdn.com/craigskibo/archive/2005/12/07/501208.aspx"&gt;http://blogs.msdn.com/craigskibo/archive/2005/12/07/501208.aspx&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;
* Deblector: a plugin for reflector to support debugging an assembly. For example,
you can attach to a running process and set a breakpoint in a framework method in
order to see what really happens. Awesome stuff even if it’s in alpha stage.&lt;br&gt;
&lt;br&gt;
More information about deblector here:&lt;br&gt;
&lt;br&gt;
&lt;a href="http://www.felicepollano.com/CategoryView,category,Deblector.aspx"&gt;http://www.felicepollano.com/CategoryView,category,Deblector.aspx&lt;/a&gt;
&lt;br&gt;
&lt;br&gt;
I tried it but it didn’t work here. Maybe it was because the current version of reflector
is newer than the one used to test the latest version of deblector but definitely
I’ll keep an eye on this project!
&lt;/p&gt;
&lt;img src="http://www.manuelabadia.com/blog/content/binary/DeblectorAlpha.png" border=0&gt;&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=dc8614ea-bd9c-4c43-8ff2-f57aac7b59fb" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,dc8614ea-bd9c-4c43-8ff2-f57aac7b59fb.aspx</comments>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=3ff1433a-2c81-4c0f-849a-7c1cc2a5c989</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,3ff1433a-2c81-4c0f-849a-7c1cc2a5c989.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,3ff1433a-2c81-4c0f-849a-7c1cc2a5c989.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=3ff1433a-2c81-4c0f-849a-7c1cc2a5c989</wfw:commentRss>
      <slash:comments>1</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I have been using this HTTP Module for the last 2 weeks and I have to say it is awesome:
</p>
        <p>
          <a href="http://www.thejoyofcode.com/Validator_Module.aspx">http://www.thejoyofcode.com/Validator_Module.aspx</a>
        </p>
        <p>
Basically, it checks the html generated by the page and displays if it validates against
the XHTML mode you're using.
</p>
        <p>
If you use it early in a project to check for XHTML conformance is very easy
to keep the pages as compliant as possible. You may be wonder why to use it because
Visual Studio checks the HTML generated, but keep in mind that Visual Studio checks
the HTML in the ASPX page but not after all the controls have rendered their mark-up. The
big surprise is that the ASP.NET TreeView control fails validation (XHTML 1.0 Transitional)!
When a TreeView is rendered, some script is injected in the page:
</p>
        <p>
 
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;</span>
            <span style="COLOR: maroon">script</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <font color="#008000">&lt;!--</font>
          </p>
          <p style="MARGIN: 0px">
    <span style="COLOR: blue">function</span> TreeView_PopulateNodeDoCallBack(context,param)
{
</p>
          <p style="MARGIN: 0px">
        WebForm_DoCallback(context.data.treeViewID,param,TreeView_ProcessNodeData,context,TreeView_ProcessNodeData,<span style="COLOR: blue">false</span>);
</p>
          <p style="MARGIN: 0px">
    }
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">// --&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">&lt;/</span>
            <span style="COLOR: maroon">script</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
But the script tag is missing the required attribute "type". It's hard to explain
how the testing team overlooked this. I took a look to the CSS Control Adapters found
here:
</p>
        <p>
          <a href="http://www.asp.net/cssadapters/">http://www.asp.net/cssadapters/</a>
        </p>
        <p>
but even if they look good, they are in beta and they are not complete. For example,
the SelectedNodeChanged event is not triggered if you use the CSS Control Adapters
and some properties like ShowCheckBoxes aren't used when rendering the control). The
CSS Control Adapters should be taken as a sample about writting custom adapters.
</p>
        <p>
So for now I have to live with the TreeView bug :(
</p>
        <p>
The validator module is extensible so you can hook in a class that will be called
when validation has occured to do whatever you want to do. There is a post about that
here that explains how to extend the module to send an email when the validation fails:
</p>
        <p>
          <a href="http://www.thejoyofcode.com/Extending_the_Validator_Module.aspx">http://www.thejoyofcode.com/Extending_the_Validator_Module.aspx</a>
        </p>
        <p>
I have added to my TODO list an extension to the module that logs errors using the
health monitoring system.
</p>
        <p>
Now that we have XHTML validation, what would be really cool is an HTTP Module that
does CSS validation. However that's a lot more complicated than XHTML validation.
</p>
        <p>
If anyone has some spare time, the sources for the W3C CSS validator are here:
</p>
        <p>
          <u>
            <font color="#800080">
              <a href="http://dev.w3.org/cvsweb/2002/css-validator">http://dev.w3.org/cvsweb/2002/css-validator</a>
            </font>
          </u>
        </p>
        <p>
So with a bit of work that could be rewriten in C# and converted to an HTTP Module.
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=3ff1433a-2c81-4c0f-849a-7c1cc2a5c989" />
      </body>
      <title>XHTML Validation</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,3ff1433a-2c81-4c0f-849a-7c1cc2a5c989.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,3ff1433a-2c81-4c0f-849a-7c1cc2a5c989.aspx</link>
      <pubDate>Wed, 31 May 2006 12:42:31 GMT</pubDate>
      <description>&lt;p&gt;
I have been using this HTTP Module for the last 2 weeks and I have to say it is awesome:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.thejoyofcode.com/Validator_Module.aspx"&gt;http://www.thejoyofcode.com/Validator_Module.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Basically, it checks the html generated by the page and displays if it validates against
the XHTML mode you're using.
&lt;/p&gt;
&lt;p&gt;
If you use it early in a project to check for XHTML conformance&amp;nbsp;is very easy
to keep the pages as compliant as possible. You may be wonder why to use it because
Visual Studio checks the HTML generated, but keep in mind that Visual Studio checks
the HTML in the ASPX page but not after all the controls have rendered their mark-up.&amp;nbsp;The
big surprise is that the ASP.NET TreeView control fails validation (XHTML 1.0 Transitional)!
When a TreeView is rendered, some script is injected in the page:
&lt;/p&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;script&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;font color=#008000&gt;&amp;lt;!--&lt;/font&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;function&lt;/span&gt; TreeView_PopulateNodeDoCallBack(context,param)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; WebForm_DoCallback(context.data.treeViewID,param,TreeView_ProcessNodeData,context,TreeView_ProcessNodeData,&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;
&lt;span style="COLOR: green"&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;script&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
But the script tag is missing the required attribute "type". It's hard to explain
how the testing team overlooked this. I took a look to the CSS Control Adapters found
here:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.asp.net/cssadapters/"&gt;http://www.asp.net/cssadapters/&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
but even if they look good, they are in beta and they are not complete. For example,
the SelectedNodeChanged event is not triggered if you use the CSS Control Adapters
and some properties like ShowCheckBoxes aren't used when rendering the control). The
CSS Control Adapters should be taken as a sample about writting custom adapters.
&lt;/p&gt;
&lt;p&gt;
So for now I have to live with the TreeView bug :(
&lt;/p&gt;
&lt;p&gt;
The validator module is extensible so you can hook in a class that will be called
when validation has occured to do whatever you want to do. There is a post about that
here that explains how to extend the module to send an email when the validation fails:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.thejoyofcode.com/Extending_the_Validator_Module.aspx"&gt;http://www.thejoyofcode.com/Extending_the_Validator_Module.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
I have added to my TODO list an extension to the module that logs errors using the
health monitoring system.
&lt;/p&gt;
&lt;p&gt;
Now that we have XHTML validation, what would be really cool is an HTTP Module that
does CSS validation. However that's a lot more complicated than XHTML validation.
&lt;/p&gt;
&lt;p&gt;
If anyone has some spare time, the sources for the W3C CSS validator are here:
&lt;/p&gt;
&lt;p&gt;
&lt;u&gt;&lt;font color=#800080&gt;&lt;a href="http://dev.w3.org/cvsweb/2002/css-validator"&gt;http://dev.w3.org/cvsweb/2002/css-validator&lt;/a&gt;&lt;/font&gt;&lt;/u&gt;
&lt;/p&gt;
&lt;p&gt;
So with a bit of work that could be rewriten in C# and converted to an HTTP Module.
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=3ff1433a-2c81-4c0f-849a-7c1cc2a5c989" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,3ff1433a-2c81-4c0f-849a-7c1cc2a5c989.aspx</comments>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=b191b8d0-703e-47a2-afb0-ba03b83cb49f</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,b191b8d0-703e-47a2-afb0-ba03b83cb49f.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,b191b8d0-703e-47a2-afb0-ba03b83cb49f.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=b191b8d0-703e-47a2-afb0-ba03b83cb49f</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I have been exploring different ways to do URL rewriting. Basically there are two
options: 
</p>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <p>
* doing the rewrite at the web server level<br />
* doing the rewrite using ASP.NET
</p>
        </blockquote>
        <p>
The first option is the most flexible one and the one that causes less problems and
less side effects but it is not an option if you don’t have full permissions on the
server for the project you’re working (which is not the case). IIS 7 will allow modules
written in managed code but I’m not sure if an application will be able to configure
the modules to use without full permissions.
</p>
        <p>
So, the only option is to do it at the ASP.NET level. ASP.NET 2.0 has some built in
functionality for doing URL rewriting but it’s nearly useless because it does not
support regular expressions. There are some HTTP modules and HTTP handlers out there
that provide more functionality, but most of them have some problems because it’s
tricky to handle themes, postbacks, output caching, etc properly when using rewritten
URLs. It seems that the most used HTTP module for URL rewriting is:
</p>
        <p>
          <a href="http://www.urlrewriting.net/">http://www.urlrewriting.net</a>
        </p>
        <p>
It’s easy to use and seems to work properly for now (I have been using it only for
a few days), however there are times where regular expressions are not enough for
doing rewrites. I wrote the authors an explained them a scenario where a more generic
approach is desirable. Basically what I had in mind was that the module was able to
call a custom method when certain condition is met (this condition will be evaluated
using regular expressions) or always and that method could handle the rewrite or not
(the return value could be used to indicate that the rule has been applied or not).
Inside the method you could do anything that you want to rewrite the URL. They told
me that they were thinking in adding this kind of functionality in a near future,
so good news but we’ll have to wait ;)
</p>
        <p>
I’ll show an example in case the problem isn’t obvious. If you want to optimize your
site for search engine spiders, a good thing to do is to avoid passing parameters
using the query string because some spiders will not index pages with dynamic parameters
or others will limit the indexed pages with dynamic parameters or not index pages
with more than a predefined number of parameters. Rewriting a URL like:
</p>
        <p>
          <a href="http://www.mysite.com/viewproduct.aspx?id=234&amp;idCat=13">http://www.mysite.com/viewproduct.aspx?id=234&amp;idCat=13</a>
        </p>
        <p>
to:
</p>
        <p>
          <a href="http://www.mysite.com/id/234/idCat/13/viewproduct.aspx">http://www.mysite.com/id/234/idCat/13/viewproduct.aspx</a>
        </p>
        <p>
helps the search engine spiders to index it. If you have different number of parameters
for your pages you can end up with a lot of rules like:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;</span>
            <span style="COLOR: maroon">rewrites</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">virtualUrl</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">^~/(.*?)/(.*?)/(.*?)/(.*?)/(.*?)/(.*?)/(.*).aspx</span>"<span style="COLOR: blue"> 
          </span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">          </span>
            <span style="COLOR: red">rewriteUrlParameter</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">ExcludeFromClientQueryString</span>"<span style="COLOR: blue"></span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">          </span>
            <span style="COLOR: red">destinationUrl</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">~/$7.aspx?$1=$2</span><span style="COLOR: red">&amp;amp;</span><span style="COLOR: blue">$3=$4</span><span style="COLOR: red">&amp;amp;</span><span style="COLOR: blue">$5=$6</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">          </span>
            <span style="COLOR: red">ignoreCase</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">true</span>"<span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">virtualUrl</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">^~/(.*?)/(.*?)/(.*?)/(.*?)/(.*).aspx</span>"<span style="COLOR: blue"> 
          </span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">          </span>
            <span style="COLOR: red">rewriteUrlParameter</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">ExcludeFromClientQueryString</span>"<span style="COLOR: blue"></span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">          </span>
            <span style="COLOR: red">destinationUrl</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">~/$5.aspx?$1=$2</span><span style="COLOR: red">&amp;amp;</span><span style="COLOR: blue">$3=$4</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">          </span>
            <span style="COLOR: red">ignoreCase</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">true</span>"<span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">      &lt;</span>
            <span style="COLOR: maroon">add</span>
            <span style="COLOR: blue">
            </span>
            <span style="COLOR: red">virtualUrl</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">^~/(.*?)/(.*?)/(.*).aspx</span>"<span style="COLOR: blue"> 
          </span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">          </span>
            <span style="COLOR: red">rewriteUrlParameter</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">ExcludeFromClientQueryString</span>"<span style="COLOR: blue"></span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">          </span>
            <span style="COLOR: red">destinationUrl</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">~/$3.aspx?$1=$2</span>"
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">          </span>
            <span style="COLOR: red">ignoreCase</span>
            <span style="COLOR: blue">=</span>"<span style="COLOR: blue">true</span>"<span style="COLOR: blue">/&gt;</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">    &lt;/</span>
            <span style="COLOR: maroon">rewrites</span>
            <span style="COLOR: blue">&gt;</span>
          </p>
        </div>
        <!--EndFragment-->
        <p>
 
</p>
        <p>
Note that in order for this to work properly you have to specify the rule with the
maximum number of parameters first, so every time the module is trying to rewrite
an URL it will evaluate the first rule, that probably will not be the most used, incurring
in an unnecessary performance loss. If you want to do a rewrite similar to the previous
one and you have pages in multiple directories things get more complicated because
the directory could be handled as a parameter if the rules are not written conscientiously.
</p>
        <p>
All the code about URL rewriting that I’ve found out there was for an HTTP module
or an HTTP handler. However, for ASP.NET 2.0 another option is available: a Virtual
Path Provider (VPP for now on).
</p>
        <p>
Essentially, access to files and folders in ASP.NET has been virtualized. The default
VPP provider just reads files from the file system checking IIS permissions. You can
code your own VPP to read files from a database, generate aspx pages on the fly or
anything you can imagine.
</p>
        <p>
There’s a good article about VPP written by Victor García Aprea where he explains
how to run a website from a zip file:
</p>
        <p>
          <a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/vpp_vga.asp">http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/vpp_vga.asp</a>
        </p>
        <p>
Most of the stuff about VPP is straightforward except the GetFileHash and GetCacheDependency
methods. ASP.NET caches aspx pages after they’re compiled for the first time and monitors
file changes, forcing a recompile when a page changes. A bad implementation of the
one of those methods could make your application to compile each page on each request
so if you are going to code your own VPP provider be sure to triple check your GetCacheDependency
and GetFileHash methods.
</p>
        <p>
I started playing with a custom VPP provider that did URL rewriting based on regular
expressions in all methods that were using a virtual path (nothing serious, just some
code to make a proof of concept). Basically I was calling the default provider implementation
with the rewritten virtual path but the framework checks that the path stays unchanged
on instances of the VirtualFile and VirtualDirectory classes!
</p>
        <p>
I had to change my strategy to return the same virtual path as I was passed even if
I was actually accessing to a different path. I had a quick test version working on
my local machine but when trying it on the server there was a big problem. Unfortunately,
to use a VPP provider you need full trust permissions. That was a stopper for me so
I ended my VPP adventure here. Thank god I tried it on the server before transforming
the quick and primitive proof of concept code into something usable (also I didn’t
spent any time thinking about other implications (like output caching) of my approach).
Even if VPP weren’t useful for me, the knowledge acquired is always welcome.<br /></p>
        <p>
        </p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=b191b8d0-703e-47a2-afb0-ba03b83cb49f" />
      </body>
      <title>Virtual Path Providers, HTTP Modules and URL Rewriting</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,b191b8d0-703e-47a2-afb0-ba03b83cb49f.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,b191b8d0-703e-47a2-afb0-ba03b83cb49f.aspx</link>
      <pubDate>Sun, 28 May 2006 21:39:39 GMT</pubDate>
      <description>&lt;p&gt;
I have been exploring different ways to do URL rewriting. Basically there are two
options:&amp;nbsp;
&lt;/p&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;p&gt;
* doing the rewrite at the web server level&lt;br&gt;
* doing the rewrite using ASP.NET
&lt;/p&gt;
&lt;/blockquote&gt; 
&lt;p&gt;
The first option is the most flexible one and the one that causes less problems and
less side effects but it is not an option if you don’t have full permissions on the
server for the project you’re working (which is not the case). IIS 7 will allow modules
written in managed code but I’m not sure if an application will be able to configure
the modules to use without full permissions.
&lt;/p&gt;
&lt;p&gt;
So, the only option is to do it at the ASP.NET level. ASP.NET 2.0 has some built in
functionality for doing URL rewriting but it’s nearly useless because it does not
support regular expressions. There are some HTTP modules and HTTP handlers out there
that provide more functionality, but most of them have some problems because it’s
tricky to handle themes, postbacks, output caching, etc properly when using rewritten
URLs. It seems that the most used HTTP module for URL rewriting is:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.urlrewriting.net/"&gt;http://www.urlrewriting.net&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
It’s easy to use and seems to work properly for now (I have been using it only for
a few days), however there are times where regular expressions are not enough for
doing rewrites. I wrote the authors an explained them a scenario where a more generic
approach is desirable. Basically what I had in mind was that the module was able to
call a custom method when certain condition is met (this condition will be evaluated
using regular expressions) or always and that method could handle the rewrite or not
(the return value could be used to indicate that the rule has been applied or not).
Inside the method you could do anything that you want to rewrite the URL. They told
me that they were thinking in adding this kind of functionality in a near future,
so good news but we’ll have to wait ;)
&lt;/p&gt;
&lt;p&gt;
I’ll show an example in case the problem isn’t obvious. If you want to optimize your
site for search engine spiders, a good thing to do is to avoid passing parameters
using the query string because some spiders will not index pages with dynamic parameters
or others will limit the indexed pages with dynamic parameters or not index pages
with more than a predefined number of parameters. Rewriting a URL like:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.mysite.com/viewproduct.aspx?id=234&amp;amp;idCat=13"&gt;http://www.mysite.com/viewproduct.aspx?id=234&amp;amp;idCat=13&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
to:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.mysite.com/id/234/idCat/13/viewproduct.aspx"&gt;http://www.mysite.com/id/234/idCat/13/viewproduct.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
helps the search engine spiders to index it. If you have different number of parameters
for your pages you can end up with a lot of rules like:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;rewrites&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;virtualUrl&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;^~/(.*?)/(.*?)/(.*?)/(.*?)/(.*?)/(.*?)/(.*).aspx&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;&amp;nbsp;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;rewriteUrlParameter&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;ExcludeFromClientQueryString&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;destinationUrl&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;~/$7.aspx?$1=$2&lt;/span&gt;&lt;span style="COLOR: red"&gt;&amp;amp;amp;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;$3=$4&lt;/span&gt;&lt;span style="COLOR: red"&gt;&amp;amp;amp;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;$5=$6&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;ignoreCase&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;true&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;virtualUrl&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;^~/(.*?)/(.*?)/(.*?)/(.*?)/(.*).aspx&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;&amp;nbsp;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;rewriteUrlParameter&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;ExcludeFromClientQueryString&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;destinationUrl&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;~/$5.aspx?$1=$2&lt;/span&gt;&lt;span style="COLOR: red"&gt;&amp;amp;amp;&lt;/span&gt;&lt;span style="COLOR: blue"&gt;$3=$4&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;ignoreCase&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;true&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;nbsp; &amp;nbsp; &amp;nbsp; &amp;lt;&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;add&lt;/span&gt;&lt;span style="COLOR: blue"&gt; &lt;/span&gt;&lt;span style="COLOR: red"&gt;virtualUrl&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;^~/(.*?)/(.*?)/(.*).aspx&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;&amp;nbsp;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;rewriteUrlParameter&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;ExcludeFromClientQueryString&lt;/span&gt;"&lt;span style="COLOR: blue"&gt; &lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;destinationUrl&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;~/$3.aspx?$1=$2&lt;/span&gt;"
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/span&gt;&lt;span style="COLOR: red"&gt;ignoreCase&lt;/span&gt;&lt;span style="COLOR: blue"&gt;=&lt;/span&gt;"&lt;span style="COLOR: blue"&gt;true&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;nbsp; &amp;nbsp; &amp;lt;/&lt;/span&gt;&lt;span style="COLOR: maroon"&gt;rewrites&lt;/span&gt;&lt;span style="COLOR: blue"&gt;&amp;gt;&lt;/span&gt;
&lt;/p&gt;
&lt;/div&gt;
&lt;!--EndFragment--&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
Note that in order for this to work properly you have to specify the rule with the
maximum number of parameters first, so every time the module is trying to rewrite
an URL it will evaluate the first rule, that probably will not be the most used, incurring
in an unnecessary performance loss. If you want to do a rewrite similar to the previous
one and you have pages in multiple directories things get more complicated because
the directory could be handled as a parameter if the rules are not written conscientiously.
&lt;/p&gt;
&lt;p&gt;
All the code about URL rewriting that I’ve found out there was for an HTTP module
or an HTTP handler. However, for ASP.NET 2.0 another option is available: a Virtual
Path Provider (VPP for now on).
&lt;/p&gt;
&lt;p&gt;
Essentially, access to files and folders in ASP.NET has been virtualized. The default
VPP provider just reads files from the file system checking IIS permissions. You can
code your own VPP to read files from a database, generate aspx pages on the fly or
anything you can imagine.
&lt;/p&gt;
&lt;p&gt;
There’s a good article about VPP written by Victor García Aprea where he explains
how to run a website from a zip file:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/vpp_vga.asp"&gt;http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnaspp/html/vpp_vga.asp&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Most of the stuff about VPP is straightforward except the GetFileHash and GetCacheDependency
methods. ASP.NET caches aspx pages after they’re compiled for the first time and monitors
file changes, forcing a recompile when a page changes. A bad implementation of the
one of those methods could make your application to compile each page on each request
so if you are going to code your own VPP provider be sure to triple check your GetCacheDependency
and GetFileHash methods.
&lt;/p&gt;
&lt;p&gt;
I started playing with a custom VPP provider that did URL rewriting based on regular
expressions in all methods that were using a virtual path (nothing serious, just some
code to make a proof of concept). Basically I was calling the default provider implementation
with the rewritten virtual path but the framework checks that the path stays unchanged
on instances of the VirtualFile and VirtualDirectory classes!
&lt;/p&gt;
&lt;p&gt;
I had to change my strategy to return the same virtual path as I was passed even if
I was actually accessing to a different path. I had a quick test version working on
my local machine but when trying it on the server there was a big problem. Unfortunately,
to use a VPP provider you need full trust permissions. That was a stopper for me so
I ended my VPP adventure here. Thank god I tried it on the server before transforming
the quick and primitive proof of concept code into something usable (also I didn’t
spent any time thinking about other implications (like output caching) of my approach).
Even if VPP weren’t useful for me, the knowledge acquired is always welcome.&lt;br&gt;
&lt;/p&gt;
&lt;p&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=b191b8d0-703e-47a2-afb0-ba03b83cb49f" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,b191b8d0-703e-47a2-afb0-ba03b83cb49f.aspx</comments>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=f21842d9-c4b6-470f-ad37-1f6530d768ef</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,f21842d9-c4b6-470f-ad37-1f6530d768ef.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,f21842d9-c4b6-470f-ad37-1f6530d768ef.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=f21842d9-c4b6-470f-ad37-1f6530d768ef</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I was giving the final touches to a control I was developing and I found out that
I couldn’t apply a Style object to an HtmlControl directly. An HtmlControl exposes
a Style property of type CssStyleCollection and the WebControl exposes a ControlStyle
property of type Style. My control has several properties of type Style and I had
styled WebControls without any problem using the ApplyStyle method, but that was not
possible with HtmlControls.
</p>
        <p>
To solve the problem you have the option to use only WebControls instead of HtmlControls
and produce the same Html output but that was my last option.
</p>
        <p>
I searched google but I only found a helper class that did the translation:
</p>
        <p>
          <a href="http://www.cambiaresearch.com/cambia3/snippets/csharp/classes/StyleHelper.aspx">http://www.cambiaresearch.com/cambia3/snippets/csharp/classes/StyleHelper.aspx</a>
        </p>
        <p>
Fortunately there's a way to avoid having to do that conversion “manually”. This is
the method that I’m using now to style a control:
</p>
        <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">public</span> <span style="COLOR: blue">void</span> ApplyStyleToControl(<span style="COLOR: teal">Control</span> control, <span style="COLOR: teal">Style</span> style)
</p>
          <p style="MARGIN: 0px">
        {
</p>
          <p style="MARGIN: 0px">
            <span style="COLOR: green">//
if the control is a WebControl, apply the style directly</span></p>
          <p style="MARGIN: 0px">
            <span style="COLOR: blue">if</span> (control <span style="COLOR: blue">is</span><span style="COLOR: teal">WebControl</span>)
{
</p>
          <p style="MARGIN: 0px">
                ((<span style="COLOR: teal">WebControl</span>)control).ApplyStyle(style);
</p>
          <p style="MARGIN: 0px">
            } <span style="COLOR: blue">else</span><span style="COLOR: blue">if</span> (control <span style="COLOR: blue">is</span><span style="COLOR: teal">HtmlControl</span>)
{
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: green">//
if the control is a HtmlControl</span></p>
          <p style="MARGIN: 0px">
                <span style="COLOR: teal">HtmlControl</span> htmlControl
= (<span style="COLOR: teal">HtmlControl</span>)control;
</p>
          <p style="MARGIN: 0px">
 
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: green">//
get the css style collection from the style and modify the control's style collection</span></p>
          <p style="MARGIN: 0px">
                <span style="COLOR: teal">CssStyleCollection</span> styles
= style.GetStyleAttributes(control);
</p>
          <p style="MARGIN: 0px">
                <span style="COLOR: blue">foreach</span> (<span style="COLOR: blue">string</span> key <span style="COLOR: blue">in</span> styles.Keys)
{
</p>
          <p style="MARGIN: 0px">
                   
htmlControl.Style[key] = styles[key];
</p>
          <p style="MARGIN: 0px">
                }
</p>
          <p style="MARGIN: 0px">
            }
</p>
          <p style="MARGIN: 0px">
        }
</p>
        </div>
        <p>
          <!--EndFragment-->
          <br />
The GetStyleAttributes is not present in version 1.x so if you’re not using version
2.0 you’re out of luck!
</p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=f21842d9-c4b6-470f-ad37-1f6530d768ef" />
      </body>
      <title>Applying a Style to an HtmlControl</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,f21842d9-c4b6-470f-ad37-1f6530d768ef.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,f21842d9-c4b6-470f-ad37-1f6530d768ef.aspx</link>
      <pubDate>Wed, 24 May 2006 17:44:02 GMT</pubDate>
      <description>&lt;p&gt;
I was giving the final touches to a control I was developing and I found out that
I couldn’t apply a Style object to an HtmlControl directly. An HtmlControl exposes
a Style property of type CssStyleCollection and the WebControl exposes a ControlStyle
property of type Style. My control has several properties of type Style and I had
styled WebControls without any problem using the ApplyStyle method, but that was not
possible with HtmlControls.
&lt;/p&gt;
&lt;p&gt;
To solve the problem you have the option to use only WebControls instead of HtmlControls
and produce the same Html output but that&amp;nbsp;was my last option.
&lt;/p&gt;
&lt;p&gt;
I searched google but I only found a helper class that did the translation:
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://www.cambiaresearch.com/cambia3/snippets/csharp/classes/StyleHelper.aspx"&gt;http://www.cambiaresearch.com/cambia3/snippets/csharp/classes/StyleHelper.aspx&lt;/a&gt;
&lt;/p&gt;
&lt;p&gt;
Fortunately there's a way to avoid having to do that conversion “manually”. This is
the method that I’m using now to style a control:
&lt;/p&gt;
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;public&lt;/span&gt;&amp;nbsp;&lt;span style="COLOR: blue"&gt;void&lt;/span&gt; ApplyStyleToControl(&lt;span style="COLOR: teal"&gt;Control&lt;/span&gt; control, &lt;span style="COLOR: teal"&gt;Style&lt;/span&gt; style)
&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;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
if the control is a WebControl, apply the style directly&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (control &lt;span style="COLOR: blue"&gt;is&lt;/span&gt; &lt;span style="COLOR: teal"&gt;WebControl&lt;/span&gt;)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; ((&lt;span style="COLOR: teal"&gt;WebControl&lt;/span&gt;)control).ApplyStyle(style);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; } &lt;span style="COLOR: blue"&gt;else&lt;/span&gt; &lt;span style="COLOR: blue"&gt;if&lt;/span&gt; (control &lt;span style="COLOR: blue"&gt;is&lt;/span&gt; &lt;span style="COLOR: teal"&gt;HtmlControl&lt;/span&gt;)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
if the control is a HtmlControl&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;HtmlControl&lt;/span&gt; htmlControl
= (&lt;span style="COLOR: teal"&gt;HtmlControl&lt;/span&gt;)control;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: green"&gt;//
get the css style collection from the style and modify the control's style collection&lt;/span&gt;
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: teal"&gt;CssStyleCollection&lt;/span&gt; styles
= style.GetStyleAttributes(control);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span style="COLOR: blue"&gt;foreach&lt;/span&gt; (&lt;span style="COLOR: blue"&gt;string&lt;/span&gt; key &lt;span style="COLOR: blue"&gt;in&lt;/span&gt; styles.Keys)
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;
htmlControl.Style[key] = styles[key];
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&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;&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;&amp;nbsp;&amp;nbsp; }
&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;
&lt;!--EndFragment--&gt;
&lt;br&gt;
The GetStyleAttributes is not present in version 1.x so if you’re not using version
2.0 you’re out of luck!
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=f21842d9-c4b6-470f-ad37-1f6530d768ef" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,f21842d9-c4b6-470f-ad37-1f6530d768ef.aspx</comments>
      <category>ASP.NET</category>
    </item>
    <item>
      <trackback:ping>http://www.manuelabadia.com/blog/Trackback.aspx?guid=8cdc7001-bca7-4ea6-a3f8-0fb2861548f6</trackback:ping>
      <pingback:server>http://www.manuelabadia.com/blog/pingback.aspx</pingback:server>
      <pingback:target>http://www.manuelabadia.com/blog/PermaLink,guid,8cdc7001-bca7-4ea6-a3f8-0fb2861548f6.aspx</pingback:target>
      <dc:creator>Your DisplayName here!</dc:creator>
      <wfw:comment>http://www.manuelabadia.com/blog/CommentView,guid,8cdc7001-bca7-4ea6-a3f8-0fb2861548f6.aspx</wfw:comment>
      <wfw:commentRss>http://www.manuelabadia.com/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=8cdc7001-bca7-4ea6-a3f8-0fb2861548f6</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I’m spending a lot of time lately with the designer infrastructure and I don’t know
why it’s so badly documented. I'm posting some tips that you may find useful when
working with design time stuff:
</p>
        <ul>
          <li>
 The designers are cached so if you have opened a WebForm, make sure you reopen
it again to test your changes. Otherwise you will be running an old version of your
designer. 
</li>
        </ul>
        <p>
          <br />
        </p>
        <ul>
          <li>
The design time life cycle is very reduced from the usual life cycle: 
<ul><li>
Only the Init and Render stages are executed (no PreInit, PreLoad, Load, LoadComplete,
PreRender or UnLoad stages are executed). 
<br /></li><li>
There’s no Context.</li></ul></li>
        </ul>
        <p>
          <br />
        </p>
        <ul>
          <li>
When there’s an error in a designer, very little information about the error is shown.
Change the GetErrorDesignTimeHtml to display the stack trace so you can figure out
where the error is without having to debug the component:<br /></li>
        </ul>
        <blockquote dir="ltr" style="MARGIN-RIGHT: 0px">
          <div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New">
            <p style="MARGIN: 0px">
              <span style="COLOR: blue">protected</span>
              <span style="COLOR: blue">override</span>
              <span style="COLOR: blue">string</span> GetErrorDesignTimeHtml(<span style="COLOR: teal">Exception</span> e)
</p>
            <p style="MARGIN: 0px">
{
</p>
            <p style="MARGIN: 0px">
              <span style="COLOR: blue">   return</span> CreateErrorDesignTimeHtml(<span style="COLOR: maroon">"Error
creating the control "</span> + e.StackTrace.ToString(), e);
</p>
            <p style="MARGIN: 0px">
}
</p>
          </div>
        </blockquote>
        <!--EndFragment-->
        <ul>
          <li>
If your component is a class library you can debug it, choosing project properties-&gt;debug-&gt;start
external program-&gt;(put complete path to devenv.exe).<br /></li>
        </ul>
        <p>
That's all for now.<br /></p>
        <img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=8cdc7001-bca7-4ea6-a3f8-0fb2861548f6" />
      </body>
      <title>Design Time tips</title>
      <guid isPermaLink="false">http://www.manuelabadia.com/blog/PermaLink,guid,8cdc7001-bca7-4ea6-a3f8-0fb2861548f6.aspx</guid>
      <link>http://www.manuelabadia.com/blog/PermaLink,guid,8cdc7001-bca7-4ea6-a3f8-0fb2861548f6.aspx</link>
      <pubDate>Sun, 21 May 2006 19:29:49 GMT</pubDate>
      <description>&lt;p&gt;
I’m spending a lot of time lately with the designer infrastructure and I don’t know
why it’s so badly documented. I'm posting some tips that you may find useful when
working with design time stuff:
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&amp;nbsp;The designers are cached so if you have opened a WebForm, make sure you reopen
it again to test your changes. Otherwise you will be running an old version of your
designer. 
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
The design time life cycle is very reduced from the usual life cycle: 
&lt;ul&gt;
&lt;li&gt;
Only the Init and Render stages are executed (no PreInit, PreLoad, Load, LoadComplete,
PreRender or UnLoad stages are executed). 
&lt;br&gt;
&lt;li&gt;
There’s no Context.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
&lt;br&gt;
&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
When there’s an error in a designer, very little information about the error is shown.
Change the GetErrorDesignTimeHtml to display the stack trace so you can figure out
where the error is without having to debug the component:&lt;br&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote dir=ltr style="MARGIN-RIGHT: 0px"&gt; 
&lt;div style="FONT-SIZE: 10pt; BACKGROUND: white; COLOR: black; FONT-FAMILY: Courier New"&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;protected&lt;/span&gt; &lt;span style="COLOR: blue"&gt;override&lt;/span&gt; &lt;span style="COLOR: blue"&gt;string&lt;/span&gt; GetErrorDesignTimeHtml(&lt;span style="COLOR: teal"&gt;Exception&lt;/span&gt; e)
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
{
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
&lt;span style="COLOR: blue"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;return&lt;/span&gt; CreateErrorDesignTimeHtml(&lt;span style="COLOR: maroon"&gt;"Error
creating the control "&lt;/span&gt; + e.StackTrace.ToString(), e);
&lt;/p&gt;
&lt;p style="MARGIN: 0px"&gt;
}
&lt;/p&gt;
&lt;/div&gt;
&lt;/blockquote&gt;
&lt;!--EndFragment--&gt;
&lt;ul&gt;
&lt;li&gt;
If your component is a class library you can debug it, choosing project properties-&amp;gt;debug-&amp;gt;start
external program-&amp;gt;(put complete path to devenv.exe).&lt;br&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;
That's all for now.&lt;br&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://www.manuelabadia.com/blog/aggbug.ashx?id=8cdc7001-bca7-4ea6-a3f8-0fb2861548f6" /&gt;</description>
      <comments>http://www.manuelabadia.com/blog/CommentView,guid,8cdc7001-bca7-4ea6-a3f8-0fb2861548f6.aspx</comments>
      <category>ASP.NET</category>
    </item>
  </channel>
</rss>