<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/atom.xsl" media="screen"?><feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en"><title type="html">"Peter and the case of the ASP.NET developer"</title><subtitle type="html">Solving the mysteries of ASP.NET web control development, ASP.NET Dynamic Data, and the products of PeterBlum.com.</subtitle><id>http://weblogs.asp.net/peterblum/atom.aspx</id><link rel="alternate" type="text/html" href="http://weblogs.asp.net/peterblum/default.aspx" /><link rel="self" type="application/atom+xml" href="http://weblogs.asp.net/peterblum/atom.aspx" /><generator uri="http://communityserver.org" version="3.0.20510.895">Community Server</generator><updated>2009-12-02T11:45:00Z</updated><entry><title>User Controls and the Publish Web Site command</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/peterblum/archive/2011/11/28/user-controls-and-the-publish-web-site-command.aspx" /><id>http://weblogs.asp.net/peterblum/archive/2011/11/28/user-controls-and-the-publish-web-site-command.aspx</id><published>2011-11-28T19:51:02Z</published><updated>2011-11-28T19:51:02Z</updated><content type="html">&lt;p&gt;Visual Studio 2010’s Publish Web Site command offers the option “Allow this precompiled site to be updatable”. When used and your application has User Control (.ascx) files, the published application no longer contains your user controls! Instead, the \bin folder contains new files ending in the .compiled extension, one for each User Control. Your User Controls still work though, just through some hidden behaviors that I will discuss here.&lt;/p&gt;  &lt;p&gt;First, the &lt;a href="http://msdn.microsoft.com/en-us/library/t9ecy7tf.aspx" target="_blank"&gt;Page.LoadControl()&lt;/a&gt; method still works. LoadControl() creates a User Control on demand. In the past, it had to build it from the User Control’s file contents. Without the file present, it knows about the missing files through those new files in the .bin folder.&lt;/p&gt;  &lt;p&gt;In my case, I was calling LoadControl after checking for a specific User Control file via a FileExists() function. I used &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.hosting.virtualpathprovider.fileexists.aspx" target="_blank"&gt;System.Web.Hosting.VirtualPathProvider.FileExists()&lt;/a&gt; function. It turns out that VirtualPathProvider.FileExists() does not support the .compiled files and always returns false.&lt;/p&gt;  &lt;p&gt;The solution comes from how ASP.NET Dynamic Data v4 does it: Use the &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.compilation.buildmanager.getobjectfactory.aspx" target="_blank"&gt;System.Web.Compilation.BuildManager.GetObjectFactory()&lt;/a&gt; method. Always pass false for the ThrowException parameter and test the result for null. If not null, the file exists.&lt;/p&gt;  &lt;p&gt;Here is a method that replaces the Page.LoadControl() method, loading a User Control if it exists. It works with the Publish Web Site feature as discussed.&lt;/p&gt;  &lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; System.Web.UI.WebControls.UserControl LoadUserControlIfExists(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; pVirtualFilePath)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;{&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (System.Web.Compilation.BuildManager.GetObjectFactory(pVirtualFilePath, &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;) != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; Page.LoadControl(pVirtualFilePath);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;}&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=8079373" width="1" height="1"&gt;</content><author><name>plblum</name><uri>http://weblogs.asp.net/members/plblum.aspx</uri></author><category term="ASP.NET 4" scheme="http://weblogs.asp.net/peterblum/archive/tags/ASP.NET+4/default.aspx" /><category term="Tricks of the trade" scheme="http://weblogs.asp.net/peterblum/archive/tags/Tricks+of+the+trade/default.aspx" /></entry><entry><title>More with ajax control toolkit’s combobox and Modalpopupextender</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/peterblum/archive/2011/09/16/more-with-ajax-control-toolkit-s-combobox-and-modalpopupextender.aspx" /><id>http://weblogs.asp.net/peterblum/archive/2011/09/16/more-with-ajax-control-toolkit-s-combobox-and-modalpopupextender.aspx</id><published>2011-09-16T16:16:00Z</published><updated>2011-09-16T16:16:00Z</updated><content type="html">&lt;p&gt;One idiosyncrasy of the ModalPopupExtender is that its HTML content is actually visible while the page is loading, until the $create() call initializes it. If you have a lengthy load time, as I did with a ListView full of records, the visibility is noticeable.&lt;/p&gt;  &lt;p&gt;One simple solution to this is to assign the style=”display:none” to the Control containing your content.&lt;/p&gt;  &lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:Panel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;AdvancedFiltersContainer&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;CssClass&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;AdvSch_PopupControl&amp;quot;&lt;/span&gt; &lt;font style="background-color: #ffff00"&gt;&lt;span style="color: #ff0000"&gt;Style&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;display:none;&amp;quot;&lt;/span&gt;&lt;/font&gt; &lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    content&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:Panel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;act:ModalPopupExtender&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Modal1&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Server&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;PopupControlID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;AdvancedFiltersContainer&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;act:ModalPopupExtender&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;However, I’ve learned that once an Ajax Control Toolkit ComboBox control is present, IE 9 (and presumably earlier browsers) reports a JavaScript error as the Combobox is being initialized. When the HTML for the combobox is hidden, its elements have an offsetWidth, offsetHeight, clientWidth, and clientHeight of 0. The ComboBox calculates a value based on offsetWidth, subtracts the size of the border, and assigns the result to a Style.width object.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Here is a snippet from the function, _getOptionListWidth, where the issue resides&lt;/em&gt;.&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #008000"&gt;// first, default to the clientWidth of the container&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; bestWidth = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.get_comboTableControl().offsetWidth;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #008000"&gt;// subtract borders from the offsetWidth&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;bestWidth -= (leftBorder + rightBorder);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&amp;#160;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #008000"&gt;// in order for ths list's scrollWidth to be correct, must set its width&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;var&lt;/span&gt; originalWidth = style.width;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;font style="background-color: #ffff00"&gt;style.width = bestWidth + &lt;span style="color: #006080"&gt;'px'&lt;/span&gt;&lt;/font&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;If you are paying attention, you’ll notice that when style.width is set, the value it gets is a negative number (0 – border width). That throws a JavaScript exception in IE 9. I’ve found that even assigning style.width to “0px” throws this exception.&lt;/p&gt;

&lt;p&gt;As a result, you cannot use style=”display:none;” to fix the problem I’ve raised, at least on IE 9.&lt;/p&gt;

&lt;p&gt;Here’s my simple solution.&lt;/p&gt;

&lt;p&gt;Assign style=”position:absolute;left:100000px;” instead. This will leave the ModalPopup visible, but way off screen. When ModalPopup initializes itself, it overwrites both position and left styles to fit its needs.&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:Panel&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;AdvancedFiltersContainer&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;CssClass&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;AdvSch_PopupControl&amp;quot;&lt;/span&gt; &lt;font style="background-color: #ffff00"&gt;&lt;span style="color: #ff0000"&gt;Style&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;position:absolute;left:100000px;&amp;quot;&lt;/span&gt;&lt;/font&gt; &lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;    content&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;asp:Panel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;act:ModalPopupExtender&lt;/span&gt; &lt;span style="color: #ff0000"&gt;id&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Modal1&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;runat&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;Server&amp;quot;&lt;/span&gt; &lt;span style="color: #ff0000"&gt;PopupControlID&lt;/span&gt;&lt;span style="color: #0000ff"&gt;=&amp;quot;AdvancedFiltersContainer&amp;quot;&lt;/span&gt; &lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;act:ModalPopupExtender&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7954920" width="1" height="1"&gt;</content><author><name>plblum</name><uri>http://weblogs.asp.net/members/plblum.aspx</uri></author><category term="ASP.NET 4" scheme="http://weblogs.asp.net/peterblum/archive/tags/ASP.NET+4/default.aspx" /><category term="Ajax Control Toolkit" scheme="http://weblogs.asp.net/peterblum/archive/tags/Ajax+Control+Toolkit/default.aspx" /></entry><entry><title>Fixing combobox from ajax control toolkit</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/peterblum/archive/2011/09/14/fixing-combobox-from-ajax-control-toolkit.aspx" /><id>http://weblogs.asp.net/peterblum/archive/2011/09/14/fixing-combobox-from-ajax-control-toolkit.aspx</id><published>2011-09-14T14:36:00Z</published><updated>2011-09-14T14:36:00Z</updated><content type="html">&lt;p&gt;I was using the ComboBox control of Microsoft’s Ajax Control Toolkit and ran into two issues.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;When its initially hidden (its inside something with a style of display:none) and you make it visible, the toggle button and actual dropdown list are incorrectly sized to be almost meaningless.      &lt;br /&gt;&lt;em&gt;how it should look:        &lt;br /&gt;&lt;/em&gt;&lt;a href="http://weblogs.asp.net/blogs/peterblum/ComboBox_OnShow_Correct_405751A6.png"&gt;&lt;em&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ComboBox_OnShow_Correct" border="0" alt="ComboBox_OnShow_Correct" src="http://weblogs.asp.net/blogs/peterblum/ComboBox_OnShow_Correct_thumb_38CBE239.png" width="244" height="201" /&gt;&lt;/em&gt;&lt;/a&gt;       &lt;br /&gt;&lt;em&gt;how it actually looks&lt;/em&gt;       &lt;br /&gt;&lt;a href="http://weblogs.asp.net/blogs/peterblum/ComboBox_OnShow_Incorrect_0D1B183D.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ComboBox_OnShow_Incorrect" border="0" alt="ComboBox_OnShow_Incorrect" src="http://weblogs.asp.net/blogs/peterblum/ComboBox_OnShow_Incorrect_thumb_13CE21C0.png" width="228" height="32" /&gt;&lt;/a&gt;       &lt;br /&gt;Notice the toggle button has virtually disappeared. That grey underline is the dropdown list.       &lt;br /&gt;      &lt;br /&gt;&lt;/li&gt;    &lt;li&gt;When its in a ModalDialog created by the ModalPopupExtender, the dropdown lists appear far away from where they belong.      &lt;br /&gt;&lt;em&gt;Here the Category dropdown toggle was clicked. The list should be flush with the bottom of the Category’s textbox.&lt;/em&gt;       &lt;br /&gt;&lt;a href="http://weblogs.asp.net/blogs/peterblum/ComboBox_InMDE_7E706C57.png"&gt;&lt;img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="ComboBox_InMDE" border="0" alt="ComboBox_InMDE" src="http://weblogs.asp.net/blogs/peterblum/ComboBox_InMDE_thumb_6BBB72A0.png" width="426" height="380" /&gt;&lt;/a&gt; &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;I created the following class to solve both of these problems. It was developed with v3.0.30512.1 of the AjaxControlToolkit.dll. (&lt;a href="http:///peterblum.com/Blog%20Files/ACTComboBoxFixer.zip"&gt;Get it as a zip file here&lt;/a&gt;)&lt;/p&gt;  &lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; max-height: 1600px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;   &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;     &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum1"&gt;   1:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// These static methods fix bugs related to the AjaxControlToolkit's ComboBox.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum4"&gt;   4:&lt;/span&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; ComboBoxFixer&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum5"&gt;   5:&lt;/span&gt;    {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum6"&gt;   6:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum7"&gt;   7:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// Use this when adding ACT Comboboxes that may be initially hidden when loaded.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum8"&gt;   8:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// It registers all comboboxes into a client-side array. If the user writes&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum9"&gt;   9:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// scripts that make the ACT Comboboxes visible, they should call&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum10"&gt;  10:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// ActComboBoxMadeVisible_All(), a client-side method.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum11"&gt;  11:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum12"&gt;  12:&lt;/span&gt;       &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; RegisterComboBox(AjaxControlToolkit.ComboBox pComboBox)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum13"&gt;  13:&lt;/span&gt;       {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum14"&gt;  14:&lt;/span&gt;          ClientScriptManager vClientScript = pComboBox.Page.ClientScript;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum15"&gt;  15:&lt;/span&gt;          &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!vClientScript.IsClientScriptBlockRegistered(&lt;span style="color: #006080"&gt;&amp;quot;ActComboBoxFixer&amp;quot;&lt;/span&gt;))&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum16"&gt;  16:&lt;/span&gt;          {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum17"&gt;  17:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; vScript =&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum18"&gt;  18:&lt;/span&gt;                &lt;span style="color: #006080"&gt;&amp;quot;function ActComboBoxMadeVisible_All()\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum19"&gt;  19:&lt;/span&gt;                &lt;span style="color: #006080"&gt;&amp;quot;{\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum20"&gt;  20:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;   if (window.gActComboboxes)\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum21"&gt;  21:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;      for (var vI = 0; vI &amp;lt; window.gActComboboxes.length; vI++)\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum22"&gt;  22:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;      {\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum23"&gt;  23:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;         var vCB = $find(window.gActComboboxes[vI]);\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum24"&gt;  24:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;         if (vCB)\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum25"&gt;  25:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;         {\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum26"&gt;  26:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;            ActComboBoxMadeVisible(vCB);\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum27"&gt;  27:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;         }\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum28"&gt;  28:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;      }\r\n&amp;quot;&lt;/span&gt; +  &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum29"&gt;  29:&lt;/span&gt;                &lt;span style="color: #006080"&gt;&amp;quot;}\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum30"&gt;  30:&lt;/span&gt;                &lt;span style="color: #006080"&gt;&amp;quot;function ActComboBoxMadeVisible(pCB)\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum31"&gt;  31:&lt;/span&gt;                &lt;span style="color: #006080"&gt;&amp;quot;{\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum32"&gt;  32:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;  if (pCB &amp;amp;&amp;amp; !pCB._optionListItemHeight)\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum33"&gt;  33:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;  {\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum34"&gt;  34:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;     var vBtn = pCB.get_buttonControl();\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum35"&gt;  35:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;     vBtn.style.width = '';\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum36"&gt;  36:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;     vBtn.style.height = '';\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum37"&gt;  37:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;     pCB.initializeButton();\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum38"&gt;  38:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;     pCB._optionListHeight = null;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum39"&gt;  39:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;     pCB._optionListWidth = null;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum40"&gt;  40:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;     pCB._optionListItemHeight = 21;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum41"&gt;  41:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;     pCB._getOptionListWidth();\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum42"&gt;  42:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;     pCB._getOptionListHeight();\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum43"&gt;  43:&lt;/span&gt;                 &lt;span style="color: #006080"&gt;&amp;quot;  }\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum44"&gt;  44:&lt;/span&gt;                &lt;span style="color: #006080"&gt;&amp;quot;}\r\n&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum45"&gt;  45:&lt;/span&gt;             vClientScript.RegisterClientScriptBlock(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(Page), &lt;span style="color: #006080"&gt;&amp;quot;ActComboBoxFixer&amp;quot;&lt;/span&gt;, vScript, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum46"&gt;  46:&lt;/span&gt;          }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum47"&gt;  47:&lt;/span&gt;          pComboBox.Page.ClientScript.RegisterArrayDeclaration(&lt;span style="color: #006080"&gt;&amp;quot;gActComboboxes&amp;quot;&lt;/span&gt;, &lt;span style="color: #006080"&gt;&amp;quot;'&amp;quot;&lt;/span&gt; + pComboBox.ClientID + &lt;span style="color: #006080"&gt;&amp;quot;'&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum48"&gt;  48:&lt;/span&gt;       }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum49"&gt;  49:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum50"&gt;  50:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum51"&gt;  51:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// Helps ModalDialogExtenders work with AjaxControlToolkit.ComboBox. Call for each ModalDialogExtender&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum52"&gt;  52:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// that may have ComboBoxes. If you have more than one and they may appear simulateously, add them&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum53"&gt;  53:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// in a specific order where the topmost one is added before those below it.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum54"&gt;  54:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum55"&gt;  55:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// &amp;lt;remarks&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum56"&gt;  56:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// &amp;lt;para&amp;gt;Requires each ComboBox is passed to ComboBoxFixer.RegisterComboBox.&amp;lt;/para&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum57"&gt;  57:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// &amp;lt;/remarks&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum58"&gt;  58:&lt;/span&gt; &lt;span style="color: #008000"&gt;/// &amp;lt;param name=&amp;quot;pModalExtender&amp;quot;&amp;gt;&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum59"&gt;  59:&lt;/span&gt;       &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; RegisterModalPopupExtender(AjaxControlToolkit.ModalPopupExtender pModalExtender)&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum60"&gt;  60:&lt;/span&gt;       {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum61"&gt;  61:&lt;/span&gt;          ClientScriptManager vClientScript = pModalExtender.Page.ClientScript;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum62"&gt;  62:&lt;/span&gt;          vClientScript.RegisterArrayDeclaration(&lt;span style="color: #006080"&gt;&amp;quot;gACTModalDEIDs&amp;quot;&lt;/span&gt;, &lt;span style="color: #006080"&gt;&amp;quot;'&amp;quot;&lt;/span&gt; + pModalExtender.ClientID + &lt;span style="color: #006080"&gt;&amp;quot;'&amp;quot;&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum63"&gt;  63:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum64"&gt;  64:&lt;/span&gt;          &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (!vClientScript.IsClientScriptBlockRegistered(&lt;span style="color: #006080"&gt;&amp;quot;ActComboBoxInMDE&amp;quot;&lt;/span&gt;))&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum65"&gt;  65:&lt;/span&gt;          {&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum66"&gt;  66:&lt;/span&gt;    &lt;span style="color: #008000"&gt;// The basic idea: Replace AjaxControlToolkit._popupShown with ActComboBoxInMDE_PopupShown.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum67"&gt;  67:&lt;/span&gt;    &lt;span style="color: #008000"&gt;// ActComboBoxInMDE_PopupShown is a clone of _popupShown, but inserts code to change x,y&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum68"&gt;  68:&lt;/span&gt;    &lt;span style="color: #008000"&gt;// when a ModalDialogExtender is visible. &lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum69"&gt;  69:&lt;/span&gt;    &lt;span style="color: #008000"&gt;// MDEs are registerd in the client-side array gACTModalDEIDs.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum70"&gt;  70:&lt;/span&gt;    &lt;span style="color: #008000"&gt;// This allows multiple MDEs and will only evaluate the first whose content element (called _foregroundElement)&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum71"&gt;  71:&lt;/span&gt;    &lt;span style="color: #008000"&gt;// is visible. So if there are nested MDEs, register the topmost one first and bottommost last.&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum72"&gt;  72:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; vScript =&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum73"&gt;  73:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;function ActComboBoxInMDE_Init()\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum74"&gt;  74:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;{\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum75"&gt;  75:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   if (window.gActComboboxes)\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum76"&gt;  76:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;      for (var vI = 0; vI &amp;lt; gActComboboxes.length; vI++)\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum77"&gt;  77:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;      {\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum78"&gt;  78:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;         var vCB = $find(gActComboboxes[vI]);\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum79"&gt;  79:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;         if (vCB.InitedMDE) continue;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum80"&gt;  80:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;         vCB._popupShown = ActComboBoxInMDE_PopupShown;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum81"&gt;  81:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;         vCB._popupShownHandlerFix = Function.createDelegate(vCB, ActComboBoxInMDE_PopupShown);\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum82"&gt;  82:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;         vCB._popupBehavior.add_shown(vCB._popupShownHandlerFix);\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum83"&gt;  83:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;         vCB.InitedMDE = 1;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum84"&gt;  84:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;      }\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum85"&gt;  85:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;}\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum86"&gt;  86:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;function ActComboBoxInMDE_PopupShown() {\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum87"&gt;  87:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum88"&gt;  88:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   this.get_optionListControl().style.display = 'block';\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum89"&gt;  89:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum90"&gt;  90:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   // check and enforce correct positioning.\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum91"&gt;  91:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   var tableBounds = Sys.UI.DomElement.getBounds(this.get_comboTableControl());\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum92"&gt;  92:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   var listBounds = Sys.UI.DomElement.getBounds(this.get_optionListControl());\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum93"&gt;  93:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   var textBoxBounds = Sys.UI.DomElement.getBounds(this.get_textBoxControl());\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum94"&gt;  94:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   var y = listBounds.y;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum95"&gt;  95:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   var x;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum96"&gt;  96:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum97"&gt;  97:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   if (this._popupBehavior.get_positioningMode() === AjaxControlToolkit.PositioningMode.BottomLeft\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum98"&gt;  98:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;      || this._popupBehavior.get_positioningMode() === AjaxControlToolkit.PositioningMode.TopLeft) {\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum99"&gt;  99:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;      x = textBoxBounds.x;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum100"&gt; 100:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   }\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum101"&gt; 101:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   else if (this._popupBehavior.get_positioningMode() === AjaxControlToolkit.PositioningMode.BottomRight\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum102"&gt; 102:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;      || this._popupBehavior.get_positioningMode() === AjaxControlToolkit.PositioningMode.TopRight) {\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum103"&gt; 103:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;      x = textBoxBounds.x - (listBounds.width - textBoxBounds.width);\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum104"&gt; 104:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   }\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum105"&gt; 105:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum106"&gt; 106:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   if (window.gACTModalDEIDs)\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum107"&gt; 107:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;      for (var vI = 0; vI &amp;lt; gACTModalDEIDs.length; vI++)\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum108"&gt; 108:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;      {\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum109"&gt; 109:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;         var vMDE = $find(gACTModalDEIDs[vI]);\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum110"&gt; 110:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;         if (vMDE._foregroundElement.style.display == '')\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum111"&gt; 111:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;         {\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum112"&gt; 112:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;            var vMDBounds = Sys.UI.DomElement.getBounds(vMDE._foregroundElement);\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum113"&gt; 113:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;            x = x - vMDBounds.x;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum114"&gt; 114:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;            y = (textBoxBounds.y + textBoxBounds.height) - vMDBounds.y;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum115"&gt; 115:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;            break;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum116"&gt; 116:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;         }\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum117"&gt; 117:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;      }\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum118"&gt; 118:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   Sys.UI.DomElement.setLocation(this.get_optionListControl(), x, y);\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum119"&gt; 119:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum120"&gt; 120:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   // enforce default scroll\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum121"&gt; 121:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   this._ensureHighlightedIndex();\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum122"&gt; 122:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   this._ensureScrollTop();\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum123"&gt; 123:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum124"&gt; 124:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   // show the option list\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum125"&gt; 125:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   this.get_optionListControl().style.visibility = 'visible';\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum126"&gt; 126:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum127"&gt; 127:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;}\r\n&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum128"&gt; 128:&lt;/span&gt;             vClientScript.RegisterClientScriptBlock(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(Page), &lt;span style="color: #006080"&gt;&amp;quot;ActComboBoxInMDE&amp;quot;&lt;/span&gt;, vScript, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum129"&gt; 129:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum130"&gt; 130:&lt;/span&gt;             vClientScript.RegisterStartupScript(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(Page), &lt;span style="color: #006080"&gt;&amp;quot;ActComboBoxInMDEInit&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum131"&gt; 131:&lt;/span&gt;                &lt;span style="color: #006080"&gt;&amp;quot;Sys.Application.add_load(ActComboBoxInMDE_Init);\r\n&amp;quot;&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum132"&gt; 132:&lt;/span&gt;&amp;#160; &lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum133"&gt; 133:&lt;/span&gt;             &lt;span style="color: #008000"&gt;// on MDE popup, also fix comboboxes&lt;/span&gt;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum134"&gt; 134:&lt;/span&gt;             vScript =&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum135"&gt; 135:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;function ActComboBoxInMDE_MDEPopupInit()\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum136"&gt; 136:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;{\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum137"&gt; 137:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   if (window.gACTModalDEIDs)\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum138"&gt; 138:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;      for (var vI = 0; vI &amp;lt; gACTModalDEIDs.length; vI++)\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum139"&gt; 139:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;      {\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum140"&gt; 140:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;         var vMD = $find(gACTModalDEIDs[vI]);\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum141"&gt; 141:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;         vMD.add_shown(ActComboBoxInMDE_MDEPopupShown);\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum142"&gt; 142:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;      }\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum143"&gt; 143:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;}\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum144"&gt; 144:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;function ActComboBoxInMDE_MDEPopupShown(sender, args)\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum145"&gt; 145:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;{\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum146"&gt; 146:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;   if (window.ActComboBoxMadeVisible_All)\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum147"&gt; 147:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;      ActComboBoxMadeVisible_All();\r\n&amp;quot;&lt;/span&gt; +&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum148"&gt; 148:&lt;/span&gt;             &lt;span style="color: #006080"&gt;&amp;quot;}\r\n&amp;quot;&lt;/span&gt;;&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum149"&gt; 149:&lt;/span&gt;             vClientScript.RegisterClientScriptBlock(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(Page), &lt;span style="color: #006080"&gt;&amp;quot;ActComboBoxInMDE_MDEPopupInitBlock&amp;quot;&lt;/span&gt;, vScript, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum150"&gt; 150:&lt;/span&gt;             vClientScript.RegisterStartupScript(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(Page), &lt;span style="color: #006080"&gt;&amp;quot;ActComboBoxInMDE_MDEPopupInit&amp;quot;&lt;/span&gt;,&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum151"&gt; 151:&lt;/span&gt;                &lt;span style="color: #006080"&gt;&amp;quot;Sys.Application.add_load(ActComboBoxInMDE_MDEPopupInit);\r\n&amp;quot;&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum152"&gt; 152:&lt;/span&gt;          }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum153"&gt; 153:&lt;/span&gt;       }&lt;/pre&gt;
&lt;!--CRLF--&gt;

    &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;&lt;span style="color: #606060" id="lnum154"&gt; 154:&lt;/span&gt;    }&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
&lt;/div&gt;

&lt;p&gt;You can retrieve a zip file with C# and VB versions of this code &lt;a href="http:///peterblum.com/Blog%20Files/ACTComboBoxFixer.zip"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Here is how to use this class:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Call ComboBoxFixer.RegisterComboBox(combobox) for each ComboBox that is initially hidden. Generally this is done in Page_Load or if inside of a Databound control like ListView or FormView, from their ItemCreated event. &lt;/li&gt;

  &lt;li&gt;Call ComboBoxFixer.RegisterModalPopupExtender(modalpopupextender) for each ModalPopupExtender that contains ComboBoxes. If you have nested ModalDialogs, register the topmost first. &lt;/li&gt;

  &lt;li&gt;If you have a button that makes the comboboxes visible, add this javascript to its client-side onclick event. It must be run after the comboboxes are visible. 
    &lt;br /&gt;

    &lt;div style="border-bottom: silver 1px solid; text-align: left; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; height: 39px; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
      &lt;div style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: #f4f4f4; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;
        &lt;pre style="border-bottom-style: none; text-align: left; padding-bottom: 0px; line-height: 12pt; background-color: white; margin: 0em; border-left-style: none; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; direction: ltr; border-top-style: none; color: black; border-right-style: none; font-size: 8pt; overflow: visible; padding-top: 0px"&gt;ActComboBoxMadeVisible_All();&lt;/pre&gt;
&lt;!--CRLF--&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A little background on what these scripts do:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;The ComboBox initializes the sizes of its toggle button and list when the page is first loaded. If this happens when the control is hidden, its calculations do not get the correct sizing information as the clientWidth and clientHeight properties of DOM elements are usually 0 in this case. The ActComboBoxMadeVisible(cb) function resets properties that determine width. It explicitly calls a function to recalculate the button size and lets the ComboBox’s _popupShowing() method use the rest to know to recalculate. &lt;/li&gt;

  &lt;li&gt;The ComboBox’s _popupShown() method calculates the x and y coordinates for the dropdownlist using the offset of its textbox from the upper left of the browser window. It uses style=”position:absolute;top:x;left:y;” to position it. This works well until the ModalPopupExtender gets involved. The ModalPopupExtender uses style=”position:fixed” and this appears to impact positioning. _popupShown() needs to position from the upper left of the &amp;lt;div&amp;gt; using that style=”position:fixed”. 
    &lt;br /&gt;To fix this, _popupShown() is replaced by a clone generated by ComboBoxFixer.RegisterModalPopupExtender(). This new function inserts code that detects if a ModalPopupExtender is visible and adjusts the x and y coordinates based on its location. &lt;/li&gt;
&lt;/ol&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7952424" width="1" height="1"&gt;</content><author><name>plblum</name><uri>http://weblogs.asp.net/members/plblum.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/peterblum/archive/tags/ASP.NET/default.aspx" /><category term="Ajax Control Toolkit" scheme="http://weblogs.asp.net/peterblum/archive/tags/Ajax+Control+Toolkit/default.aspx" /></entry><entry><title>Defending against Lizamoon Attack</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/peterblum/archive/2011/04/03/defending-against-lizamoon-attack.aspx" /><id>http://weblogs.asp.net/peterblum/archive/2011/04/03/defending-against-lizamoon-attack.aspx</id><published>2011-04-03T18:47:00Z</published><updated>2011-04-03T18:47:00Z</updated><content type="html">&lt;p&gt;Lizamoon is the name of a SQL Injection attack heavily reported in the press since the end of March 2011. It inserts a &amp;lt;script&amp;gt; tag into your database that when returned, redirects to another site (sometimes with the domain name Lizamoon). That site uses social engineering to entice the user to download what they think is antivirus software, and later to get them to provide credit card information to pay for it. At that point, the hackers have stolen their credit card information.&lt;/p&gt;  &lt;p&gt;You can read more with these articles:&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.pcworld.com/article/223995/millions_of_sites_hit_with_massinjection_cyberattack.html" target="_blank"&gt;pcworld, April 1: “Millions of Sites Hit with Mass-Injection Cyberattack”&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.eweek.com/c/a/Security/LizaMoon-Mass-SQL-Injection-Attack-Escalates-Out-of-Control-378108/" target="_blank"&gt;eweek, April 1, “'LizaMoon' Mass SQL Injection Attack Escalates Out of Control”&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Based on this thread from last September amongst Stackoverflow.com users, I think this attack has existing long before the March 28 date reported in the press:&lt;/p&gt; &lt;a href="http://stackoverflow.com/questions/3788080/attack-on-asp-site-that-uses-a-sql-server-database"&gt;Attack on ASP site that uses a SQL server database&lt;/a&gt; (starts on Sept 10, 2010)  &lt;br /&gt;  &lt;p&gt;Users of &lt;a href="http://www.peterblum.com/des/inputsecurity.aspx" target="_blank"&gt;Peter’s Input Security&lt;/a&gt; (a module within my &lt;a href="http://www.peterblum.com/des/home.aspx" target="_blank"&gt;Peter’s Data Entry Suite&lt;/a&gt;) have the tools to defend against this attack. But just having the tools, doesn’t mean you are protected. As a rule, you must evaluate any inputs of each page to determine if they are secure or not. A web page has these “inputs” which hackers use to attack: data entry controls like textboxes, cookies, hidden fields, and query string parameters. (They also can use web services.)&lt;/p&gt;  &lt;p&gt;This post discusses how to check your Peter’s Input Security settings to defend against the Lizamoon attack.&lt;/p&gt;  &lt;p&gt;If you are on a DES 4 version below 4.0.6, get to DES 4.0.6 and apply a hotfix. Future releases will have the hotfix incorporated. The hotfix introduces a new feature that further assists in protecting you, but is not required. If you are using VAM or do not want to use the hotfix, I’ve included instructions for you below.&lt;/p&gt;  &lt;h2&gt;Getting v4.0.6 and the hotfix&lt;/h2&gt;  &lt;p&gt;&lt;em&gt;Note: This hotfix has a minor &lt;font style="background-color: #ffc000"&gt;breaking change&lt;/font&gt; to Peter’s Input Security that is described in step 5 of “Protecting yourself with the DetectDatabaseElementNamesInQueryString property”, below.&lt;/em&gt;&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;You &lt;b&gt;must&lt;/b&gt; use DES 4.0.6 to apply this hotfix.       &lt;br /&gt;If you do not have it installed, go to &lt;a href="http://www.peterblum.com/getupdate.aspx"&gt;http://www.peterblum.com/getupdate.aspx&lt;/a&gt;, login and download it. If you do not know your login, get your serial number and contact Peter at PLBlum@PeterBlum.com to request it.       &lt;br /&gt;Run the .msi to install 4.0.6.       &lt;br /&gt;Run the v4.0.6 Web Application Updater with the option &amp;quot;Update a web application (service release)&amp;quot;. This application is found in your Start menu and the folder where you installed DES. &lt;/li&gt;    &lt;li&gt;Get the hotfix at &lt;a href="http://www.peterblum.com/hotfixes/PeterBlum.DES4_0_6_5000.zip"&gt;http://www.peterblum.com/hotfixes/PeterBlum.DES4_0_6_5000.zip&lt;/a&gt;.       &lt;br /&gt;&lt;i&gt;Note: This hotfix rolls up all previous hotfixes for v4.0.6&lt;/i&gt;.       &lt;br /&gt;Unzip the file.       &lt;br /&gt;Replace the PeterBlum.DES.dll in your web application. Be sure that your Visual Studio project has a reference to this new assembly.       &lt;br /&gt;Clear your IE9 RC1 browser's cache if you were already using 4.0.6. &lt;/li&gt; &lt;/ol&gt;  &lt;h2&gt;Understanding the new feature of the hotfix&lt;/h2&gt;  &lt;p&gt;The new feature is the &lt;strong&gt;DetectDatabaseElementNamesInQueryString&lt;/strong&gt; property on the PageSecurityValidator manager.&amp;#160; When this property is &lt;font face="Courier New"&gt;true&lt;/font&gt; (the default), the PageSecurityValidator evaluates every query string parameter for any value defined in the &amp;lt;databaseelementnames&amp;gt; node of the [web app]\DES\Security Config Files\master.config file and report an error if found.&lt;/p&gt;  &lt;p&gt;This feature detects lizamoon because the attack incorporates the names of tables and columns from you database, previously extracted through another hack directed at your databases’s master tables. Here is its SQL attack pattern:&lt;/p&gt;  &lt;p&gt;&lt;font face="Courier New"&gt;update [your table name] set [your field name] = REPLACE(…)&lt;/font&gt;&lt;/p&gt;  &lt;p&gt;The &amp;lt;databaseelementnames&amp;gt; section of master.config is intended to hold names of tables and important column names that you do not want to appear within your inputs. It works best when your table and column names are not spoken languages, such as using “tbl_client” instead of “client” for a table of clients. Here is an example of this node. (The file is here: [web app]\DES\Security Config Files\master.config)&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;databaseelementnames&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;item&lt;/span&gt; &lt;span class="attr"&gt;action&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;add&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;tbl_products&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;item&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;item&lt;/span&gt; &lt;span class="attr"&gt;action&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;add&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;tbl_orders&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;item&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;item&lt;/span&gt; &lt;span class="attr"&gt;action&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;add&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;tbl_categories&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;item&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;databaseelementnames&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }
&lt;/style&gt;&lt;/pre&gt;

&lt;h2&gt;Protecting yourself with the DetectDatabaseElementNamesInQueryString property&lt;/h2&gt;

&lt;p&gt;By default, &lt;strong&gt;DetectDatabaseElementNamesInQueryString&lt;/strong&gt; is &lt;font face="Courier New"&gt;true&lt;/font&gt;, which means the feature is active. Yet, it does nothing if you have not setup the page correctly.&lt;/p&gt;

&lt;p&gt;1. If you are new to Peter’s Input Security, follow the directions of the &lt;strong&gt;Input Security Installation Guide&lt;/strong&gt;. This will enable loading the various config files, have you describe key elements about your app, and install a logging feature to capture attacks.&lt;/p&gt;

&lt;p&gt;2. If you have not setup the page for Peter’s Input Security, follow the steps in the “Securing a Page” section of the &lt;strong&gt;Input Security User’s Guide&lt;/strong&gt;. &lt;em&gt;There are many actions to lock down all inputs. Be prepared to spend some time protecting each page.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;3. At this point, your page has a PageSecurityValidator with the &lt;strong&gt;DetectDatabaseElementNamesInQueryString&lt;/strong&gt; set to &lt;font face="Courier New"&gt;true&lt;/font&gt; (the default). If you do nothing else, this attack will be prevented.&lt;/p&gt;

&lt;p&gt;4. Query string parameters that accept string values may have legal values blocked by the &lt;strong&gt;DetectDatabaseElementNamesInQueryString&lt;/strong&gt; property. Review those parameters against the values in the &amp;lt;databaseelementnames&amp;gt; node of [web app]\DES\Security Config Files\master.config. If there is a legal value, set &lt;strong&gt;DetectDatabaseElementNamesInQueryString&lt;/strong&gt; to &lt;font face="Courier New"&gt;false&lt;/font&gt;. Then add a &lt;strong&gt;ParameterRule&lt;/strong&gt; object to the &lt;strong&gt;QueryStringRules&lt;/strong&gt; object with its &lt;strong&gt;DataType&lt;/strong&gt;=&lt;font face="Courier New"&gt;String&lt;/font&gt; and &lt;strong&gt;DetectInjection&lt;/strong&gt;=&lt;font face="Courier New"&gt;true&lt;/font&gt; (the default). Also adjust the &lt;strong&gt;SQLDetectionLevel&lt;/strong&gt; property, which defaults to the highest protection. &lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;des:PageSecurityValidator&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;PageSecurityValidator1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DetectDatabaseElementNamesInQueryString&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;false&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;QueryStringRules&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;des:ParameterRule&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;search&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DataType&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;String&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DetectInjection&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;SQLDetectionLevel&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;MediumLow&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;QueryStringRules&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;des:PageSecurityValidator&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;style type="text/css"&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;5. The hotfix also introduced a &lt;em&gt;&lt;font style="background-color: #ffc000"&gt;breaking change&lt;/font&gt;&lt;/em&gt; by changing the default of the &lt;strong&gt;DetectInjection&lt;/strong&gt; property from &lt;font face="Courier New"&gt;false&lt;/font&gt; to &lt;font face="Courier New"&gt;true&lt;/font&gt; on the &lt;strong&gt;HiddenFieldRule&lt;/strong&gt;, &lt;strong&gt;ParameterRule&lt;/strong&gt;, and &lt;strong&gt;QueryStringRule&lt;/strong&gt; objects. This breaking change only applies to Rules that: 

&lt;ul&gt;
  &lt;li&gt;do not set &lt;strong&gt;DetectInjection&lt;/strong&gt;, thus using the default. &lt;/li&gt;

  &lt;li&gt;has its &lt;strong&gt;DataType&lt;/strong&gt; property set to &lt;font face="Courier New"&gt;Ignore&lt;/font&gt; or &lt;font face="Courier New"&gt;String&lt;/font&gt;, or does not set &lt;strong&gt;DataType&lt;/strong&gt; (which defaults to &lt;font face="Courier New"&gt;Ignore&lt;/font&gt;) &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Look through your PageSecurityValidators to locate Rules that are now using &lt;strong&gt;DetectInjection&lt;/strong&gt;=&lt;font face="Courier New"&gt;true&lt;/font&gt;. If you do not want that behavior, set its &lt;strong&gt;DetectInjection&lt;/strong&gt; property to &lt;font face="Courier New"&gt;false&lt;/font&gt;.&lt;/p&gt;

&lt;h2&gt;Protecting yourself with VAM or without the DES hotfix&lt;/h2&gt;

&lt;p&gt;This topic helps users who have Professional Validation and More (“VAM”) as well as DES without the hotfix.&lt;/p&gt;

&lt;p&gt;1. If you are new to Peter’s Input Security, follow the directions of the &lt;strong&gt;Input Security Installation Guide&lt;/strong&gt;. This will enable loading the various config files, have you describe key elements about your app, and install a logging feature to capture attacks.&lt;/p&gt;

&lt;p&gt;2. If you have not setup the page for Peter’s Input Security, follow the steps in the “Securing a Page” section of the &lt;strong&gt;Input Security User’s Guide&lt;/strong&gt;. &lt;em&gt;There are many actions to lock down all inputs. Be prepared to spend some time protecting each page.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;3. Review the &lt;strong&gt;QueryStringRules&lt;/strong&gt; collection of each &lt;strong&gt;PageSecurityValidator&lt;/strong&gt; to be sure that every query string parameter used by this page is listed, with the appropriate rules. When a &lt;strong&gt;ParameterRule&lt;/strong&gt; has its &lt;strong&gt;DataType&lt;/strong&gt; property set to &lt;font face="Courier New"&gt;Ignore&lt;/font&gt; or &lt;font face="Courier New"&gt;String&lt;/font&gt;, or it does not declare the &lt;strong&gt;DataType&lt;/strong&gt; property are candidates for this attack. Your defense is to set &lt;strong&gt;DetectInjection&lt;/strong&gt; to &lt;font face="Courier New"&gt;true&lt;/font&gt;.&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;des:PageSecurityValidator&lt;/span&gt; &lt;span class="attr"&gt;ID&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;PageSecurityValidator1&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;runat&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;server&amp;quot;&lt;/span&gt; &lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
   &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;QueryStringRules&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
      &lt;span class="kwrd"&gt;&amp;lt;&lt;/span&gt;&lt;span class="html"&gt;des:ParameterRule&lt;/span&gt; &lt;span class="attr"&gt;Name&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;search&amp;quot;&lt;/span&gt; &lt;span class="attr"&gt;DataType&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;String&amp;quot;&lt;/span&gt; &lt;font style="background-color: #ffff00"&gt;&lt;span class="attr"&gt;DetectInjection&lt;/span&gt;&lt;span class="kwrd"&gt;=&amp;quot;true&amp;quot;&lt;/span&gt;&lt;/font&gt; &lt;span class="kwrd"&gt;/&amp;gt;&lt;/span&gt;
   &lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;QueryStringRules&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="kwrd"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="html"&gt;des:PageSecurityValidator&lt;/span&gt;&lt;span class="kwrd"&gt;&amp;gt;&lt;/span&gt;    &lt;/pre&gt;
&lt;style type="text/css"&gt;



.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7741857" width="1" height="1"&gt;</content><author><name>plblum</name><uri>http://weblogs.asp.net/members/plblum.aspx</uri></author><category term="Peter's Data Entry Suite" scheme="http://weblogs.asp.net/peterblum/archive/tags/Peter_2700_s+Data+Entry+Suite/default.aspx" /><category term="Input security" scheme="http://weblogs.asp.net/peterblum/archive/tags/Input+security/default.aspx" /></entry><entry><title>Exploring Dynamic Data: Other attributes for business logic</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/peterblum/archive/2009/12/29/exploring-dynamic-data-other-attributes-for-business-logic.aspx" /><id>http://weblogs.asp.net/peterblum/archive/2009/12/29/exploring-dynamic-data-other-attributes-for-business-logic.aspx</id><published>2009-12-29T22:21:00Z</published><updated>2009-12-29T22:21:00Z</updated><content type="html">
&lt;p&gt;&lt;a href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx" mce_href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx"&gt;Index to this series of articles&lt;/a&gt;&lt;/p&gt;
  &lt;div style="background-color: rgb(255, 255, 204); margin-left: 50px; margin-right: 50px;"&gt;   
&lt;p&gt;Business logic is applied to your Entity classes (objects that describe individual tables where columns are the properties) through metadata. Typically this metadata is defined by applying attributes from the &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations%28VS.100%29.aspx"&gt;System.ComponentModel.DataAnnotations namespace&lt;/a&gt;.&lt;/p&gt;
 &lt;/div&gt;  
&lt;p&gt;To successfully let business logic drive the user interface, you need an extensive library of business rules. Here are the additional business rules available as attributes. In my “Peter’s Soapbox”, you will find attributes that I feel need to be provided to complete the library.&lt;/p&gt;
  
&lt;ul&gt;   
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.defaultvalueattribute.aspx"&gt;DefaultValueAttribute&lt;/a&gt; – Supplies the initial value for the column when creating a new record. Generally this value is assigned to the user interface to establish a default. ASP.NET Dynamic Data supports it in the FieldValue property of FieldTemplateUserControl class. FieldValue is generally assigned to the data entry control when generating the HTML output. If in Insert mode, it uses the default. Otherwise it uses the value previously stored. &lt;/li&gt;
    
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayformatattribute%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayformatattribute(VS.100).aspx"&gt;DisplayFormatAttribute&lt;/a&gt; – Column values that need to be displayed as strings use the DisplayFormatAttribute to assist in converting from its native type to the string. &lt;/li&gt;
    
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displaycolumnattribute%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displaycolumnattribute(VS.100).aspx"&gt;DisplayColumnAttribute&lt;/a&gt; – Applied to the Entity class definition, it specifies which column to display in lists, such as those shown in filters or in foreign key links. For example, you may want to show the Last Name column in lists. By default, Dynamic Data uses the first column of type string that it finds. It also lets you change the default sorting, to specify a different column and sort order. &lt;/li&gt;

&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.editableattribute%28VS.95%29.aspx" target="_blank" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.editableattribute%28VS.95%29.aspx"&gt;EditableAttribute&lt;/a&gt; - Introduced in .net 4, it's a bit like a security oriented attribute. It tells the client application whether a column can be made editable or not. It also tells the client application whether insert mode allows an entry. Typically its used to define a read only column and perhaps to express that the user can still enter a value in insert mode.&lt;br&gt;&lt;/li&gt;
    
&lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.keyattribute%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.keyattribute%28VS.100%29.aspx"&gt;KeyAttribute&lt;/a&gt; – When your Entity class is not generated by Entity Framework or LINQ to SQL, use this attribute to identify columns that are primary keys. Primary keys have special behaviors in the user interface. &lt;/li&gt;
 &lt;/ul&gt;
  &lt;h1&gt;Peter’s Soapbox&lt;/h1&gt;  
&lt;p&gt;Is that it? A handful of Validation attributes, 2 DataTypeAttributes, and the rest mentioned in the last few postings? I’ve already mentioned in those posts where I felt the attributes were lacking. Here’s some more.&lt;/p&gt;
  &lt;h3&gt;Security roles attributes&lt;/h3&gt;  
&lt;p&gt;Role-based security restrictions to tables and columns is industry standard stuff. Where’s the support?&lt;/p&gt;
  
&lt;p&gt;My next release of &lt;a href="http://www.peterblum.com/DES/Home.aspx" mce_href="http://www.peterblum.com/DES/Home.aspx"&gt;Peter’s Data Entry Suite&lt;/a&gt; introduces the ColumnRestrictionAttribute and TableRestrictionAttribute. For example:&lt;/p&gt;
  &lt;div id="codeSnippetWrapper"&gt;   
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 114.24%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 88px; color: black; font-size: 8pt;" id="codeSnippet"&gt;[DES.ColumnRestriction(&lt;span style="color: rgb(0, 96, 128);"&gt;"Admin"&lt;/span&gt;, DES.DenyAccess.None)]&lt;br&gt;[DES.ColumnRestriction(&lt;span style="color: rgb(0, 96, 128);"&gt;"Sales"&lt;/span&gt;, DES.DenyAccess.Insert | DES.DenyAccess.Edit)]&lt;br&gt;[DES.ColumnRestriction(&lt;span style="color: rgb(0, 96, 128);"&gt;"Support"&lt;/span&gt;, DES.DenyAccess.View)]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; Photo { get; set; }&lt;/pre&gt; &lt;br&gt;&lt;/div&gt;

&lt;h3&gt;Dependency attributes&lt;/h3&gt;

&lt;p&gt;Often on field is required based on the state of another. For example, when the column “CustomerType” has a value of “Other”, the OtherDescription field should require a value. The user interface would enable and disable both the textbox and validator associated with the OtherDescription field based on the setting of the CustomerType DropDownList. It’s a pretty standard thing and not too difficult to create attributes to describe.&lt;/p&gt;

&lt;p&gt;This is already supported in my Peter’s Data Entry Suite.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;[DES.RequiredDependency(ColumnNames=&lt;span style="color: rgb(0, 96, 128);"&gt;"PrinterType|FaxType"&lt;/span&gt;,&lt;br&gt;    MultipleMode=PeterBlum.DES.MultipleRequiredControlsMode.AtLeastOne)]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; OutputHeading {get; set; }&lt;/pre&gt; &lt;br&gt;&lt;/div&gt;
&lt;h3&gt;Column is sortable attribute&lt;/h3&gt;

&lt;p&gt;The column headers of the ListView and GridView can usually be clicked to sort them. Another user interface would be to offer a dropdownlist of sortable fields. These user interfaces should be driven by the business logic through a SortableColumnAttribute. It not only determines if sorting is active, but also specifies the Sort Expression to apply.&lt;/p&gt;

&lt;p&gt;Again, already supported in my Peter’s Data Entry Suite.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;[DES.SortableColumn(&lt;span style="color: rgb(0, 0, 255);"&gt;false&lt;/span&gt;)]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; Notes { get; set; }&lt;/pre&gt; &lt;br&gt;&lt;/div&gt;
&lt;h3&gt;Using the CategoryAttribute&lt;/h3&gt;

&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.categoryattribute.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.categoryattribute.aspx" target="_blank"&gt;System.ComponentModel.CategoryAttribute&lt;/a&gt; can be used in creative ways. Take a look at my earlier posting on the subject: &lt;a href="http://weblogs.asp.net/peterblum/archive/2009/12/09/the-categoryattribute-and-dynamic-data.aspx" mce_href="http://weblogs.asp.net/peterblum/archive/2009/12/09/the-categoryattribute-and-dynamic-data.aspx"&gt;The CategoryAttribute and Dynamic Data&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Text entry attributes&lt;/h3&gt;

&lt;p&gt;Often the only difference between string column values is the pattern and character set permitted. Both can be used by textboxes to enhance entry. In addition, they are used by validators. Here’s how.&lt;/p&gt;

&lt;ul&gt;
  
&lt;li&gt;Pattern. Think of the “masked textbox” concept. Let’s suppose that you declare: 
    &lt;div id="codeSnippetWrapper"&gt;
      
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;[TextMask(&lt;span style="color: rgb(0, 96, 128);"&gt;"999-999-9999"&lt;/span&gt;)]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; SocialSecurityNumber { get; set; }&lt;/pre&gt; &lt;br&gt;&lt;/div&gt;
    
&lt;p&gt;The Text_Edit.ascx Field Template can use this to establish the &lt;a href="http://www.asp.net/AJAX/AjaxControlToolkit/Samples/MaskedEdit/MaskedEdit.aspx" mce_href="http://www.asp.net/AJAX/AjaxControlToolkit/Samples/MaskedEdit/MaskedEdit.aspx"&gt;MaskedEdit Extender&lt;/a&gt; control on it’s textbox. With a converter routine, it can also be converted into a regular expression that is applied to the RegularExpressionValidator in the Field Template. (Or the Field Template can create a MaskedEditValidator.)&lt;/p&gt;

    
&lt;p&gt;&lt;i&gt;I think the TextMaskAttribute should be a subclass of DataTypeAttribute so there can be a standard Field Template called TextMask_Edit.ascx.&lt;/i&gt;&lt;/p&gt;
  &lt;/li&gt;

  
&lt;li&gt;Character set. Many strings don’t have a pattern, but have a limited character set. For example, a person’s first name may be limited to upper and lower case letters. Again the Field Template establishes the necessary javascript to apply the character set, and sets up the RegularExpressionValidator to limit to those characters. 
    &lt;div id="codeSnippetWrapper"&gt;
      
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;[CharacterSet(Digits=&lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;, Othercharacters=&lt;span style="color: rgb(0, 96, 128);"&gt;"-"&lt;/span&gt;)]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; SocialSecurityNumber { get; set; }&lt;/pre&gt;
    &lt;/div&gt;
    
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;Injection attack attributes&lt;/h3&gt;

&lt;p&gt;Business logic determines what’s legal within strings. Hackers employ SQL Injection and Cross Site Scripting attacks through your web form’s inputs. String type fields should determine what HTML patterns and SQL statements are allowed or rejected.&lt;/p&gt;

&lt;p&gt;Field Templates should use these attributes to generate a CustomValidator control that invokes your Injection detection code (server side only). &lt;i&gt;What? You don’t have one? There’s one in my Peter’s Data Entry Suite called &lt;a href="http://www.peterblum.com/DES/inputsecurity.aspx" mce_href="http://www.peterblum.com/DES/inputsecurity.aspx" target="_blank"&gt;Peter’s Input Security&lt;/a&gt;.&lt;/i&gt;&lt;/p&gt;

&lt;h1&gt;Once again: “Is that all?”&lt;/h1&gt;

&lt;p&gt;I highly doubt that’s all of the business rules for entity objects. Feel free to describe your own cases in the comments.&lt;/p&gt;

&lt;p&gt;&amp;nbsp; &lt;br&gt;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx" mce_href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx"&gt;Index to this series of articles&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7274043" width="1" height="1"&gt;</content><author><name>plblum</name><uri>http://weblogs.asp.net/members/plblum.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/peterblum/archive/tags/ASP.NET/default.aspx" /><category term="Dynamic Data" scheme="http://weblogs.asp.net/peterblum/archive/tags/Dynamic+Data/default.aspx" /><category term="ASP.NET 4" scheme="http://weblogs.asp.net/peterblum/archive/tags/ASP.NET+4/default.aspx" /><category term="Improving ASP.NET" scheme="http://weblogs.asp.net/peterblum/archive/tags/Improving+ASP.NET/default.aspx" /><category term="Web controls" scheme="http://weblogs.asp.net/peterblum/archive/tags/Web+controls/default.aspx" /><category term="Business logic" scheme="http://weblogs.asp.net/peterblum/archive/tags/Business+logic/default.aspx" /></entry><entry><title>Exploring Dynamic Data: Scaffolding attributes for business logic</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/peterblum/archive/2009/12/23/exploring-dynamic-data-scaffolding-attributes-for-business-logic.aspx" /><id>http://weblogs.asp.net/peterblum/archive/2009/12/23/exploring-dynamic-data-scaffolding-attributes-for-business-logic.aspx</id><published>2009-12-23T22:13:00Z</published><updated>2009-12-23T22:13:00Z</updated><content type="html">&lt;p&gt;&lt;a href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx" mce_href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx"&gt;Index to this series of articles&lt;/a&gt;&lt;/p&gt;  &lt;div style="background-color: rgb(255, 255, 204); margin-left: 50px; margin-right: 50px;"&gt;   &lt;p&gt;Business logic is applied to your Entity classes (objects that describe individual tables where columns are the properties) through metadata. Typically this metadata is defined by applying attributes from the &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations%28VS.100%29.aspx"&gt;System.ComponentModel.DataAnnotations namespace&lt;/a&gt;.&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Scaffolding is a term that describes letting the business logic determine the list of columns and tables displayed in your user interface. You see it in action when using Dynamic Data’s Page Templates. Yet, it is fine to explicitly define the list of columns in your user interface code, especially when you need flexibility in your layout from column to column.&lt;/p&gt;  &lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.scaffoldcolumnattribute%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.scaffoldcolumnattribute(VS.100).aspx"&gt;ScaffoldColumnAttribute&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayattribute%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayattribute(VS.100).aspx"&gt;DisplayAttribute&lt;/a&gt; are both used to identify if a column is included or excluded. ScaffoldColumnAttribute was introduced first and has fewer capabilities. DisplayNameAttribute is new to .net 4, adding the Order and GroupName properties to the scaffolding rules.&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;[ScaffoldColumn(&lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;)]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; Picture { get; set; }&lt;/pre&gt;

  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;or&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;[Display(AutoGenerateField=&lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;)]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; Picture { get; set; }&lt;/pre&gt;

  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;i&gt;You can read about my complaints of the DisplayAttribute’s design in the previous post. See the “Peter’s Soapbox” section.&lt;/i&gt;&lt;/p&gt;

&lt;h4&gt;When no attribute is supplied&lt;/h4&gt;

&lt;p&gt;When neither of these attributes are assigned, the Dynamic Data scaffolding engine determines if the field shows based on the following rules:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Included: A Field Template name is specified in the UIHintAttribute. &lt;/li&gt;

  &lt;li&gt;Excluded: MetaColumn.IsForeignKeyComponent = true (Part of a ForeignKeyColumn) &lt;/li&gt;

  &lt;li&gt;Excluded: MetaColumn.IsGenerated = true (The column’s data is generated by the database) &lt;/li&gt;

  &lt;li&gt;Included: MetaColumn.IsPrimaryKey = true (The column is a primary key) &lt;/li&gt;

  &lt;li&gt;Excluded: MetaColumn.IsCustomProperty = true (The column was created in the EntityTable class, but does not exist in the database) &lt;/li&gt;

  &lt;li&gt;Included: MetaColumnType is one of these: string, char, integer, floating point, bool, DateTime, TimeSpan, or DateTimeOffset. &lt;/li&gt;

  &lt;li&gt;Excluded: Anything not listed above. &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Ordering the scaffolded columns&lt;/h4&gt;

&lt;p&gt;By default, Dynamic Data shows the columns in the same order they appear in the Entity class. If you want to change the order, use the DisplayAttribute. Its &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayattribute.order%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayattribute.order%28VS.100%29.aspx"&gt;Order&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayattribute.groupname%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayattribute.groupname%28VS.100%29.aspx"&gt;GroupName&lt;/a&gt; properties are used by the scaffolding engine to sort the columns.&lt;/p&gt;

&lt;h4&gt;Scaffolding Tables&lt;/h4&gt;

&lt;p&gt;Like columns, Dynamic Data can provide a specific list of tables to show. Use the &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.scaffoldtableattribute%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.scaffoldtableattribute(VS.100).aspx"&gt;ScaffoldTableAttribute&lt;/a&gt; to exclude a table. When initializing Dynamic Data in Application_Start(), use the &lt;b&gt;ScaffoldAllTables&lt;/b&gt; property to include all tables that are not set to [ScaffoldTableAttribute(false)].&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;DefaultModel.RegisterContext(&lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(NorthwindModel.Entities), &lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; ContextConfiguration() { ScaffoldAllTables = &lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt; });&lt;/pre&gt;

  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;This attribute impacts two features of Dynamic Data:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;The “entry point” web form, which is Default.aspx, initially, can show this table. It internally uses the MetaModel.VisibleTables property to get a list of tables. Be aware that this list is ordered by how the Tables were defined by the ModelProvider class to the MetaModel class. If you want to control the ordering yourself, create a list of MetaTables in the desired order instead of using MetaModel.VisibleTables. &lt;/li&gt;

  &lt;li&gt;Url Routing will prevent Urls that contain table names that are not scaffolded. &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Scaffolding for Filters&lt;/h4&gt;

&lt;p&gt;List oriented interfaces often have filters to let the user modify the query used to generate the list. Your business logic can assist your user interface in building filters with these two attributes:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;DisplayAttribute – Use the &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayattribute.autogeneratefilter%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayattribute.autogeneratefilter(VS.100).aspx"&gt;AutoGenerateFilter&lt;/a&gt; property to include or exclude the column from your filter interface. &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.filteruihintattribute%28VS.95%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.filteruihintattribute(VS.95).aspx" target="_blank"&gt;FilterUIHintAttribute&lt;/a&gt; – Specifies an alternative Filter Template file (a violation of the separation of concerns). &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;ASP.NET Dynamic Data uses this with its &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.dynamicdata.queryablefilterrepeater%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.web.dynamicdata.queryablefilterrepeater(VS.100).aspx"&gt;QueryableFilterRepeater&lt;/a&gt; control to generate a user interface based on business logic.&lt;/p&gt;

&lt;h5&gt;When no DisplayAttribute is supplied&lt;/h5&gt;

&lt;p&gt;When the DisplayAttribute is not assigned, the Dynamic Data scaffolding engine determines if the filter shows based on the following rules:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Included: A Filter Template name is specified in the FilterUIHintAttribute. &lt;/li&gt;

  &lt;li&gt;Excluded: The column is not scaffolded (see the earlier scaffolding rules for fields) &lt;/li&gt;

  &lt;li&gt;Excluded: MetaColumn.IsCustomProperty = true (The column was created in the EntityTable class, but does not exist in the database) &lt;/li&gt;

  &lt;li&gt;Included: MetaColumnType is one of these: bool, enumerated type &lt;/li&gt;

  &lt;li&gt;Excluded: Anything not listed above. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx" mce_href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx"&gt;Index to this series of articles&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7274039" width="1" height="1"&gt;</content><author><name>plblum</name><uri>http://weblogs.asp.net/members/plblum.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/peterblum/archive/tags/ASP.NET/default.aspx" /><category term="Dynamic Data" scheme="http://weblogs.asp.net/peterblum/archive/tags/Dynamic+Data/default.aspx" /><category term="Business logic" scheme="http://weblogs.asp.net/peterblum/archive/tags/Business+logic/default.aspx" /></entry><entry><title>Exploring Dynamic Data: Textual attributes for business logic</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/peterblum/archive/2009/12/21/exploring-dynamic-data-textual-attributes-for-business-logic.aspx" /><id>http://weblogs.asp.net/peterblum/archive/2009/12/21/exploring-dynamic-data-textual-attributes-for-business-logic.aspx</id><published>2009-12-21T22:07:00Z</published><updated>2009-12-21T22:07:00Z</updated><content type="html">&lt;p&gt;&lt;a href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx" mce_href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx"&gt;Index to this series of articles&lt;/a&gt;&lt;/p&gt;  &lt;div style="background-color: rgb(255, 255, 204); margin-left: 50px; margin-right: 50px;"&gt;   &lt;p&gt;Business logic is applied to your Entity classes (objects that describe individual tables where columns are the properties) through metadata. Typically this metadata is defined by applying attributes from the &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations%28VS.100%29.aspx"&gt;System.ComponentModel.DataAnnotations namespace&lt;/a&gt;.&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;Each column has a name taken from the database. Yet there are many ways to display text about the column which does not match the column’s name. The &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayattribute%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.displayattribute%28VS.100%29.aspx"&gt;DisplayAttribute&lt;/a&gt; (introduced in ASP.NET 4) provides the following properties that are available to your user interface:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;Name – The column’s name corrected to reflect language and formatting issues. &lt;/li&gt;    &lt;li&gt;ShortName – A shorter version of the Name. &lt;/li&gt;    &lt;li&gt;Description – A description that may appear in a hint, tooltip or help label. &lt;/li&gt;    &lt;li&gt;Prompt – A description that works well as a prompt, such as in a wizard or the label preceding a textbox. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;This attribute supports resource based localization.&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;[Display(Name=&lt;span style="color: rgb(0, 96, 128);"&gt;"Category"&lt;/span&gt;, Prompt=&lt;span style="color: rgb(0, 96, 128);"&gt;"Enter the category name"&lt;/span&gt;)]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; CategoryName { get; set; }&lt;/pre&gt;

  &lt;br&gt;&lt;/div&gt;



&lt;p&gt;If you are still using ASP.NET 3.5, you can define the Name and Description from the &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.displaynameattribute.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.displaynameattribute.aspx" target="_blank"&gt;System.ComponentModel.DisplayNameAttribute&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/system.enterpriseservices.descriptionattribute.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.enterpriseservices.descriptionattribute.aspx" target="_blank"&gt;System.ComponentModel.DescriptionAttribute&lt;/a&gt; classes. The rest are not available.&lt;/p&gt;

&lt;h4&gt;Naming for tables&lt;/h4&gt;

&lt;p&gt;Like a column, each table has a name taken from the database. If you want to display the table name, it may need an alternative version that reflects language and formatting issues.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;[DisplayName(&lt;span style="color: rgb(0, 96, 128);"&gt;"Categories"&lt;/span&gt;)]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; Category &lt;br&gt;{ &lt;br&gt;}&lt;/pre&gt;

  &lt;br&gt;&lt;/div&gt;



&lt;h4&gt;Peter’s Soapbox&lt;/h4&gt;

&lt;p&gt;I have mixed feelings about the DisplayAttribute introduced in .net 4. I feel it mixes too many concepts together and these concepts already had their own attributes.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Text – Already in DisplayNameAttribute and DescriptionAttribute. No support for ShortName and Prompt in the past though. &lt;/li&gt;

  &lt;li&gt;Scaffolding (the “AutogenerateField” property) – Allows business logic to dictate if the column appears. There already exists &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.scaffoldcolumnattribute%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.scaffoldcolumnattribute%28VS.100%29.aspx" target="_blank"&gt;ScaffoldColumnAttribute&lt;/a&gt;, although this new version introduces the Order and GroupName properties to determine the column’s position. 

    &lt;p&gt;I think that the new properties should have been added to the ScaffoldColumnAttribute. I foresee are additional rules for scaffolding which should appear in the framework, such as defining a list of columns that match a specific category. The ScaffoldColumnAttribute makes sense for this kind of growth.&lt;/p&gt;
  &lt;/li&gt;

  &lt;li&gt;Filter scaffolding (the “AutoGenerateFilter” property). Its another aspect to scaffolding that impacts generating a list of filters in the &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.dynamicdata.queryablefilterrepeater%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.web.dynamicdata.queryablefilterrepeater(VS.100).aspx"&gt;QueryableFilterRepeater&lt;/a&gt; control. This probably belongs in the ScaffoldColumnAttribute so it can share the Order and GroupName properties. 

    &lt;p&gt;Again, there are probably other rules for scaffolding to come for filters. One is already defined in a separate attribute, FilterUIHintAttribute, which helps select the user interface used for filtering, such as setting up a range or a checkboxlist.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx" mce_href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx"&gt;Index to this series of articles&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7274041" width="1" height="1"&gt;</content><author><name>plblum</name><uri>http://weblogs.asp.net/members/plblum.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/peterblum/archive/tags/ASP.NET/default.aspx" /><category term="Dynamic Data" scheme="http://weblogs.asp.net/peterblum/archive/tags/Dynamic+Data/default.aspx" /><category term="Improving ASP.NET" scheme="http://weblogs.asp.net/peterblum/archive/tags/Improving+ASP.NET/default.aspx" /><category term="Business logic" scheme="http://weblogs.asp.net/peterblum/archive/tags/Business+logic/default.aspx" /></entry><entry><title>Exploring Dynamic Data: The DataTypeAttribute for Business Logic</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/peterblum/archive/2009/12/16/exploring-dynamic-data-the-datatypeattribute-for-business-logic.aspx" /><id>http://weblogs.asp.net/peterblum/archive/2009/12/16/exploring-dynamic-data-the-datatypeattribute-for-business-logic.aspx</id><published>2009-12-16T22:00:00Z</published><updated>2009-12-16T22:00:00Z</updated><content type="html">&lt;p&gt;&lt;a href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx" mce_href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx"&gt;Index to this series of articles&lt;/a&gt;&lt;/p&gt;
  &lt;div style="background-color: rgb(255, 255, 204); margin-left: 50px; margin-right: 50px;"&gt;   
&lt;p&gt;Business logic is applied to your Entity classes (objects that describe individual tables where columns are the properties) through metadata. Typically this metadata is defined by applying attributes from the &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations%28VS.100%29.aspx"&gt;System.ComponentModel.DataAnnotations namespace&lt;/a&gt;.&lt;/p&gt;
 &lt;/div&gt;  
&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.datatypeattribute%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.datatypeattribute(VS.100).aspx"&gt;DataTypeAttribute&lt;/a&gt; impacts the “data type” of a column. When defined in the database or a programming language, data types are integers, decimals, strings, etc. We use these to hold all kinds of real world types. Examples:&lt;/p&gt;
  
&lt;ul&gt;   
&lt;li&gt;Integers: percentage, enumerated type, age &lt;/li&gt;
    
&lt;li&gt;Decimals: currency, duration, distance, weight &lt;/li&gt;
    
&lt;li&gt;Strings: phone number, postal code, email address, URL &lt;/li&gt;
    
&lt;li&gt;DateTime: Date, time, Month/Year (credit card expiration), Birthday (day and month). &lt;/li&gt;
 &lt;/ul&gt;
  
&lt;p&gt;Each of these real-world data types have differences in their business rules. The user interface should respect these differences by using different data entry controls (like DateTextBox, Calendar, IntegerTextBox, etc) and validators.&lt;/p&gt;
  
&lt;p&gt;Use the DataTypeAttribute to specify the real world type. Its parameter takes either a value from &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.datatype%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.datatype(VS.100).aspx"&gt;System.ComponentModel.DataAnnotations.DataType&lt;/a&gt; or a string. When the DataType enumerated list lacks the desired type, specify it as a string.&lt;/p&gt;
  &lt;div id="codeSnippetWrapper"&gt;   
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;[DataType(DataType.Date)]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; BirthDate { get; set; }&lt;br&gt;[DataType(&lt;span style="color: rgb(0, 96, 128);"&gt;"Longitude"&lt;/span&gt;)]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; Longitude { get; set; }&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h4&gt;Making DataTypeAttribute impact validation&lt;/h4&gt;

&lt;p&gt;Validation is a very important feature of business rules, and DataTypeAttribute is heavily involved. That’s why DataTypeAttribute is subclassed from &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validationattribute%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validationattribute(VS.100).aspx"&gt;System.ComponentModel.DataAnnotations.ValidationAttribute&lt;/a&gt;. Yet DataTypeAttribute’s implementation of the IsValid() method is to return true every time.&lt;/p&gt;

&lt;p&gt;I recommend subclassing DataTypeAttribute for each data type where validation is needed and implementing the IsValid() method. For example:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; DateAttribute : DataTypeAttribute&lt;br&gt;{&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;override&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; IsValid(&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; instance)&lt;br&gt;    {&lt;br&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (instance &lt;span style="color: rgb(0, 0, 255);"&gt;is&lt;/span&gt; DateTime)&lt;br&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;;&lt;br&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (instance &lt;span style="color: rgb(0, 0, 255);"&gt;is&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;)&lt;br&gt;        {&lt;br&gt;            DateTime vTemp;&lt;br&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; DateTime.TryParse((&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;)instance, &lt;span style="color: rgb(0, 0, 255);"&gt;out&lt;/span&gt; vTemp)&lt;br&gt;        }&lt;br&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;false&lt;/span&gt;;&lt;br&gt;    }&lt;br&gt;}&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; EmailAddressAttribute : DataTypeAttribute&lt;br&gt;{&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;override&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; IsValid(&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; instance)&lt;br&gt;    {&lt;br&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (instance &lt;span style="color: rgb(0, 0, 255);"&gt;is&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;)&lt;br&gt;        {&lt;br&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; Regex.IsMatch((&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;) instance,&lt;br&gt;                &lt;span style="color: rgb(0, 96, 128);"&gt;"^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$"&lt;/span&gt;);&lt;br&gt;        }&lt;br&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;false&lt;/span&gt;;&lt;br&gt;    }&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;
&lt;h4&gt;How Dynamic Data uses the DataTypeAttribute&lt;/h4&gt;

&lt;p&gt;ASP.NET Dynamic Data uses the DataTypeAttribute to select a Field Template. Field Templates are User Control files that define the user interface for a specific data type in a specific situation. The situation includes the mode – read-only, edit, or insert – and other ways the user interface may change. Field Templates for edit and insert mode should create Validation web controls based on the business logic.&lt;/p&gt;

&lt;p&gt;Here are some guidelines for creating Field Templates which respect DataTypeAttributes:&lt;/p&gt;

&lt;ul&gt;
  
&lt;li&gt;The file name of the Field Template should be the same as the value passed into the DataTypeAttribute’s parameter, plus “_Edit” or “_Insert” for the desired mode. For example, DataTypeAttribute(DataType.EmailAddress) should have a Field Template named “EmailAddress_Edit.ascx”. &lt;/li&gt;

  
&lt;li&gt;The data entry control should be suitable for the data type. Generally you will use a TextBox for string-types, although its not a requirement. &lt;/li&gt;

  
&lt;li&gt;When using a textbox, always define a Validator web control that will enforce the data type. Typically you will add the CompareValidator, RegularExpressionValidator, or CustomValidator. 
    
&lt;ul type="circle"&gt;
      
&lt;li&gt;The CompareValidator works for non-string types. Set its Operator property to the desired type. If the Operator doesn’t match the type you need, use one of the other two validators. &lt;/li&gt;

      
&lt;li&gt;The RegularExpressionValidator works for string types that have a pattern. Your business logic may specify the RegularExpressionAttribute to deliver a regular expression to this validator, letting Dynamic Data automatically connect the two. As a result, there will be two attributes: DataTypeAttribute and RegularExpressionAttributes. &lt;i&gt;It would be nice to combine these two.&lt;/i&gt; &lt;/li&gt;

      
&lt;li&gt;The CustomValidator handles everything else. &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;The EnumDataTypeAttribute&lt;/h4&gt;

&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.enumdatatypeattribute%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.enumdatatypeattribute(VS.100).aspx"&gt;EnumDataTypeAttribute&lt;/a&gt; is a DataTypeAttribute subclass for one very common case: Enumerated types. It can be assigned to properties whose type is an enumerated type, a string, or integer.&lt;/p&gt;

&lt;p&gt;The EnumDataTypeAttribute maps a list of strings to the value stored in the data. It gets those strings from the actual enumerated type definition. For example:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 99.6%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 156px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;enum&lt;/span&gt; Movement&lt;br&gt;{&lt;br&gt;    Stop,&lt;br&gt;    Slow,&lt;br&gt;    Normal,&lt;br&gt;    Fast,&lt;br&gt;    Excessive&lt;br&gt;}&lt;/pre&gt; &lt;br&gt;&lt;/div&gt;
&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;[EnumDataType(&lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(Movement))]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt; VehicleMovement { get; set; }&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;


&lt;p&gt;Dynamic Data provides the Enum.ascx and Enum_Edit.ascx Field Templates to display the list of strings from this attribute. In edit mode, it gives you a DropDownList.&lt;/p&gt;

&lt;h2&gt;Peter’s soapbox&lt;/h2&gt;

&lt;p&gt;While its easy to setup, I dislike supplying the list of strings from the enumerated type. Values in the type are usually not correct for the language and lack formatting. In my Peter’s Data Entry Suite, I created an EnumeratedAttribute to handle this. While it can be setup using the enumerated type, you can also define strings explicitly, including culture specific strings.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx" mce_href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx"&gt;Index to this series of articles&lt;/a&gt;&lt;/p&gt;
&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7274040" width="1" height="1"&gt;</content><author><name>plblum</name><uri>http://weblogs.asp.net/members/plblum.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/peterblum/archive/tags/ASP.NET/default.aspx" /><category term="Dynamic Data" scheme="http://weblogs.asp.net/peterblum/archive/tags/Dynamic+Data/default.aspx" /><category term="Validation" scheme="http://weblogs.asp.net/peterblum/archive/tags/Validation/default.aspx" /><category term="Business logic" scheme="http://weblogs.asp.net/peterblum/archive/tags/Business+logic/default.aspx" /></entry><entry><title>Exploring Dynamic Data: Validation attributes for business logic</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-validation-attributes-for-business-logic.aspx" /><id>http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-validation-attributes-for-business-logic.aspx</id><published>2009-12-14T22:01:00Z</published><updated>2009-12-14T22:01:00Z</updated><content type="html">&lt;p&gt;&lt;a href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx" mce_href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx"&gt;Index to this series of articles&lt;/a&gt;&lt;/p&gt;  &lt;div style="background-color: rgb(255, 255, 204); margin-left: 50px; margin-right: 50px;"&gt;   &lt;p&gt;Business logic is applied to your Entity classes (objects that describe individual tables where columns are the properties) through metadata. Typically this metadata is defined by applying attributes from the &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations%28VS.100%29.aspx"&gt;System.ComponentModel.DataAnnotations namespace&lt;/a&gt;.&lt;/p&gt; &lt;/div&gt;  &lt;p&gt;&lt;b&gt;Validation attributes&lt;/b&gt; focus on evaluating data to report errors. The base class is &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validationattribute%28VS.95%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validationattribute%28VS.95%29.aspx"&gt;System.ComponentModel.DataAnnotations.ValidationAttribute&lt;/a&gt;. It defines the &lt;a href="http://msdn.microsoft.com/en-us/library/dd730022%28VS.95%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/dd730022%28VS.95%29.aspx"&gt;IsValid()&lt;/a&gt; method, which is always overriden to evalutate the data. It also supplies the ErrorMessage property, where you can describe the error reported. (I have complaints about using the error message here. See &lt;a href="http://weblogs.asp.net/peterblum/archive/2009/11/24/where-does-this-go-separating-ui-elements-from-business-logic-in-dynamic-data-part-2.aspx" mce_href="http://weblogs.asp.net/peterblum/archive/2009/11/24/where-does-this-go-separating-ui-elements-from-business-logic-in-dynamic-data-part-2.aspx"&gt;Where does this go? Applying SoC to dynamic data – Part 2&lt;/a&gt;.)&lt;/p&gt;  &lt;p&gt;The namespace defines the following attributes to validate your data.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.requiredattribute.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.requiredattribute.aspx"&gt;RequiredAttribute&lt;/a&gt; – Marks the field as required. If your database already defines the column as “not nullable”, Dynamic Data knows that the field is required. Yet, since your Entity classes may be used outside of Dynamic Data, always consider assigning this.       &lt;div id="codeSnippetWrapper"&gt;       &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;[Required()]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; Name { get; set; }&lt;/pre&gt;

      &lt;br&gt;&lt;/div&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;p&gt;&lt;i&gt;Concerns&lt;/i&gt;&lt;/p&gt;

    &lt;p&gt;This attribute is limited to testing text returned from the browser and is generally mapped to the &lt;a href="http://msdn.microsoft.com/en-us/library/5hbw267h%28VS.80%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/5hbw267h%28VS.80%29.aspx"&gt;RequiredFieldValidator web control&lt;/a&gt;. &lt;/p&gt;

    &lt;p&gt;It is further limited to considering only the empty string is invalid, whereas you can use the &lt;b&gt;InitialValue&lt;/b&gt; property on RequiredFieldValidator to recognize another case (a watermark in the textbox).&lt;/p&gt;
  &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.regularexpressionattribute.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.regularexpressionattribute.aspx"&gt;RegularExpressionAttribute&lt;/a&gt; – Evaluates text against a regular expression. Dynamic Data maps this attribute to the &lt;a href="http://msdn.microsoft.com/en-us/library/eahwtc9e.aspx" mce_href="http://msdn.microsoft.com/en-us/library/eahwtc9e.aspx"&gt;RegularExpressionValidator web control&lt;/a&gt;. 

    &lt;div id="codeSnippetWrapper"&gt;
      &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;[RegularExpression(&lt;span style="color: rgb(0, 96, 128);"&gt;"^\d{5}$"&lt;/span&gt;)]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; ZipCode { get; set; }&lt;/pre&gt;

      &lt;br&gt;&lt;/div&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;p&gt;&lt;i&gt;Concerns&lt;/i&gt;&lt;/p&gt;

    &lt;p&gt;Like with the RegularExpressionValidator, this attribute has no way to set the “ignore case” or “multiline” options, which are useful in developing regular expressions.&lt;/p&gt;

    &lt;p&gt;When this expression is used with server side validation, it will use the .net framework’s regular expression engine. When it is used within the browser, it uses javascript’s regular expression engine. Javascript has a simpler syntax. Take care to define your expressions with the Javascript syntax when using Dynamic Data. See &lt;a href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/RegExp" mce_href="https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Global_Objects/RegExp"&gt;Javascript RegExp class guide&lt;/a&gt;.&lt;/p&gt;
  &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.stringlengthattribute.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.stringlengthattribute.aspx"&gt;StringLengthAttribute&lt;/a&gt; – Evaluates the length of text to confirm it has not exceeded a maximum value. If your database already defines the length on a textual column, Dynamic Data has access to that value. Yet, since your Entity classes may be used outside of Dynamic Data, always consider assigning this. 

    &lt;div id="codeSnippetWrapper"&gt;
      &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;[StringLength(10)]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; SocialSecurityNumber { get; set; }&lt;/pre&gt;

      &lt;br&gt;&lt;/div&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;

    &lt;p&gt;&lt;i&gt;Concerns&lt;/i&gt;&lt;/p&gt;

    &lt;p&gt;None of the Field Templates actually include a validator web control for this attribute. Those that have single-line textboxes (like Text_Edit.ascx) set their TextBox control’s MaxLength property. If you are using a multiline textbox, you will need to introduce a validator. I recommend using the RegularExpressionValidator with its expression programmatically set in the Field Template’s Page_Load method to a pattern like this:&lt;/p&gt;

    &lt;div id="codeSnippetWrapper"&gt;
      &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;^[\s\S]{0,#}$&lt;/pre&gt;

      &lt;br&gt;&lt;/div&gt;

    &lt;p&gt;where # is replaced by the value from the Field Template’s Column.MaxLength property. Do NOT attach your validator to the FieldTemplateUserControl’s class by using the SetupValidator() method as that try to associate it with the RegularExpressionAttribute. It will either have its expression updated or be disabled.&lt;/p&gt;

    &lt;p&gt;Instead, I recommend creating a method in the Field Template that sets it based on the StringLengthAttribute and if not found, sets the Validator’s Enabled property to false.&lt;/p&gt;
  &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.rangeattribute.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.rangeattribute.aspx"&gt;RangeAttribute&lt;/a&gt; – Confirms that the value is between a low and high value of a range. Dynamic Data maps this attribute to the &lt;a href="http://msdn.microsoft.com/en-us/library/f70d09xt.aspx" mce_href="http://msdn.microsoft.com/en-us/library/f70d09xt.aspx"&gt;RangeValidator web control&lt;/a&gt;. 

    &lt;p&gt;If you only want to compare greater than or equal to a value, just set the low (the Minimum property). Similarly set Maximum to compare less than or equal to the high value. &lt;/p&gt;

    &lt;div id="codeSnippetWrapper"&gt;
      &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;[Range(0, 100)]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; Percentage{ get; set; }&lt;/pre&gt;
    &lt;/div&gt;

    &lt;p&gt;&amp;nbsp;&lt;/p&gt;
  &lt;/li&gt;

  &lt;li&gt;&lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.customvalidationattribute%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.customvalidationattribute(VS.100).aspx"&gt;CustomValidationAttribute&lt;/a&gt; – (requires ASP.NET 4). Lets you add a method to your Entity class which will be invoked to validate the column in some way. It can also evaluate multiple columns of an entity. The CustomValidationAttribute only validates on the server side. Dynamic Data uses its &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.dynamicdata.dynamicvalidator%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.web.dynamicdata.dynamicvalidator(VS.100).aspx"&gt;DynamicValidator&lt;/a&gt; web control to report errors. 

    &lt;p&gt;See my earlier posting, “&lt;a href="http://weblogs.asp.net/peterblum/archive/2009/12/07/the-customvalidationattribute.aspx" mce_href="http://weblogs.asp.net/peterblum/archive/2009/12/07/the-customvalidationattribute.aspx"&gt;The CustomValidationAttribute&lt;/a&gt;”. &lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;While Dynamic Data installs validator web controls into the user interface, your Entity class should never assume that validation was handled elsewhere. It should always run a final validation against the validation rules that you have created. Use the &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validator%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validator%28VS.100%29.aspx"&gt;System.ComponentModel.DataAnnotations.Validator&lt;/a&gt; class to run that validation. Typically you will call its TryValidateObject() method. It throws an exception for the first error &lt;/p&gt;

&lt;p&gt;In this example, the Products table has a method called OnValidate() which invokes it. (OnValidate() is defined in Linq to SQL Entities automatically, but the call to TryValidateObject is not.)&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; Product&lt;br&gt;{&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; OnValidate(System.Data.Linq.ChangeAction pAction)&lt;br&gt;    {&lt;br&gt;        List&amp;lt;ValidationResult&amp;gt; vErrors = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; List&amp;lt;ValidationResult&amp;gt;();&lt;br&gt;        Validator.TryValidateObject(&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;,&lt;br&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; ValidatorContext(&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;), vErrors);&lt;br&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (vErrors.Count &amp;gt; 0)&lt;br&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; Exception(vErrors[0].ErrorMessage)&lt;br&gt;    }&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;/pre&gt;

  &lt;br&gt;&lt;/div&gt;

&lt;h4&gt;Peter’s Soapbox&lt;/h4&gt;

&lt;p&gt;As many of you know, I have been developing an &lt;a href="http://www.peterblum.com/DES/ProfessionalValidation.aspx" mce_href="http://www.peterblum.com/DES/ProfessionalValidation.aspx"&gt;enhanced validation framework&lt;/a&gt; for ASP.NET for years. I’ve found and fixed &lt;a href="http://www.peterblum.com/DES/CompareFrameworks.aspx" mce_href="http://www.peterblum.com/DES/CompareFrameworks.aspx"&gt;numerous limitations&lt;/a&gt;. Not surprisingly, I find that many of my concerns remain unresolved within the Validation Attributes. I have worked to fix all of the complaints listed in this posting in my &lt;a href="http://www.peterblum.com/DES/Home.aspx" mce_href="http://www.peterblum.com/DES/Home.aspx"&gt;Peter’s Data Entry Suite&lt;/a&gt;. You’ll learn more here.&lt;/p&gt;

&lt;h5&gt;Field Templates cannot setup “compare two field” validators&lt;/h5&gt;

&lt;p&gt;One of the most common validation rules is not available as a ValidationAttribute: comparing two fields. For example, BirthDate &amp;lt; HireDate. This expression is easily represented with the CompareValidator in the web form level:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;asp:CompareValidator&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="CompareBirthToHire"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;runat&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="server"&lt;/span&gt; &lt;br&gt;    &lt;span style="color: rgb(255, 0, 0);"&gt;ControlToValidate&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="BirthDateTextBox"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;ControlToCompare&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="HireDate"&lt;/span&gt; &lt;br&gt;    &lt;span style="color: rgb(255, 0, 0);"&gt;Operator&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="LessThan"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;Type&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="Date"&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;Field Templates are supposed to automatically setup Validator web controls like this based on the ValidationAttributes. I’d like to see something like:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;[CompareColumn(OtherColumn=&lt;span style="color: rgb(0, 96, 128);"&gt;"HireDate"&lt;/span&gt;, Operator=&lt;span style="color: rgb(0, 96, 128);"&gt;"LessThan"&lt;/span&gt;)]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; DateTime BirthDate { get; set; }&lt;/pre&gt;

  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Without this, you can still use the CustomValidatorAttribute on the class definition, but it is strictly server side. Field Templates do not manage a validator web control associated with it.&lt;/p&gt;

&lt;p&gt;There are a few issues to fixing this problem, including:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Property-level validation only passes in the value of the property itself, not the overall object, to the IsValid() property. Therefore IsValid cannot see the second property’s value. Yet this is fixable because IsValid actually can be passed a second value, the entire instance, in the ValidationContext property. This issue requires a change to the DynamicValidator class. More importantly, if the goal is to convert the CompareColumnAttribute into a CompareValidator web control, we really don’t care about the IsValid method. &lt;/li&gt;

  &lt;li&gt;The two columns are converted into HTML using separate Field Templates. Each is a User Control, which means it uses a separate Naming Container. As a rule, properties on web controls take an ID to controls in the same naming container. So the CompareValidator cannot locate the two textboxes. &lt;i&gt;My own Validator classes allow attaching to the textbox object as an alternative. You can learn more about my philosophy here: &lt;a href="http://weblogs.asp.net/peterblum/archive/2009/11/12/improving-asp-net-finding-controls.aspx" mce_href="http://weblogs.asp.net/peterblum/archive/2009/11/12/improving-asp-net-finding-controls.aspx"&gt;Improving ASP.NET: Finding Controls&lt;/a&gt;.&lt;/i&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;h5&gt;There are many more common validation rules&lt;/h5&gt;

&lt;p&gt;My validation suite includes around 25 Validator web controls. There are so many reusable ways to validate. In my Dynamic Data solution, I’ve created numerous ValidationAttributes.&lt;/p&gt;

&lt;h5&gt;Field Templates may not be coded to handle every ValidationAttribute&lt;/h5&gt;

&lt;p&gt;The Field Template must create a Validator web control for each ValidationAttribute declared on the column. Its easy to introduce a new ValidationAttribute on your business logic without it impacting the Field Template for which it was intended. For example, the default field template for strings, Text_Edit.ascx, lacks a validator for the StringLengthAttribute. Your Entity class should still catch errors prior to saving by using the System.ComponentModel.DataAnnotations.Validator class. But the Validator class is strictly server side.&lt;/p&gt;

&lt;p&gt;In my solutions, I chose to abandon defining Validator web controls in the Field Template. Instead, the user drops in a new control called ColumnValidationManager. This control evaluates the list of ValidationAttributes on the column and creates all validators it needs. To work, the ValidationAttribute class must help out. My extensions to the ValidationAttribute class include methods to return an instance of the web control that will be used. If you do the same, be sure to also add the DynamicValidator in your validator generator code.&lt;/p&gt;

&lt;p&gt;Here’s my version of Text_Edit.ascx Field Template:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 148.48%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 250px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="background-color: rgb(255, 255, 0);"&gt;&amp;lt;%@ Control Language="C#" AutoEventWireup="true" Inherits="PeterBlum.DES.DynamicData.TextEditFTUC" %&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="background-color: rgb(255, 255, 0);"&gt;&amp;lt;%@ Register assembly="PeterBlum.DES.DynamicData" namespace="PeterBlum.DES.DynamicData" tagprefix="desDD" %&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;script&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;runat&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="server"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: white; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);" id="lnum1"&gt;   1:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);" id="lnum2"&gt;   2:&lt;/span&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;protected&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Page_Init(&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: white; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);" id="lnum3"&gt;   3:&lt;/span&gt;    {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);" id="lnum4"&gt;   4:&lt;/span&gt;       SetUpEditableDataControl(TextBox1);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: white; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);" id="lnum5"&gt;   5:&lt;/span&gt;       SetUpColumnValidatorManager(ColumnValidatorManager1);&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);" id="lnum6"&gt;   6:&lt;/span&gt;    }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;script&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;des:FilteredTextBox&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;ID&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="TextBox1"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;runat&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="server"&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;des:FilteredTextBox&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;desDD:ColumnValidatorManager&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;ID&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="ColumnValidatorManager1"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;runat&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="server"&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx" mce_href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx"&gt;Index to this series of articles&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7274042" width="1" height="1"&gt;</content><author><name>plblum</name><uri>http://weblogs.asp.net/members/plblum.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/peterblum/archive/tags/ASP.NET/default.aspx" /><category term="Dynamic Data" scheme="http://weblogs.asp.net/peterblum/archive/tags/Dynamic+Data/default.aspx" /><category term="Improving ASP.NET" scheme="http://weblogs.asp.net/peterblum/archive/tags/Improving+ASP.NET/default.aspx" /><category term="Validation" scheme="http://weblogs.asp.net/peterblum/archive/tags/Validation/default.aspx" /><category term="Business logic" scheme="http://weblogs.asp.net/peterblum/archive/tags/Business+logic/default.aspx" /></entry><entry><title>Exploring Dynamic Data: Article Index</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx" /><id>http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-article-index.aspx</id><published>2009-12-14T21:31:00Z</published><updated>2009-12-14T21:31:00Z</updated><content type="html">&lt;p&gt;This is the index to a series of articles, to be published periodically, about the elements of &lt;a href="http://www.asp.net/dynamicdata" mce_href="http://www.asp.net/dynamicdata"&gt;ASP.NET Dynamic Data&lt;/a&gt;. It focuses on specific technologies, especially the web controls you use to build a Dynamic Data-based web form. As the author of &lt;a href="http://www.peterblum.com/des/home.aspx" mce_href="http://www.peterblum.com/des/home.aspx"&gt;Peter’s Data Entry Suite&lt;/a&gt;, I have identified limitations and gaps in Dynamic Data which I will also discuss. My &lt;a href="http://www.peterblum.com/des/dynamicdata.aspx" mce_href="http://www.peterblum.com/des/dynamicdata.aspx"&gt;commercial solution&lt;/a&gt; resolves many of those limitations and gaps.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;a href="http://weblogs.asp.net/peterblum/archive/2009/11/03/datasources-dynamic-data-and-soc.aspx" target="_blank" mce_href="http://weblogs.asp.net/peterblum/archive/2009/11/03/datasources-dynamic-data-and-soc.aspx"&gt;&lt;b&gt;Data Source controls&lt;/b&gt;&lt;/a&gt; to interact with your business logic – Discusses which DataSource web controls are best for good separation of concerns between UI and business logic. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;&lt;a href="http://weblogs.asp.net/peterblum/archive/2009/12/14/exploring-dynamic-data-validation-attributes-for-business-logic.aspx" target="_blank"&gt;Validation attributes&lt;/a&gt;&lt;/b&gt; for business logic. A look at the Validation attributes in System.ComponentModel.DataAnnotations. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://weblogs.asp.net/peterblum/archive/2009/12/16/exploring-dynamic-data-the-datatypeattribute-for-business-logic.aspx" mce_href="http://weblogs.asp.net/peterblum/archive/2009/12/16/exploring-dynamic-data-the-datatypeattribute-for-business-logic.aspx"&gt;&lt;b&gt;DataTypeAttribute&lt;/b&gt;&lt;/a&gt; for business logic.&lt;br&gt;&lt;/li&gt;    &lt;li&gt;&lt;a href="http://weblogs.asp.net/peterblum/archive/2009/12/21/exploring-dynamic-data-textual-attributes-for-business-logic.aspx" mce_href="http://weblogs.asp.net/peterblum/archive/2009/12/21/exploring-dynamic-data-textual-attributes-for-business-logic.aspx"&gt;&lt;b&gt;Textual attributes&lt;/b&gt;&lt;/a&gt; for business logic. The many ways to associate text with column and table elements. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://weblogs.asp.net/peterblum/archive/2009/12/23/exploring-dynamic-data-scaffolding-attributes-for-business-logic.aspx" mce_href="http://weblogs.asp.net/peterblum/archive/2009/12/23/exploring-dynamic-data-scaffolding-attributes-for-business-logic.aspx"&gt;&lt;b&gt;Scaffolding attributes&lt;/b&gt;&lt;/a&gt; for business logic. What is scaffolding and how to manage it. &lt;/li&gt;    &lt;li&gt;&lt;a href="http://weblogs.asp.net/peterblum/archive/2009/12/29/exploring-dynamic-data-other-attributes-for-business-logic.aspx" target="_blank" mce_href="http://weblogs.asp.net/peterblum/archive/2009/12/29/exploring-dynamic-data-other-attributes-for-business-logic.aspx"&gt;&lt;b&gt;Other attributes&lt;/b&gt;&lt;/a&gt; for business logic. Includes my thoughts on what business logic attributes are missing. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Field Templates&lt;/b&gt; – Pending. The user interfaces for each data type. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;DynamicControl and DynamicField&lt;/b&gt; – Pending. The mainstay web control for a user interface of a column in your business logic. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;DynamicValidator control&lt;/b&gt; – Pending. Displays errors generated by your business logic. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Entity Templates&lt;/b&gt; – Pending. A user interface with webcontrols (including DynamicControls) and HTML to describe typical situation, such as a two column row in a detail record, an email entry, and a street address entry. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;DataBound controls&lt;/b&gt; – Pending. ListView, FormView, GridView, and DetailsView are DataBound controls. Dynamic Data requires one as a container for any DynamicControl or DynamicField. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;DynamicDataManager control&lt;/b&gt; – Pending. Connects Dynamic Data technology to the DataBound control. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;DynamicFilter, FilterRepeater, and DynamicFilterRepeater&lt;/b&gt; – Pending. For building filtering user interfaces. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;DataPager control&lt;/b&gt; – Pending. More than just for Dynamic Data, but central to managing list-based DataBound controls. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;QueryExtender&lt;/b&gt; – Pending. Connects DynamicFilterRepeater with the DataSource control. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Page Templates&lt;/b&gt; – Pending. Provides nearly instant applications completely driven by scaffolding and other business logic attributes. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;DynamicHyperlink control&lt;/b&gt; – Pending. Delivers a hyperlink that defines its URL based on URL routing rules. &lt;/li&gt;    &lt;li&gt;&lt;b&gt;What’s missing&lt;/b&gt; – Pending. Other elements that I’ve implemented to make Dynamic Data more robust. &lt;/li&gt; &lt;/ul&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7274013" width="1" height="1"&gt;</content><author><name>plblum</name><uri>http://weblogs.asp.net/members/plblum.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/peterblum/archive/tags/ASP.NET/default.aspx" /><category term="Dynamic Data" scheme="http://weblogs.asp.net/peterblum/archive/tags/Dynamic+Data/default.aspx" /></entry><entry><title>Reflection on a method with an out parameter</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/peterblum/archive/2009/12/10/reflection-on-a-method-with-an-out-parameter.aspx" /><id>http://weblogs.asp.net/peterblum/archive/2009/12/10/reflection-on-a-method-with-an-out-parameter.aspx</id><published>2009-12-10T19:47:00Z</published><updated>2009-12-10T19:47:00Z</updated><content type="html">&lt;p&gt;As I code my &lt;a href="http://www.peterblum.com/des/dynamicdata.aspx" target="_blank" mce_href="http://www.peterblum.com/des/dynamicdata.aspx"&gt;commercial Dynamic Data libraries&lt;/a&gt; for ASP.NET 4 support, I’ve elected to deliver one assembly compiled under .net 3.5 SP 1 that also supports new features of ASP.NET 4. 3.5SP1 is the initial release of Dynamic Data. To interact with the new properties and methods in ASP.NET 4, I am using &lt;a href="http://msdn.microsoft.com/en-us/library/f7ykdhsy.aspx" mce_href="http://msdn.microsoft.com/en-us/library/f7ykdhsy.aspx" target="_blank"&gt;.net Reflection&lt;/a&gt;.&lt;/p&gt;
  
&lt;p&gt;I have long used .net reflection, so I didn’t think there were many more things to learn. Today I encountered a new case, a method that has an &lt;i&gt;out &lt;/i&gt;parameter.&lt;/p&gt;
  
&lt;p&gt;Here’s the method I wanted to call. It's on the class System.Web.DynamicData.DynamicDataExtensions:&lt;/p&gt;
  &lt;div&gt;   
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 118.95%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 26px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; TryGetMetaTable(&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt; INamingContainer control, &lt;span style="color: rgb(0, 0, 255);"&gt;out&lt;/span&gt; MetaTable table);&lt;/pre&gt;
&lt;/div&gt;
&lt;div&gt;To call a function using .reflection, you take these actions:&lt;/div&gt;

&lt;ol&gt;
  
&lt;li&gt;Call a GetMethod(“methodname”) method on the specific type.&lt;/li&gt;

  
&lt;li&gt;Call the Invoke method on the MethodInfo object that was returned by GetMethod.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If this function did not have an &lt;i&gt;out &lt;/i&gt;parameter, the code would look like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 170.45%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 176px; color: black; font-size: 8pt;" id="codeSnippet"&gt;Type[] vTypes = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; Type[] { &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(INamingContainer), &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(MetaTable) };&lt;br&gt;MethodInfo vTGMTMI = &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(DynamicDataExtensions).GetMethod(&lt;span style="color: rgb(0, 96, 128);"&gt;"TryGetMetaTable"&lt;/span&gt;, BindingFlags.Public | BindingFlags.Static,  &lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;,  vTypes, &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;);&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (vTGMTMI == &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;)&lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; NotImplementedException(&lt;span style="color: rgb(0, 96, 128);"&gt;"Must use ASP.NET 4.0 or higher."&lt;/span&gt;);&lt;br&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;[] vParms = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;[] { GridView, &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt; };&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; vResult = (&lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt;) vTGMTMI.Invoke(&lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;, BindingFlags.InvokeMethod, &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;, vParms, &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;);&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (vResult)&lt;br&gt;  &lt;span style="color: rgb(0, 128, 0);"&gt;// metatable returned is in vParms[1]&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;
&lt;div&gt;The GetMethod() method gets more complex with that &lt;i&gt;out&lt;/i&gt; parameter. You must pass the output parameter TYPE as a reference to the intended type. &lt;/div&gt;&lt;div&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Approach 1 - Using Type.MakeByRefType&lt;/b&gt;&lt;br&gt;&lt;/div&gt;&lt;div&gt;As pointed out in the comments, the Type class has the tools needed.&amp;nbsp; Use the method &lt;a href="http://msdn.microsoft.com/en-us/library/system.type.makebyreftype.aspx" target="_blank" mce_href="http://msdn.microsoft.com/en-us/library/system.type.makebyreftype.aspx"&gt;MakeByRefType()&lt;/a&gt; like this:&lt;/div&gt;&lt;div&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 170.45%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 25px; color: black; font-size: 8pt;" id="codeSnippet"&gt;Type[] vTypes = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; Type[] { &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(INamingContainer), &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(MetaTable).MakeByRefType() };&lt;/pre&gt;&lt;/div&gt;&lt;div&gt;&amp;nbsp;&lt;/div&gt;&lt;div&gt;&lt;b&gt;Approach 2 - Using GetType("string")&lt;/b&gt; &lt;br&gt;&lt;/div&gt;&lt;div&gt;Before learning of the MakeByRefType() method, I used this technique. I wanted to keep it in the post because I educates on how to use GetType("string") for an &lt;i&gt;out&lt;/i&gt; parameter. &lt;br&gt;&lt;/div&gt;&lt;div&gt;&lt;br&gt;&lt;/div&gt;
&lt;div&gt;Pass the fully qualified type name into the &lt;a href="http://msdn.microsoft.com/en-us/library/w3f99sx1.aspx" mce_href="http://msdn.microsoft.com/en-us/library/w3f99sx1.aspx" target="_blank"&gt;Type.GetType(“string of the type”)&lt;/a&gt; method. The type within the string must be:&lt;/div&gt;

&lt;ul&gt;
  
&lt;li&gt;full name&lt;/li&gt;

  
&lt;li&gt;end with “&amp;amp;” to indicate its a pointer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here is the MetaTable class as a full qualified name, including type, &amp;amp;, and assembly name:&lt;/p&gt;
&lt;p&gt;Type.GetType("System.Web.DynamicData.MetaTable&amp;amp;, System.Web.DynamicData, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35")&lt;br&gt;&lt;/p&gt;
&lt;p&gt;Here’s the corrected code, allowing the MetaTable's type supply both full names.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 141.39%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 55px; color: black; font-size: 8pt;" id="codeSnippet"&gt;Type vMetaTableP = Type.GetType(&lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(MetaTable).FullName + &lt;span style="color: rgb(0, 96, 128);"&gt;"&amp;amp;,"&lt;/span&gt; + &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(MetaTable).Assembly.FullName);&lt;br&gt;Type[] vTypes = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; Type[] { &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(INamingContainer), vMetaTableP };&lt;br&gt;&lt;br&gt;&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;The big trick is to avoid using typeof(MetaTable).AssemblyQualifiedName, because it omits the “&amp;amp;”. &lt;/p&gt;
&lt;p&gt;&lt;b&gt;Putting it all together&lt;/b&gt; &lt;br&gt;&lt;/p&gt;
This is the complete code using my preferred solution, MakeByRefType().&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 193.74%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 212px; color: black; font-size: 8pt;" id="codeSnippet"&gt;Type[] vTypes = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; Type[] { &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(INamingContainer), &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(MetaTable).MakeByRefType() };&lt;br&gt;&lt;br&gt;MethodInfo vTGMTMI = &lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(DynamicDataExtensions).GetMethod(&lt;span style="color: rgb(0, 96, 128);"&gt;"TryGetMetaTable"&lt;/span&gt;, BindingFlags.Public | BindingFlags.Static,  &lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;,  vTypes, &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;);&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (vTGMTMI == &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;)&lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; NotImplementedException(&lt;span style="color: rgb(0, 96, 128);"&gt;"Must use ASP.NET 4.0 or higher."&lt;/span&gt;);&lt;br&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;[] vParms = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt;[] { GridView, &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt; };&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; vResult = (&lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt;) vTGMTMI.Invoke(&lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;, BindingFlags.InvokeMethod, &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;, vParms, &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;);&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (vResult)&lt;br&gt;  &lt;span style="color: rgb(0, 128, 0);"&gt;// metatable returned is in vParms[1]&lt;/span&gt;&lt;br&gt;&lt;/pre&gt;
  
&lt;p&gt;Note that the GetMethod takes a parameter of type &lt;a href="http://msdn.microsoft.com/en-us/library/system.reflection.parametermodifier.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.reflection.parametermodifier.aspx" target="_blank"&gt;ParameterModifier&lt;/a&gt;. It certainly is involved with &lt;i&gt;out &lt;/i&gt;parameters,
but only when calling COM functions. In this case, the last parameter
for GetMethod is null instead of a ParameterModifier array.&lt;/p&gt;

&lt;/div&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7275688" width="1" height="1"&gt;</content><author><name>plblum</name><uri>http://weblogs.asp.net/members/plblum.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/peterblum/archive/tags/ASP.NET/default.aspx" /><category term="Tricks of the trade" scheme="http://weblogs.asp.net/peterblum/archive/tags/Tricks+of+the+trade/default.aspx" /></entry><entry><title>The CategoryAttribute and Dynamic Data</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/peterblum/archive/2009/12/09/the-categoryattribute-and-dynamic-data.aspx" /><id>http://weblogs.asp.net/peterblum/archive/2009/12/09/the-categoryattribute-and-dynamic-data.aspx</id><published>2009-12-09T16:08:00Z</published><updated>2009-12-09T16:08:00Z</updated><content type="html">&lt;p&gt;The &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.categoryattribute.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.categoryattribute.aspx"&gt;System.ComponentModel.CategoryAttribute&lt;/a&gt; has long been around. It’s generally used for annotating properties on web controls so that design mode’s Property Editor can organize your properties. &lt;/p&gt;
 
&lt;p&gt;I think the CategoryAttribute makes a lot of sense as business logic in your Entity classes. By categorizing properties, your user interface can get creative: &lt;/p&gt;
 
&lt;ul&gt; 
&lt;li&gt;Automatic scaffolding can be generated based on matched categories. This requires writing a custom FieldGenerator class.  &lt;/li&gt;

&lt;li&gt;Field Templates can customize themselves. For example, the Text.ascx Field Template uses a default style sheet class on its &amp;lt;asp:Label&amp;gt; control. When the Category is set to “Title”, the Field Template can change the style sheet class to one that uses a different font. &lt;/li&gt;
&lt;/ul&gt;
 
&lt;p&gt;The CategoryAttribute takes one value, a string. This is supposed to represent a single category. &lt;/p&gt;
 &lt;div id="codeSnippetWrapper"&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;[Category(&lt;span style="color: rgb(0, 96, 128);"&gt;"Title"&lt;/span&gt;)]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; Name { get; set; }&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;
&lt;p&gt;I recommend allowing multiple categories in a pipe character delimited list: &lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;[Category(&lt;span style="color: rgb(0, 96, 128);"&gt;"Title|ProperName"&lt;/span&gt;)]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; Name { get; set; }&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;
&lt;p&gt;This allows much more flexibility. &lt;/p&gt;
&lt;h4&gt;The CategoryManager class&lt;/h4&gt;
&lt;p&gt;Add this class to your application. It checks your requested category names against those in the CategoryAttribute. &lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 215.75%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 1097px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Web.DynamicData;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.ComponentModel;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Text.RegularExpressions;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Linq;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; CategoryManager&lt;br&gt;{&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// Checks the MetaColumn's CategoryAttribute against the filtering rules to determine if there is a match.&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;remarks&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;para&amp;gt;Works as a Extender method on the MetaColumn class.&amp;lt;/para&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;/remarks&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;param name="pColumn"&amp;gt;The MetaColumn that has a list of attributes. They are searched for the CategoryAttribute.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;param name="pCategories"&amp;gt;A pipe delimited list of Categories that must either be present or absent based&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// on pExcludeCategories.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;param name="pExcludeCategories"&amp;gt;When true, none of the category names in pCategories must be in the CategoryAttribute.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;param name="pCategoriesWithNoMatchAreExcluded"&amp;gt; Determines what happens when &lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// pCategories does not contain a matching name to the CategoryAttribute’s value, &lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// including when the MetaColumn lacks a CategoryAttribute.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;returns&amp;gt;When true, keep the column&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; CheckCategories(&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt; MetaColumn pColumn, &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; pCategories, &lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; pExcludeCategories, &lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; pCategoriesWithNoMatchAreExcluded)&lt;br&gt;{&lt;br&gt;    CategoryAttribute vCA = pColumn.Attributes.OfType&amp;lt;CategoryAttribute&amp;gt;().FirstOrDefault();&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; CheckCategories(vCA, pCategories, pExcludeCategories, pCategoriesWithNoMatchAreExcluded);&lt;br&gt;} &lt;span style="color: rgb(0, 128, 0);"&gt;// CheckCategories&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// Checks the CategoryAttribute against the filtering rules to determine if there is a match.&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;param name="pCategoryAttribute"&amp;gt;The CategoryAttribute. Can be null.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;param name="pCategories"&amp;gt;A pipe delimited list of Categories that must either be present or absent based&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// on pExcludeCategories.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;param name="pExcludeCategories"&amp;gt;When true, none of the category names in pCategories must be in the CategoryAttribute.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;param name="pCategoriesWithNoMatchAreExcluded"&amp;gt; Determines what happens when &lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// pCategories does not contain a matching name to the CategoryAttribute’s value, &lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// including when the CategoryAttribute is null.&amp;lt;/param&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;returns&amp;gt;When true, the rules matched the CategoryAttribute.&amp;lt;/returns&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; CheckCategories(CategoryAttribute pCategoryAttribute, &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; pCategories, &lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; pExcludeCategories, &lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; pCategoriesWithNoMatchAreExcluded)&lt;br&gt;{&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (pCategoryAttribute == &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;)&lt;br&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; !pCategoriesWithNoMatchAreExcluded;&lt;br&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;// Both CategoryAttribute.Value and pCategories are pipe delimited lists&lt;/span&gt;&lt;br&gt;    &lt;span style="color: rgb(0, 128, 0);"&gt;// Convert CategoryAttribute.Value to a regex that can find one match in Categories.&lt;/span&gt;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; vPattern = cPipeDelimitedLeft + pCategories + cPipeDelimitedRight;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (Regex.IsMatch(pCategoryAttribute.Category, vPattern, RegexOptions.IgnoreCase))&lt;br&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; !pExcludeCategories;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; pCategoriesWithNoMatchAreExcluded;&lt;br&gt;}&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// When searching a pipe delimited list for a match, this regex should appear&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// first, before the string containing the list.&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;const&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; cPipeDelimitedLeft = &lt;span style="color: rgb(0, 96, 128);"&gt;@"(^|[\|])("&lt;/span&gt;;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// When searching a pipe delimited list for a match, this regex should appear&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// last, after the string containing the list.&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;const&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; cPipeDelimitedRight = &lt;span style="color: rgb(0, 96, 128);"&gt;@")($|[\|])"&lt;/span&gt;;&lt;br&gt;}&lt;br&gt;&lt;br&gt;&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;
&lt;div id="codeSnippetWrapper"&gt;&lt;br&gt;&lt;/div&gt;
&lt;h4&gt;Automatic Scaffolding using Categories&lt;/h4&gt;
&lt;p&gt;Here is a basic implementation of &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.iautofieldgenerator.aspx" target="_blank" mce_href="http://msdn.microsoft.com/en-us/library/system.web.ui.iautofieldgenerator.aspx"&gt;IAutoFieldGenerator&lt;/a&gt; with support for category attribute searches. &lt;/p&gt;

&lt;p&gt;&amp;nbsp; &lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 198.99%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 1670px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Collections;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Web.DynamicData;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Web.UI;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Web.UI.WebControls;&lt;br&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; CategoryFieldsGenerator : c&lt;br&gt;{&lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;private&lt;/span&gt; MetaTable _metaTable;&lt;br&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// The mode used by the caller: ReadOnly, Edit, Insert.&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; DataBoundControlMode Mode { get; set; }&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// Is the interface a list or item?&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; ContainerType ContainerType { get; set; }&lt;br&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// When true, ignore the MetaColumn.IsScaffold property. Just use the CategoryAttribute&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// even if [ScaffoldColumnAttribute(false)].&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// When false, limit to those that are MetaColumn.IsScaffold = true&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; IgnoreScaffold { get; set; }&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// A pipe delimited list of the categories either to include or exclude in the list of &lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// DynamicFields returned.&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;value&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;para&amp;gt;Use a Pipe delimited list for multiple items; matching is case insensitive.&amp;lt;/para&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;/value&amp;gt;&lt;/span&gt;&lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; Categories { get; set; }&lt;br&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// Determines what happens when the Categories property contains a matching name &lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// to the CategoryAttribute’s value. Normally when the Category name is found &lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// in the CategoryAttribute, that NamedStyle is a match. This property can make &lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// that NamedStyle not match.&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;value&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;para&amp;gt;When true, exclude data fields with any of these category names.&amp;lt;/para&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;para&amp;gt;When false, include data fields with any of these category names.&amp;lt;/para&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;/value&amp;gt;&lt;/span&gt;&lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; ExcludeCategories { get; set; }&lt;br&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// Determines what happens when the Categories property does not contain a matching name to the CategoryAttribute’s value, &lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// including when the data field lacks a CategoryAttribute.&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;value&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;para&amp;gt;When true, the DynamicField is omitted.&amp;lt;/para&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;para&amp;gt;When false, the DynamicField is included.&amp;lt;/para&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;/// &amp;lt;/value&amp;gt;&lt;/span&gt;&lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; CategoriesWithNoMatchAreExcluded { get; set; }&lt;br&gt;&lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; CategoryFieldsGenerator(MetaTable table, DataBoundControlMode mode, ContainerType containerType,&lt;br&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; categories, &lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; excludeCategories, &lt;span style="color: rgb(0, 0, 255);"&gt;bool&lt;/span&gt; categoriesWithNoMatchAreExcluded)&lt;br&gt;   {&lt;br&gt;      _metaTable = table;&lt;br&gt;      Mode = mode;&lt;br&gt;      ContainerType = containerType;&lt;br&gt;      Categories = categories;&lt;br&gt;      ExcludeCategories = excludeCategories;&lt;br&gt;      CategoriesWithNoMatchAreExcluded = categoriesWithNoMatchAreExcluded;&lt;br&gt;   }&lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; CategoryFieldsGenerator(MetaTable table, DataBoundControlMode mode, ContainerType containerType,&lt;br&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; categories) : &lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt; (table, mode, containerType, categories, &lt;span style="color: rgb(0, 0, 255);"&gt;false&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;)&lt;br&gt;   {&lt;br&gt;   }&lt;br&gt;&lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; ICollection GenerateFields(Control control)&lt;br&gt;   {&lt;br&gt;&lt;br&gt;      List&amp;lt;DynamicField&amp;gt; fields = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; List&amp;lt;DynamicField&amp;gt;();&lt;br&gt;      IEnumerable&amp;lt;MetaColumn&amp;gt; columns = IgnoreScaffold ? _metaTable.Columns : _metaTable.GetScaffoldColumns(Mode, ContainerType);&lt;br&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (MetaColumn column &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; columns)&lt;br&gt;      {&lt;br&gt;         &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (CategoryManager.CheckCategories(column, Categories, ExcludeCategories, CategoriesWithNoMatchAreExcluded))&lt;br&gt;            fields.Add(CreateField(column));&lt;br&gt;      }&lt;br&gt;&lt;br&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; fields;&lt;br&gt;   }&lt;br&gt;&lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;protected&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;virtual&lt;/span&gt; DynamicField CreateField(MetaColumn column)&lt;br&gt;   {&lt;br&gt;        DynamicField dynamicField = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; DynamicField();&lt;br&gt;        dynamicField.DataField = column.Name;&lt;br&gt;        dynamicField.HeaderText = ContainerType == ContainerType.List ? column.ShortDisplayName : column.DisplayName;&lt;br&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; dynamicField;&lt;br&gt;   }&lt;br&gt;}&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;
&lt;div id="codeSnippetWrapper"&gt;&lt;br&gt;&lt;/div&gt;

&lt;p&gt;In your web form’s Page_Init() method, create the CategoryFieldGenerator and assign it to the GridView.ColumnsGenerator or DetailsView.RowsGenerator. This example includes all columns that have the category “Small”, so long as they are also scaffoldable. (IgnoreScaffold property is false.) &lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 168.7%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 49px; color: black; font-size: 8pt;" id="codeSnippet"&gt;table = LinqDataSource1.GetTable();&lt;br&gt;GridView1.ColumnsGenerator = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; CategoryFieldGenerator(table, DataBoundControlMode.ReadOnly, ContainerType.List, &lt;span style="color: rgb(0, 96, 128);"&gt;"Small"&lt;/span&gt;);&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;
&lt;pre&gt;&lt;/pre&gt;
&lt;h4&gt;Changing the Style Sheets within Field Templates&lt;/h4&gt;
&lt;p&gt;In Page_Load, update the CssClass property on the desired controls based on the category. This example looks for “Title” and switches to the alternate style sheet. &lt;/p&gt;
&lt;div id="codeSnippetWrapper"&gt;
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 133.54%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 350px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;script&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;runat&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="server"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: white; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);" id="lnum1"&gt;   1:&lt;/span&gt;&amp;nbsp; &lt;/pre&gt;&lt;!--CRLF--&gt;&lt;br&gt;&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);" id="lnum2"&gt;   2:&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;override&lt;/span&gt; Control DataControl { get { &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; FieldValueLabel; }}&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;br&gt;&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: white; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);" id="lnum3"&gt;   3:&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;protected&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; Page_Load(&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;br&gt;&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);" id="lnum4"&gt;   4:&lt;/span&gt; {&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;br&gt;&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: white; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);" id="lnum5"&gt;   5:&lt;/span&gt;     &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (CategoryManager.CheckCategories(&lt;span style="color: rgb(0, 96, 128);"&gt;"Title"&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;false&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;false&lt;/span&gt;))&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;br&gt;&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);" id="lnum6"&gt;   6:&lt;/span&gt;         FieldValueLabel.CssClass = &lt;span style="color: rgb(0, 96, 128);"&gt;"TitleLabel"&lt;/span&gt;;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;br&gt;&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: white; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);" id="lnum7"&gt;   7:&lt;/span&gt;     &lt;span style="color: rgb(0, 0, 255);"&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;br&gt;&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);" id="lnum8"&gt;   8:&lt;/span&gt;         FieldValueLabel.CssClass = &lt;span style="color: rgb(0, 96, 128);"&gt;"StndLabel"&lt;/span&gt;;&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;br&gt;&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: white; width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;"&gt;&lt;span style="color: rgb(96, 96, 96);" id="lnum9"&gt;   9:&lt;/span&gt; }&lt;/pre&gt;&lt;!--CRLF--&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;script&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;asp:Label&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;ID&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="FieldValueLabel"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;runat&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="server"&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;asp:Label&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;br&gt;&lt;/div&gt;
&lt;h4&gt;Peter’s Soapbox&lt;/h4&gt;
&lt;p&gt;I encourage the ASP.NET Dynamic Data team to include support for the CategoryAttribute (or some variation of it) in a future release. I have no problem with MS or anyone else using the code of this posting. I consider it public domain and does not require a license. &lt;/p&gt;
&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7273906" width="1" height="1"&gt;</content><author><name>plblum</name><uri>http://weblogs.asp.net/members/plblum.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/peterblum/archive/tags/ASP.NET/default.aspx" /><category term="Dynamic Data" scheme="http://weblogs.asp.net/peterblum/archive/tags/Dynamic+Data/default.aspx" /><category term="Improving ASP.NET" scheme="http://weblogs.asp.net/peterblum/archive/tags/Improving+ASP.NET/default.aspx" /><category term="Business logic" scheme="http://weblogs.asp.net/peterblum/archive/tags/Business+logic/default.aspx" /></entry><entry><title>The CustomValidationAttribute</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/peterblum/archive/2009/12/07/the-customvalidationattribute.aspx" /><id>http://weblogs.asp.net/peterblum/archive/2009/12/07/the-customvalidationattribute.aspx</id><published>2009-12-07T17:31:00Z</published><updated>2009-12-07T17:31:00Z</updated><content type="html">&lt;p&gt;.net 4 introduces the &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.customvalidationattribute%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.customvalidationattribute%28VS.100%29.aspx"&gt;CustomValidationAttribute&lt;/a&gt;, a member of System.ComponentModel.DataAnnotations that supports validation of your business logic. Until now, validation rules were limited based on the available attributes (required, stringlength, regex, and range) plus those you created by subclassing &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validationattribute%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validationattribute(VS.100).aspx" target="_blank"&gt;System.ComponentModel.DataAnnotations.ValidationAttribute&lt;/a&gt;. CustomValidationAttribute lets you define new validation rules directly on your Entity class (or the class of your choice) without having to subclass from ValidationAttribute.&lt;/p&gt;  &lt;p&gt;Unfortunately at this time, the documentation on this attribute is limited. This posting is an attempt to document it better.&lt;/p&gt;  &lt;p&gt;The CustomValidationAttribute can validate an individual property or the complete object (the Entity instance). This is an example using the Category table from Northwind DB and LINQ to SQL.&lt;/p&gt;  &lt;div id="codeSnippetWrapper"&gt;   &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 161.98%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 820px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Collections.Generic;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Linq;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Web;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.ComponentModel.DataAnnotations;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;using&lt;/span&gt; System.Text.RegularExpressions;&lt;br&gt;&lt;br&gt;[MetadataType(&lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(CategoryMetadata))]&lt;br&gt;[CustomValidation(&lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(Category), &lt;span style="color: rgb(0, 96, 128);"&gt;"FinalCheck"&lt;/span&gt;)]&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;partial&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; Category&lt;br&gt;{&lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; CategoryMetadata&lt;br&gt;   {&lt;br&gt;      [CustomValidation(&lt;span style="color: rgb(0, 0, 255);"&gt;typeof&lt;/span&gt;(Category), &lt;span style="color: rgb(0, 96, 128);"&gt;"TestCategoryName"&lt;/span&gt;)]&lt;br&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; CategoryName { get; set; }&lt;br&gt;   }&lt;br&gt;&lt;br&gt;   &lt;span style="color: rgb(0, 128, 0);"&gt;// method defined by LINQ to SQL on every Entity class.&lt;/span&gt;&lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;partial&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; OnValidate(System.Data.Linq.ChangeAction action)&lt;br&gt;   {&lt;br&gt;      List&amp;lt;ValidationResult&amp;gt; vErrors = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; List&amp;lt;ValidationResult&amp;gt;();&lt;br&gt;&lt;br&gt;      &lt;span style="color: rgb(0, 128, 0);"&gt;// validate class-level attributes&lt;/span&gt;&lt;br&gt;      &lt;span style="color: rgb(0, 128, 0);"&gt;// When the last parameter is true, it also evaluates all ValidationAttributes on this entity's properties&lt;/span&gt;&lt;br&gt;      Validator.TryValidateObject(&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; ValidationContext(&lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;), vErrors, &lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;);&lt;br&gt;&lt;br&gt;      &lt;span style="color: rgb(0, 128, 0);"&gt;// handle errors&lt;/span&gt;&lt;br&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (vErrors.Count &amp;gt; 0)&lt;br&gt;         &lt;span style="color: rgb(0, 0, 255);"&gt;throw&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; ValidationException(vErrors[0], &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;);&lt;br&gt;&lt;br&gt;   }&lt;br&gt;&lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; ValidationResult FinalCheck(Category pCategory, ValidationContext pValidationContext)&lt;br&gt;   {&lt;br&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (pCategory.Description.Length &amp;lt; 10)&lt;br&gt;         &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; ValidationResult(&lt;span style="color: rgb(0, 96, 128);"&gt;"Description must be at least 10 characters."&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&amp;gt; { &lt;span style="color: rgb(0, 96, 128);"&gt;"Description"&lt;/span&gt; });&lt;br&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; ValidationResult.Success;&lt;br&gt;   }&lt;br&gt;&lt;br&gt;   &lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;static&lt;/span&gt; ValidationResult TestCategoryName(&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt; pNewName, ValidationContext pValidationContext)&lt;br&gt;   {&lt;br&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (Regex.IsMatch(pNewName, &lt;span style="color: rgb(0, 96, 128);"&gt;@"^\d"&lt;/span&gt;)) &lt;span style="color: rgb(0, 128, 0);"&gt;// cannot start with a digit&lt;/span&gt;&lt;br&gt;         &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; ValidationResult(&lt;span style="color: rgb(0, 96, 128);"&gt;"Cannot start with a digit"&lt;/span&gt;, &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: rgb(0, 0, 255);"&gt;string&lt;/span&gt;&amp;gt; { &lt;span style="color: rgb(0, 96, 128);"&gt;"CategoryName"&lt;/span&gt; });&lt;br&gt;      &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; ValidationResult.Success;&lt;br&gt;   }&lt;br&gt;}&lt;br&gt;&lt;/pre&gt;

  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;h4&gt;Understanding the CustomValidatorAttribute definition&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;It can be placed on the class or property definition. Both are shown above. &lt;/li&gt;

  &lt;li&gt;The class that contains your validation method must always be declared, even if the method is in the same class this attribute is assigned. &lt;/li&gt;

  &lt;li&gt;You may want to create a separate class for all validation rules of your entity, such as “class CategoryValidation”. &lt;/li&gt;

  &lt;li&gt;The method name property must be a case sensitive match your method name. &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Understanding the method definition&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;The method itself must be static and public. &lt;/li&gt;

  &lt;li&gt;The first parameter is the value to evaluate. 
    &lt;ul type="circle"&gt;
      &lt;li&gt;When the method is associated with the class, it will be passed an instance of the Entity. It can be typed to match the class of the Entity, such as it is with “Category” above. It can also be typed to “object”. &lt;/li&gt;

      &lt;li&gt;When the method is associated with a property, it will be passed the value of the property. It can be typed to match the type of the property, such as it is with “string” above. It can also be typed to “object”. &lt;/li&gt;
    &lt;/ul&gt;
  &lt;/li&gt;

  &lt;li&gt;The second parameter, &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validationcontext%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validationcontext%28VS.100%29.aspx"&gt;ValidationContext&lt;/a&gt;, describes other details about the activity. It’s more important when validating a property since it supplies the instance of the Entity (&lt;b&gt;ObjectInstance&lt;/b&gt; property) and the property name (&lt;b&gt;MemberName&lt;/b&gt; property). It’s also possible that this parameter will be null, but that generally occurs when using .net 3.5 libraries. So test for that. &lt;/li&gt;

  &lt;li&gt;Always return an instance of &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validationresult%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validationresult(VS.100).aspx"&gt;System.ComponentModel.DataAnnotations.ValidationResult&lt;/a&gt;. When there is no error, just return the static property &lt;b&gt;ValidationResult.Success&lt;/b&gt;, as shown above. Otherwise return a description and optionally the property name(s) with errors. &lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;Invoking Validation&lt;/h4&gt;

&lt;p&gt;Your CustomValidation methods are not called automatically (despite what the documentation presently says in the “Remarks” section). ASP.NET Dynamic Data knows to evaluate the property-based ValidationAttributes when there is a DynamicValidator control on the page. But since your Entity class may be reused, do not assume that Dynamic Data has done the job. Create a method on your Entity class to validate both class and property-level CustomValidationAttributes. Use &lt;a href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validator.tryvalidateobject%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.componentmodel.dataannotations.validator.tryvalidateobject%28VS.100%29.aspx"&gt;System.ComponentModel.DataAnnotations.Validator.TryValidateObject()&lt;/a&gt; to do the job, as is shown above. Always pass &lt;font size="1"&gt;true&lt;/font&gt; as the last parameter to insure the properties are validated. (If you pass false or omit the parameter, it will only validate the RequiredAttributes on properties.)&lt;/p&gt;

&lt;p&gt;The OnValidate() method above is part of LINQ to SQL. Each Entity class has a partial method called OnValidate(). You create the other partial method in your code and LINQ to SQL will call it automatically. If you are using Entity Framework or another system, you must create and invoke your own “OnValidate()” method.&lt;/p&gt;

&lt;h4&gt;Communicating Errors to the User Interface&lt;/h4&gt;

&lt;p&gt;Your error messages from the ValidationResult class somehow have to be shown in the user interface. A method like OnValidate() has no direct way to pass up the list of ValidationResults. Instead, it throws a System.ComponentModel.DataAnnotations.ValidationException. (Unfortunately, it does not pass the list of ValidationResults in that exception class. You may want to build another Exception class to deliver them.)&lt;/p&gt;

&lt;p&gt;The user interface should catch the exception and route the messages to its error display. When using ASP.NET with Dynamic Data, make sure you have a ValidationSummary and DynamicValidator control on the page, and Dynamic Data will take care of the rest. The Page Templates are setup this way.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  &lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 107.71%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 129px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;asp:ValidationSummary&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;ID&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="ValidationSummary1"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;runat&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="server"&lt;/span&gt; &lt;br&gt;    &lt;span style="color: rgb(255, 0, 0);"&gt;HeaderText&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="List of validation errors"&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;/&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;asp:DynamicValidator&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;runat&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="server"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;ID&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="DetailsViewValidator"&lt;/span&gt; &lt;br&gt;    &lt;span style="color: rgb(255, 0, 0);"&gt;ControlToValidate&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="FormView1"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;Display&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="None"&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;/&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;asp:FormView&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;runat&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="server"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;ID&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="FormView1"&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;Suppose you are creating a new Category and enter a name starting with a digit. Your validation rules will report an error like this:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/peterblum/clip_image002_089706F2.jpg" mce_href="http://weblogs.asp.net/blogs/peterblum/clip_image002_089706F2.jpg"&gt;&lt;img src="http://weblogs.asp.net/blogs/peterblum/clip_image002_thumb_07BEA108.jpg" style="border: 0px none ; display: inline;" title="clip_image002" alt="clip_image002" mce_src="http://weblogs.asp.net/blogs/peterblum/clip_image002_thumb_07BEA108.jpg" border="0" height="267" width="552"&gt;&lt;/a&gt;&lt;/p&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7273131" width="1" height="1"&gt;</content><author><name>plblum</name><uri>http://weblogs.asp.net/members/plblum.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/peterblum/archive/tags/ASP.NET/default.aspx" /><category term="Dynamic Data" scheme="http://weblogs.asp.net/peterblum/archive/tags/Dynamic+Data/default.aspx" /><category term="ASP.NET 4" scheme="http://weblogs.asp.net/peterblum/archive/tags/ASP.NET+4/default.aspx" /><category term="Validation" scheme="http://weblogs.asp.net/peterblum/archive/tags/Validation/default.aspx" /><category term="Business logic" scheme="http://weblogs.asp.net/peterblum/archive/tags/Business+logic/default.aspx" /></entry><entry><title>Validating CheckBoxLists when using ClientIDMode=Predictable</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/peterblum/archive/2009/12/04/validating-checkboxlists-when-using-clientidmode-predictable.aspx" /><id>http://weblogs.asp.net/peterblum/archive/2009/12/04/validating-checkboxlists-when-using-clientidmode-predictable.aspx</id><published>2009-12-04T20:00:00Z</published><updated>2009-12-04T20:00:00Z</updated><content type="html">&lt;p&gt;A common question on the &lt;a href="http://www.asp.net/" mce_href="http://www.asp.net/"&gt;www.asp.net&lt;/a&gt; forums asks how to validate a CheckBoxList control. There are two cases:&lt;/p&gt;
  
&lt;ul&gt;   
&lt;li&gt;Require at least one checkbox&lt;/li&gt;
    
&lt;li&gt;Require a specific number of checkboxes&lt;/li&gt;
 &lt;/ul&gt;
  
&lt;p&gt;In the past, I’ve answered this question in a way that now breaks when the new &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientidmode%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientidmode(VS.100).aspx"&gt;ClientIDMode&lt;/a&gt; property is set to Predictable. (For more, see “&lt;a href="http://weblogs.asp.net/peterblum/archive/2009/11/30/the-impact-of-clientidmode-predictable.aspx" mce_href="http://weblogs.asp.net/peterblum/archive/2009/11/30/the-impact-of-clientidmode-predictable.aspx" target="_blank"&gt;The impact of ClientIDMode=Predictable&lt;/a&gt;”.)&lt;/p&gt;
  &lt;h3&gt;The old way&lt;/h3&gt;  
&lt;p&gt;Look at the HTML generated by the CheckBoxList control. It has a specific pattern where every &amp;lt;input type="checkbox"&amp;gt; tag has an ID based on the ClientID of the control.    &lt;br&gt;&lt;/p&gt;
  &lt;div id="codeSnippetWrapper"&gt;   
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;span&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="CheckBoxList1"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;input&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;type&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="checkbox"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="CheckBoxList1_0"&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;input&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;type&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="checkbox"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="CheckBoxList1_1"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;input&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;type&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="checkbox"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="CheckBoxList1_2"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;input&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;type&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="checkbox"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="CheckBoxList1_3"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;span&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;&amp;nbsp;&lt;/p&gt;

&lt;p&gt;I recommended using a &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.customvalidator.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.customvalidator.aspx" target="_blank"&gt;CustomValidator&lt;/a&gt;. The server side code is easy.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 122.57%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 195px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;protected&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; RequiredCBL(&lt;span style="color: rgb(0, 0, 255);"&gt;object&lt;/span&gt; source, ServerValidateEventArgs args)&lt;br&gt;{ &lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;int&lt;/span&gt; count = 0; &lt;br&gt;    CustomValidator val = (CustomValidator) source; &lt;br&gt;    CheckBoxList cbl = (CheckBoxList) val.FindControl(val.ControlToValidate); &lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;foreach&lt;/span&gt; (ListItem item &lt;span style="color: rgb(0, 0, 255);"&gt;in&lt;/span&gt; cbl.Items) &lt;br&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (item.Selected) &lt;br&gt;            count++; &lt;br&gt;    args.IsValid = (count &amp;gt; 0);&lt;br&gt;}&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;The client-side code I used to recommend looked like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 135.05%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 18px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;script&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;type&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;='text/javascript'&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;
&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 136.66%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 249px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;function&lt;/span&gt; RequiredCBL(sender, args)&lt;br&gt;{&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; count = 0;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;for&lt;/span&gt; (&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; i = 0; &lt;span style="color: rgb(0, 0, 255);"&gt;true&lt;/span&gt;; i++)&lt;br&gt;    {&lt;br&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; listitem = document.getElementById(sender.controltovalidate + &lt;span style="color: rgb(0, 96, 128);"&gt;"_"&lt;/span&gt; + i.toString());&lt;br&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (!listitem)&lt;br&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;break&lt;/span&gt;; &lt;span style="color: rgb(0, 128, 0);"&gt;//!done&lt;/span&gt;&lt;br&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (listitem.&lt;span style="color: rgb(0, 0, 255);"&gt;checked&lt;/span&gt;)&lt;br&gt;            count++;&lt;br&gt;    }&lt;br&gt;    args.IsValid = count &amp;gt; 0;&lt;br&gt;}&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;
&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 136.54%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 24px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;script&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;ClientIDMode=Predictable can change the id= attributes of the &amp;lt;input type='checkbox'&amp;gt; elements by appending “_row#” when the control is inside ListView and FormView.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;span&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="CheckBoxList1"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;input&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;type&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="checkbox"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="CheckBoxList1_0_0"&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;input&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;type&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="checkbox"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="CheckBoxList1_1_0"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;input&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;type&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="checkbox"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="CheckBoxList1_2_0"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;input&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;type&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="checkbox"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="CheckBoxList1_3_0"&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;span&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;Unfortunately, you cannot use the previous client-side script as this breaks:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 131.76%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 26px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; listitem = document.getElementById(sender.controltovalidate + &lt;span style="color: rgb(0, 96, 128);"&gt;"_"&lt;/span&gt; + i.toString());&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;and you cannot just do this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 132.14%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 26px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; listitem = document.getElementById(sender.controltovalidate + &lt;span style="color: rgb(0, 96, 128);"&gt;"_"&lt;/span&gt; + i.toString() + &lt;span style="color: rgb(0, 96, 128);"&gt;"_0"&lt;/span&gt;);&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;because the additional component depends on the row number.&lt;/p&gt;

&lt;h3&gt;The new way&lt;/h3&gt;

&lt;p&gt;Microsoft’s web validation code has to handle this for RadioButtonLists. It does so by searching the child HTML tree of the CheckBoxList. Let’s use that technique, but my implementation creates an array of DHTML input elements once to be reused.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 135.62%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 19px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;script&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;type&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;='text/javascript'&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;
&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 135.89%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 685px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;function&lt;/span&gt; RequiredCBL(sender, args)&lt;br&gt;{&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; count = 0;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; checkboxes = GetBtnList(document.getElementById(sender.controltovalidate));&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;for&lt;/span&gt; (&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; i = 0; i &amp;lt; checkboxes.length; i++)&lt;br&gt;    {&lt;br&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (checkboxes[i].&lt;span style="color: rgb(0, 0, 255);"&gt;checked&lt;/span&gt;)&lt;br&gt;            count++;&lt;br&gt;    }&lt;br&gt;    args.IsValid = count &amp;gt; 0;&lt;br&gt;}&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// Returns a list of input elements contained within a CheckBoxList or RadioButtonList control's HTML&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// The first call creates that list through a search of the child node tree.&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// The result is an array of input elements in the order they were found.&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;function&lt;/span&gt; GetBtnList(pFld)&lt;br&gt;{&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;function&lt;/span&gt; FindChildren(array, parent)&lt;br&gt;    {&lt;br&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;for&lt;/span&gt; (&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; vI = 0; vI &amp;lt; parent.childNodes.length; vI++)&lt;br&gt;        {&lt;br&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; vC = parent.childNodes[vI];&lt;br&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (vC.tagName == &lt;span style="color: rgb(0, 96, 128);"&gt;"INPUT"&lt;/span&gt;)&lt;br&gt;                array[array.length] = vC;&lt;br&gt;            &lt;span style="color: rgb(0, 0, 255);"&gt;else&lt;/span&gt;&lt;br&gt;                FindChildren(array, vC); &lt;span style="color: rgb(0, 128, 0);"&gt;// RECURSIVE&lt;/span&gt;&lt;br&gt;        } &lt;span style="color: rgb(0, 128, 0);"&gt;// for&lt;/span&gt;&lt;br&gt;    }&lt;br&gt;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; vCB = pFld.childbuttons;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (!vCB)&lt;br&gt;    {&lt;br&gt;        vCB = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; Array();&lt;br&gt;        FindChildren(vCB, pFld);&lt;br&gt;        pFld.childbuttons = vCB;&lt;br&gt;    }&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; vCB;&lt;br&gt;} // GetBtnList&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;
&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 136.16%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 24px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;script&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7263229" width="1" height="1"&gt;</content><author><name>plblum</name><uri>http://weblogs.asp.net/members/plblum.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/peterblum/archive/tags/ASP.NET/default.aspx" /><category term="ASP.NET 4" scheme="http://weblogs.asp.net/peterblum/archive/tags/ASP.NET+4/default.aspx" /><category term="Validation" scheme="http://weblogs.asp.net/peterblum/archive/tags/Validation/default.aspx" /></entry><entry><title>The impact of ClientIDMode=Predictable</title><link rel="alternate" type="text/html" href="http://weblogs.asp.net/peterblum/archive/2009/12/02/the-impact-of-clientidmode-predictable.aspx" /><id>http://weblogs.asp.net/peterblum/archive/2009/12/02/the-impact-of-clientidmode-predictable.aspx</id><published>2009-12-02T16:45:00Z</published><updated>2009-12-02T16:45:00Z</updated><content type="html">&lt;p&gt;ASP.NET 4 introduces a new property on all controls: &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientidmode%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientidmode(VS.100).aspx"&gt;ClientIDMode&lt;/a&gt;. It lets web form developers minimize the size of the id= attribute written into HTML tags. It also helps them dictate the actual form of the ID, avoiding the mangled naming of previous versions when controls are inside of naming containers.&lt;/p&gt;
  
&lt;p&gt;As a commercial web control developer, I’ve studied my products when the user sets ClientIDMode to something other than AutoID (which is that mangled format.) Unfortunately, the Predictable setting can break things. &lt;/p&gt;
  
&lt;p&gt;Predictable is documented as follows:&lt;/p&gt;
  
&lt;p&gt;&lt;i&gt;This algorithm is used for controls that are in data-bound controls. The &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientid%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientid%28VS.100%29.aspx"&gt;ClientID&lt;/a&gt; value is generated by concatenating the &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientid%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.clientid%28VS.100%29.aspx"&gt;ClientID&lt;/a&gt; value of the parent naming container with the &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.id%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.web.ui.control.id%28VS.100%29.aspx"&gt;ID&lt;/a&gt; value of the control. If the control is a data-bound control that generates multiple rows, the value of the data field specified in the &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.idataboundlistcontrol.clientidrowsuffix%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.idataboundlistcontrol.clientidrowsuffix%28VS.100%29.aspx"&gt;ClientIDRowSuffix&lt;/a&gt; property is added at the end. For the &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview%28VS.100%29.aspx"&gt;GridView&lt;/a&gt; control, multiple data fields can be specified. If the &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.idataboundlistcontrol.clientidrowsuffix%28VS.100%29.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.idataboundlistcontrol.clientidrowsuffix%28VS.100%29.aspx"&gt;ClientIDRowSuffix&lt;/a&gt; property is blank, a sequential number is added at the end instead of a data field value. Each segment is separated by an underscore character (_).&lt;/i&gt;&lt;/p&gt;
  
&lt;p&gt;Since we are talking about the ClientID property, we really are focused on how our client-side javascript code interacts with the HTML generated by the web controls. My controls heavily use javascript, and always grabbing HTML elements by anticipating the id= attribute. For example, suppose you have this TextBox inside of a UserControl whose ID is “UserControl1”.&lt;/p&gt;
  &lt;div id="codeSnippetWrapper"&gt;   
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;asp:TextBox&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="TextBox1"&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;runat&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="server"&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;ASP.NET generates this HTML when ClientIDMode=AutoID.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;input&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;type&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;='text'&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="UserControl1_TextBox1"&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;To get this DHTML element, the Javascript should do this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; fld = document.getElementById(&lt;span style="color: rgb(0, 96, 128);"&gt;"UserControl1_TextBox1"&lt;/span&gt;);&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;This script breaks if the Textbox is inside of a ListView or FormView control when ClientIDMode=Predictable. It’s that ClientIDRowSuffix property, mentioned in the docs above, that is causing the problem. It appends a “_row#” pattern to the overall id= output, like this:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100%; font-family: 'Courier New',courier,monospace; direction: ltr; color: black; font-size: 8pt;" id="codeSnippet"&gt;&amp;lt;input type=&lt;span style="color: rgb(0, 96, 128);"&gt;'text'&lt;/span&gt; id=&lt;span style="color: rgb(0, 96, 128);"&gt;"UserControl1_TextBox1_0"&lt;/span&gt; /&amp;gt;&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;&lt;i&gt;Note: MS has told me that FormView won’t be a problem in the RTM of ASP.NET 4, but for Beta 2, it is.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;There is NO problem if you always get the value for the id from the ClientID property itself. For example:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 117.46%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 26px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; fld = document.getElementById(&lt;span style="color: rgb(0, 96, 128);"&gt;'&amp;lt;% = FindControl("TextBox1").ClientID %&amp;gt;'&lt;/span&gt;);&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;My web controls do something a little different. They have child controls and their IDs have a specific pattern. Take my DateTextBox control. It uses an Image control to toggle a popup calendar.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://weblogs.asp.net/blogs/peterblum/clip_image002_7AA8FD44.jpg" mce_href="http://weblogs.asp.net/blogs/peterblum/clip_image002_7AA8FD44.jpg"&gt;&lt;img src="http://weblogs.asp.net/blogs/peterblum/clip_image002_thumb_6140FA0A.jpg" style="border: 0px none ; display: inline;" title="clip_image002" alt="clip_image002" mce_src="http://weblogs.asp.net/blogs/peterblum/clip_image002_thumb_6140FA0A.jpg" border="0" height="28" width="124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;It is generated this way:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 131.64%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 182px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;public&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;class&lt;/span&gt; DateTextBox : System.Web.UI.WebControls.TextBox&lt;br&gt;{&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;protected&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;override&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;void&lt;/span&gt; CreateChildControls()&lt;br&gt;    {&lt;br&gt;        System.Web.UI.WebControls.Image image = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; System.Web.UI.WebControls.Image();&lt;br&gt;        image.ID = &lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;.ID + &lt;span style="color: rgb(0, 96, 128);"&gt;"_Img"&lt;/span&gt;;&lt;br&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;this&lt;/span&gt;.Controls.Add(image);&lt;br&gt;    }&lt;br&gt;}&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;
&lt;h3&gt;Here’s where it breaks&lt;/h3&gt;
&lt;div id="codeSnippetWrapper"&gt;My javascript attaches some event handlers to the &amp;lt;img&amp;gt; HTML tag generated by the Image control by using the ClientID from the TextBox and appending “_Img” like this:&lt;/div&gt;
&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 127.36%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 27px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; img = document.getElementById(&lt;span style="color: rgb(0, 96, 128);"&gt;'&amp;lt;% = FindControl("TextBox1").ClientID %&amp;gt;'&lt;/span&gt; + &lt;span style="color: rgb(0, 96, 128);"&gt;"_Img"&lt;/span&gt;);&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;This no longer works when using Predictable mode if the control is inside a ListView or FormView because the image tag has that suffix:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 100.16%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 29px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: rgb(128, 0, 0);"&gt;img&lt;/span&gt; &lt;span style="color: rgb(255, 0, 0);"&gt;id&lt;/span&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;="FormView1_UserControl1_TextBox1_Img_0"&lt;/span&gt; &lt;span style="color: rgb(0, 0, 255);"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;To solve this, I created the following function that I wanted to share. It handles getting the correct ID, whether or not there is that suffix. It should be used only when a child web control is named in the pattern shown here.&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 145.37%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 574px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// When joining [ClientID] + "_const", ClientIDMode=Predictable causes problems&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// It adds "_#" to the end ([ClientID]_const_0).&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// It will move _# from the end of [ClientID] to the end of the combined id.&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// This function detects the pattern and copies the "_#" from the ClientId to the end of the overall id&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// It returns the new ID.&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// pID – The ClientID of the parent control&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// pExt – The string appended to the ClientID of the parent, such as “_Img”&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// pMode - int. &lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// 0 = Normal. Move the ClientID extension to the end of the overall Id.&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// 1 = use pId + pExt exactly.&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// 2 = the HTML tag was hardcoded with an ID (Literal control written out)&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 128, 0);"&gt;// instead of being generated by a webcontrol's ID. &lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;function&lt;/span&gt; PrepIdExt(pId, pExt, pMode)&lt;br&gt;{&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (pMode == 1)&lt;br&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; pId + pExt;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (!gGBIRE)&lt;br&gt;        gGBIRE = &lt;span style="color: rgb(0, 0, 255);"&gt;new&lt;/span&gt; RegExp(&lt;span style="color: rgb(0, 96, 128);"&gt;"_\\d+$"&lt;/span&gt;); &lt;span style="color: rgb(0, 128, 0);"&gt;// _ followed by 1 or more digits followed by the end of text&lt;/span&gt;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; vM = gGBIRE.exec(pId);&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (vM != &lt;span style="color: rgb(0, 0, 255);"&gt;null&lt;/span&gt;) &lt;span style="color: rgb(0, 128, 0);"&gt;// found it. Revise the ID&lt;/span&gt;&lt;br&gt;    {&lt;br&gt;        pId = pId.substr(0, pId.length - vM[0].length) + pExt;&lt;br&gt;        &lt;span style="color: rgb(0, 0, 255);"&gt;if&lt;/span&gt; (!pMode)&lt;br&gt;        pId = pId + vM[0];&lt;br&gt;    }&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;else&lt;/span&gt;&lt;br&gt;        pId = pId + pExt;&lt;br&gt;    &lt;span style="color: rgb(0, 0, 255);"&gt;return&lt;/span&gt; pId;&lt;br&gt;} &lt;span style="color: rgb(0, 128, 0);"&gt;// PrepIdExt&lt;/span&gt;&lt;br&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; gGBIRE;&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;
&lt;div id="codeSnippetWrapper"&gt;
  &lt;br&gt;&lt;/div&gt;

&lt;p&gt;Here’s how to use it:&lt;/p&gt;

&lt;div id="codeSnippetWrapper"&gt;
  
&lt;pre style="border-style: none; margin: 0em; padding: 0px; overflow: visible; text-align: left; line-height: 12pt; background-color: rgb(244, 244, 244); width: 139.24%; font-family: 'Courier New',courier,monospace; direction: ltr; height: 36px; color: black; font-size: 8pt;" id="codeSnippet"&gt;&lt;span style="color: rgb(0, 0, 255);"&gt;var&lt;/span&gt; img = document.getElementById(PrepIdExt(&lt;span style="color: rgb(0, 96, 128);"&gt;'&amp;lt;% = FindControl("TextBox1").ClientID %&amp;gt;'&lt;/span&gt;, &lt;span style="color: rgb(0, 96, 128);"&gt;"_Img"&lt;/span&gt;, 0));&lt;/pre&gt;
  &lt;br&gt;&lt;/div&gt;
&lt;h5&gt;&lt;/h5&gt;
&lt;h3&gt;Some concluding thoughts&lt;/h3&gt;

&lt;ul&gt;
  
&lt;li&gt;There are other ways to create IDs within the web controls to avoid this. Most common is to implement &lt;a href="http://msdn.microsoft.com/en-us/library/system.web.ui.inamingcontainer.aspx" mce_href="http://msdn.microsoft.com/en-us/library/system.web.ui.inamingcontainer.aspx" target="_blank"&gt;INamingContainer&lt;/a&gt; on your base control and establish child control IDs without adding the parent (image.ID = "_Img" as opposed to image.ID = this.ID + "_Img")&lt;/li&gt;

  
&lt;li&gt;If you always use the ClientID property to specify the exact child control, your code will work. I don’t like that because you have to pass every ID you need from the server side, and the ID strings can be lengthy, impacting the page transmission time. I like to pass a single ClientID of the base control and let the javascript know how to work from there.&lt;/li&gt;

  
&lt;li&gt;&lt;i&gt;Peter’s soapbox:&lt;/i&gt; I do not feel its right for the end-user of my controls to take control over how my child controls are generated. My web control should have complete control over that. Right now, the end-user can set ClientIDMode and impact my scripts. I have no problem with their dictating the value of the ClientID of the main control’s HTML, just the child controls. Microsoft should change the design to allow web controls to ignore ClientIDMode’s impact on their children.&lt;/li&gt;

  
&lt;li&gt;If you cannot modify existing code to support ClientIDMode, you can either document to set AutoID on the containing NamingContainer’s ClientIDMode property or make your web control’s code set ClientIDMode=AutoID on every child control.&lt;/li&gt;
&lt;/ul&gt;
&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=7263010" width="1" height="1"&gt;</content><author><name>plblum</name><uri>http://weblogs.asp.net/members/plblum.aspx</uri></author><category term="ASP.NET" scheme="http://weblogs.asp.net/peterblum/archive/tags/ASP.NET/default.aspx" /><category term="Creating controls" scheme="http://weblogs.asp.net/peterblum/archive/tags/Creating+controls/default.aspx" /><category term="ASP.NET 4" scheme="http://weblogs.asp.net/peterblum/archive/tags/ASP.NET+4/default.aspx" /><category term="Web controls" scheme="http://weblogs.asp.net/peterblum/archive/tags/Web+controls/default.aspx" /></entry></feed>
