<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss'><id>tag:blogger.com,1999:blog-8150162</id><updated>2009-11-27T04:34:38.102-08:00</updated><title type='text'>Christophe's</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default?start-index=26&amp;max-results=25'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>29</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-8150162.post-1145253717174707484</id><published>2007-11-25T06:48:00.001-08:00</published><updated>2007-11-25T06:48:58.676-08:00</updated><title type='text'>Book Review "Code Complete"</title><content type='html'>http://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670/ref=pd_sim_b_img_2&lt;br&gt;&lt;br&gt;I just finished reading this book. It was a very good read. I do not remember myself thinking "this is incorrect" or "this guy is nuts".&lt;br&gt;&lt;br&gt;A&amp;nbsp; lot of very good analysis of what software construction is about. I have been programming for almost 30 years and the experience you acquire is difficult to transfer to younger programmers. Finally, all the ins and outs of good programming are here on these pages. I wish I had known about this book earlier. It would have saved me some time reading about what I just discovered by a lot of practice.&lt;br&gt;&lt;br&gt;This book should be a required read for all college students that get started in the real world. Then, they should read it again after a year and see the light.&lt;br&gt;&lt;br&gt;The only problem with this book is that the author refers to many other books that just sound too interesting for me to not read them  too!&lt;br&gt;&lt;br&gt;#$#@%%, I have to go spend more money on computer books (for a change)&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;p&gt;&amp;#32;          &lt;hr size=1&gt;Never miss a thing.  &lt;a href="http://us.rd.yahoo.com/evt=51438/*http://www.yahoo.com/r/hs"&gt; Make Yahoo your homepage.&lt;/a&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-1145253717174707484?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/1145253717174707484/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=1145253717174707484' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/1145253717174707484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/1145253717174707484'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2007/11/book-review-code-complete.html' title='Book Review &quot;Code Complete&quot;'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-116804975861774520</id><published>2007-01-05T18:15:00.000-08:00</published><updated>2007-01-05T18:15:58.680-08:00</updated><title type='text'>ASP.Net 2.0 Event Validation Exception / The Why and the How</title><content type='html'>There is a new feature in ASP.Net 2.0 called Event Validation. Its value (EnableEventValidation) is true by default. If you upgraded from 1.1 to 2.0, your site may stop working.&lt;br&gt;&lt;br&gt;The purpose of this feature is to protect your site from illegal values from being posted. For instance, let's say your have a drop down list with 3 values "0,1,2".&lt;br&gt;It is possible to construct a post (hacking) to post a value "3" for this drop down. &lt;br&gt;Indeed, the drop down simply generates a &amp;lt;select&amp;gt; element on the browser and is simple to alter.&lt;br&gt;&lt;br&gt;Now, this rogue "3" may not be very serious for this example but all posted values&lt;br&gt;could be subject to change and force your application to do something that was &lt;br&gt;not intended.&lt;br&gt;In ASP.Net the event validation just checks that the value that is posted was actually in the list of values in the drop down. In other words, if a hacker posted "3" the framework would throw an exception since the initial list was  "0,1,2".&lt;br&gt;&lt;br&gt;Most of the time, you do not have to worry about it since you do not intentionaly&lt;br&gt;post bad values. However, once you start manipulating the DOM on the browser, you could for instance dynamically add a "3" to your &amp;lt;select&amp;gt; and the user could click on it. &lt;br&gt;&lt;br&gt;As we move to more code on the client (the AJAX thing), you can see how this could happen. An asynchronous post back for instance could fetch data and you could add more options to your &amp;lt;select&amp;gt;.&lt;br&gt;&lt;br&gt;If you know you may post values that were not in the initial list, you need to&lt;br&gt;call ClientScript.RegisterForEventValidation(). In this case you would do this:&lt;br&gt;ClientScript.RegisterForEventValidation(yourDropDown.UniqueID,"3").&lt;br&gt;&lt;br&gt;Now, I have code that broke from 1.1 to 2.0. The reason was this. We created some javascript that used the __doPostBack() but we typed it manually. In other words, we were not using the GetCallBackReference() API that returns the javascript code to  raise an event on the server. So we violated the framework's intent.&lt;br&gt;&lt;br&gt;If you use Reflector and look at the GetCallBackReference(), you will see that &lt;br&gt;it uses the RegisterForEventValidation() and takes care of its business.&lt;br&gt;&lt;br&gt;The conclusion is that the framework does a lot of work for you. Use it as intended or pull your hair for hours trying to figure out what's going on.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;p&gt;&amp;#32;__________________________________________________&lt;br&gt;Do You Yahoo!?&lt;br&gt;Tired of spam?  Yahoo! Mail has the best spam protection around &lt;br&gt;http://mail.yahoo.com &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-116804975861774520?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/116804975861774520/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=116804975861774520' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/116804975861774520'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/116804975861774520'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2007/01/aspnet-20-event-validation-exception.html' title='ASP.Net 2.0 Event Validation Exception / The Why and the How'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-116589571987630679</id><published>2006-12-11T19:55:00.000-08:00</published><updated>2006-12-11T19:55:19.916-08:00</updated><title type='text'>Extending the shell to get a .Net 3.0 command prompt</title><content type='html'>Take this text below. Save it as a DotNetCmd3_0.reg file and then double click on it. Now, on any folder, you can right click and see the ".NET Cmd 3.0" command prompt. You can then use ildasm for instance or xamlpad. This reg file basically saves you from selecting the following "Start/All Programs/Microsoft Windows SDK/Cmd Shell" with the mouse every time you need 3.0.&lt;br&gt;&lt;br&gt;Windows Registry Editor Version 5.00&lt;br&gt;&lt;br&gt;[HKEY_CLASSES_ROOT\Folder\shell\.NET Cmd 3.0\command]&lt;br&gt;@="C:\\WINDOWS\\system32\\cmd.exe /E:ON /V:ON /T:0E /K \"C:\\Program Files\\Microsoft SDKs\\Windows\\v6.0\\Bin\\SetEnv.Cmd\""&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;p&gt;&amp;#32; &lt;hr size=1&gt;Cheap Talk? &lt;a href="http://us.rd.yahoo.com/mail_us/taglines/postman8/*http://us.rd.yahoo.com/evt=39663/*http://voice.yahoo.com"&gt;Check out&lt;/a&gt; Yahoo! Messenger's low PC-to-Phone call rates.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-116589571987630679?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/116589571987630679/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=116589571987630679' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/116589571987630679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/116589571987630679'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2006/12/extending-shell-to-get-net-30-command.html' title='Extending the shell to get a .Net 3.0 command prompt'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-116016983705791186</id><published>2006-10-06T14:23:00.000-07:00</published><updated>2006-10-06T14:23:57.756-07:00</updated><title type='text'>Solving The Double Post Problem On A Button</title><content type='html'>&lt;div style="font-family:times new roman, new york, times, serif;font-size:12pt"&gt;&lt;div&gt;using System;&lt;br&gt; using System.Data;&lt;br&gt; using System.Configuration;&lt;br&gt; using System.Web;&lt;br&gt; using System.Web.Security;&lt;br&gt; using System.Web.UI;&lt;br&gt; using System.Web.UI.WebControls;&lt;br&gt; using System.Web.UI.WebControls.WebParts;&lt;br&gt; using System.Web.UI.HtmlControls;&lt;br&gt; using System.Text;&lt;br&gt; &lt;br&gt; namespace Developmentor&lt;br&gt; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;summary&amp;gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// C. Fouquet: Oct 2006&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// This button cannot be clicked more than once during a post.&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// This solves the classic double post problem where a user clicks&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// a button more than once quickly and therefore posts twice!&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// The idea is simple. Disable the button IMMEDIATELY after the click and &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// THEN post. For that, we need to set a short timer to post very quickly after the&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// button is disabled and give the illusion that the click is immediate.&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; /// &amp;lt;/summary&amp;gt;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; public class OneClickButton : Button&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; public int DelayInMs&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ViewState["DelayInMs"] == null) return 20;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (int)ViewState["DelayInMs"];&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ViewState["DelayInMs"] = value;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected override void Render(HtmlTextWriter writer)&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string DisableMySelf = "document.getElementById('" + this.ClientID + "').disabled = true;";&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string PostIt = Page.ClientScript.GetPostBackEventReference(this, string.Empty);&lt;br&gt; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string FunctionName = "DelayedClick" + this.ClientID;&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; StringBuilder sb = new StringBuilder();&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append("&amp;lt;script type=text/javascript &amp;gt;"); sb.Append(Environment.NewLine);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append("function "); sb.Append(FunctionName); sb.Append("()"); sb.Append(Environment.NewLine);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append("{"); sb.Append(Environment.NewLine);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append(PostIt); sb.Append(";"); sb.Append(Environment.NewLine);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append("}"); sb.Append(Environment.NewLine);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; sb.Append("&amp;lt;/script&amp;gt;"); sb.Append(Environment.NewLine);&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; this.Attributes.Add("onclick", DisableMySelf + ";" + "setTimeout('" + FunctionName + "()',"+ DelayInMs.ToString() + ");return false");&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; writer.Write(sb.ToString()); // Write the javascript FIRST to it is available on click!&lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; base.Render(writer);&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt; }&lt;br&gt; &lt;br&gt;&lt;/div&gt;&lt;/div&gt;&lt;br&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-116016983705791186?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/116016983705791186/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=116016983705791186' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/116016983705791186'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/116016983705791186'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2006/10/solving-double-post-problem-on-button.html' title='Solving The Double Post Problem On A Button'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-115482265286939275</id><published>2006-08-05T17:04:00.000-07:00</published><updated>2006-08-05T17:04:12.933-07:00</updated><title type='text'>One-Liners Getters And Setters For ASP.Net Control Properties</title><content type='html'>&lt;br&gt;It is a little tiring to repeat the same code when persisting properties in the ViewState.&lt;br&gt;You basically have to do this for each property. Let assume we have a Count and a Text property.&lt;br&gt;&lt;br&gt;int Count&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;get&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if(ViewState["Count"] == null) return 0; // Handle the null case&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return (int) ViewState["Count"]; // Need to cast&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;set&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ViewState["Count"] = value;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;}&lt;br&gt;&lt;br&gt;string Text&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;get&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;if(ViewState["Text"] == null) return string.Empty; // Handle the null case&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return (string) ViewState["Text"];// Need to cast&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;set&lt;br&gt;&amp;nbsp;&amp;nbsp;  &amp;nbsp;{&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;ViewState["Text"] = value;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br&gt;}&lt;br&gt;&lt;br&gt;Each time, you have to handle the case where the slot in ViewState is null and decide on a default value. It gets very boring very quickly. Casting the return value gets tiring too. &lt;br&gt;&lt;br&gt;In my day job (yes, I have one), we have made our own bases classes for UserControls. This allows us to use some goodies we have made over time that is relevant to our application.&lt;br&gt;&lt;br&gt;It would be cool to somehow "Factorize" this .... so here it is. We use generics to do the same logic every time.&lt;br&gt;&lt;br&gt;namespace Developmentor&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public class UserControl : System.Web.UI.UserControl&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected void SetProperty&amp;lt;T&amp;gt;(string Name, T value) &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ViewState[Name] =  value;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected T GetProperty&amp;lt;T&amp;gt;(string Name, T defaultValue)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; if (ViewState[Name] == null)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return defaultValue;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return (T)ViewState[Name];&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;}&lt;br&gt;&lt;br&gt;Now use it in an ascx like this. Just change the Inherits to point to your new and improved base. We have gained a little. At least we can do all this in one line now. There is still some typing but it is a little more 'Generic'  ;-)&lt;br&gt;&lt;br&gt;&lt;br&gt;&amp;lt;%@ Control Language="C#" ClassName="simpleControl" Inherits="Developmentor.UserControl" %&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;script runat="server"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string TheProperty&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; set&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; SetProperty&amp;lt;string&amp;gt;("TheProperty", value);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return GetProperty&amp;lt;string&amp;gt;("TheProperty", "?");&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected override void Render(HtmlTextWriter writer)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;  writer.Write(TheProperty);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;lt;/script&amp;gt;&lt;br&gt;&lt;br&gt;This has been in my mind for a while. If you think that a brain like mine can't come up with this, well, you are right. I saw this in the Atlas framework using Reflector. Somebody at microsoft is thinking. When can we get this in the System.Web.UI.Control class in the framework? .Net 3.0?&lt;br&gt;&lt;br&gt;&lt;p&gt;&amp;#32; 		&lt;hr size=1&gt;Groups are talking. We&amp;acute;re listening. Check out the &lt;a href="http://pa.yahoo.com/*http://us.rd.yahoo.com/evt=41144/*http://groups.yahoo.com/local/newemail.html"&gt;handy changes to Yahoo! Groups.&lt;/a&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-115482265286939275?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/115482265286939275/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=115482265286939275' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/115482265286939275'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/115482265286939275'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2006/08/one-liners-getters-and-setters-for.html' title='One-Liners Getters And Setters For ASP.Net Control Properties'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-115445133338487397</id><published>2006-08-01T09:55:00.000-07:00</published><updated>2006-08-01T09:55:33.440-07:00</updated><title type='text'>Where are ASP.Net 2.0 Property Pages Settings stored?</title><content type='html'>Right here.&lt;br&gt;&lt;br&gt;These are hidden folders so you can just type the whole path to get to the file.&lt;br&gt;&lt;br&gt;C:\Documents and Settings\&lt;span style="font-weight: bold;"&gt;yourusername&lt;/span&gt;\Local Settings\Application Data\Microsoft\WebsiteCache\websites.xml&lt;br&gt;&lt;br&gt;The settings are saves once you close the IDE.&lt;br&gt;&lt;br&gt;I tried deleting the file and the IDE recreates it. It can be good to go back to a clean slate.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;p&gt;&amp;#32; 		&lt;hr size=1&gt;Groups are talking. We&amp;acute;re listening. Check out the &lt;a href="http://pa.yahoo.com/*http://us.rd.yahoo.com/evt=41144/*http://groups.yahoo.com/local/newemail.html"&gt;handy changes to Yahoo! Groups.&lt;/a&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-115445133338487397?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/115445133338487397/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=115445133338487397' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/115445133338487397'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/115445133338487397'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2006/08/where-are-aspnet-20-property-pages.html' title='Where are ASP.Net 2.0 Property Pages Settings stored?'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-115425679713401526</id><published>2006-07-30T03:53:00.000-07:00</published><updated>2006-07-30T03:53:17.190-07:00</updated><title type='text'>Adding A .Net Command Prompt to Explorer context menu</title><content type='html'>In order to get access to ildasm or the csc (C# compiler) you need to run vsvars32.bat. It would be easier to point to a folder in explorer and right click and see a ".Net Cmd 2003" item and just select it. You can then access all the .Net tools for this version of the framework.&lt;br&gt;&lt;br&gt;I have a reg file I use to set this up. You can create a reg file with this content and double click on it or set the registry key by hand. &lt;br&gt;&lt;br&gt;There is a 2003 and 2005 version (both can work at the same time)&lt;br&gt;&lt;br&gt;&lt;br&gt;---- 2003 / Version Begin Of Reg File&lt;br&gt;Windows Registry Editor Version 5.00&lt;br&gt;&lt;br&gt;[HKEY_CLASSES_ROOT\Folder\shell\.NET Cmd 2003\command]&lt;br&gt;@="cmd.exe /K&amp;nbsp; \"C:\\Program Files\\Microsoft Visual Studio .NET 2003\\Common7\\Tools\\vsvars32.bat\""&lt;br&gt;&lt;br&gt;-- End Of RegFile&lt;br&gt;&lt;br&gt;&lt;br&gt; ---- 2005 / Version Begin Of Reg File&lt;br&gt;Windows Registry Editor Version 5.00&lt;br&gt;&lt;br&gt;[HKEY_CLASSES_ROOT\Folder\shell\.NET Cmd 2005 Beta 2\command]&lt;br&gt;@="cmd.exe /K&amp;nbsp; \"C:\\Program  Files\\Microsoft Visual Studio 8\\Common7\\Tools\\vsvars32.bat\""&lt;br&gt;&lt;br&gt;-- End Of RegFile&lt;br&gt;&lt;p&gt;&amp;#32; 	 		&lt;hr size=1&gt;See the all-new, redesigned Yahoo.com. &lt;a href="http://us.rd.yahoo.com/evt=40762/*http://www.yahoo.com/preview"&gt; Check it out.&lt;/a&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-115425679713401526?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/115425679713401526/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=115425679713401526' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/115425679713401526'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/115425679713401526'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2006/07/adding-net-command-prompt-to-explorer.html' title='Adding A .Net Command Prompt to Explorer context menu'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-115284904271375021</id><published>2006-07-13T20:50:00.000-07:00</published><updated>2006-07-13T20:50:42.903-07:00</updated><title type='text'>On the light side / Superman</title><content type='html'>I just saw the new Superman movie. Yes, I was a younger man when I saw the first one. I hesitated going to see this new version. Remakes are usually disappointing.&lt;br&gt;&lt;br&gt;I was very pleased with this version. The themes are wellknown and the music is still the same good old one. Powerful special effects that do not obscure the story. A good moment.&lt;br&gt;&lt;br&gt;BTW, Superman's cape is made of whool from France. I know you don't care but I had to brag a little&lt;br&gt;&lt;p&gt;&amp;#32; 	 		&lt;hr size=1&gt;Sneak preview the &lt;a href="http://us.rd.yahoo.com/evt=40762/*http://www.yahoo.com/preview"&gt; all-new Yahoo.com&lt;/a&gt;. It's not radically different. Just radically better.  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-115284904271375021?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/115284904271375021/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=115284904271375021' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/115284904271375021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/115284904271375021'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2006/07/on-light-side-superman.html' title='On the light side / Superman'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-115284869983461918</id><published>2006-07-13T20:44:00.000-07:00</published><updated>2006-07-13T20:44:59.910-07:00</updated><title type='text'>A validated check box in ASP.Net</title><content type='html'>As you probably know, there is no validator for a check box in ASP.Net. People go through hoops to make this work.&lt;br&gt;&lt;br&gt;We just want to force the user to check the box before submitting. This is for scenarios like "click to accept agreement etc..."&lt;br&gt;&lt;br&gt;The solutions I have found were not to my complete liking. So here is my solution to this annoying problem. It is very compact and involves very little javascript. It is a cool little trick. Have fun.&lt;br&gt;&lt;br&gt;&lt;br&gt;&amp;lt;%@ Control Language="C#" %&amp;gt;&lt;br&gt;&amp;lt;script runat="server"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected override void OnPreRender(EventArgs e)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; base.OnPreRender(e);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _BoxMirror.Style.Add("display", "none"); // Hide the box. It is just there for the&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // validation logic to work.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // Now hook up the check box to the  text box. The text value mirrors the&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // value of the check box in sync.&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _Box.Attributes["onclick"] = "getElementById('" + _BoxMirror.ClientID + "').value=this.checked";&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _BoxMirror.Text = _Box.Checked.ToString().ToLower(); // Sync text box and check box &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // The validator Initial value is set to "false" so the Text Box will validate when&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; // its value is different from "false". &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;br&gt;&amp;lt;/script&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;div runat="server" id="_Wrapper" style="background-color:Yellow"&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:TextBox runat="server" ID="_BoxMirror" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:CheckBox runat="server" ID="_Box" /&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;asp:RequiredFieldValidator InitialValue="false"  &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; runat="server" Text="*" ID="_NeedToBeChecked" ControlToValidate="_BoxMirror" /&amp;gt;&lt;br&gt;&amp;lt;/div&amp;gt;&lt;br&gt;&lt;br&gt;&lt;p&gt;&amp;#32; 	 		&lt;hr size=1&gt;Sneak preview the &lt;a href="http://us.rd.yahoo.com/evt=40762/*http://www.yahoo.com/preview"&gt; all-new Yahoo.com&lt;/a&gt;. It's not radically different. Just radically better.  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-115284869983461918?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/115284869983461918/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=115284869983461918' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/115284869983461918'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/115284869983461918'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2006/07/validated-check-box-in-aspnet.html' title='A validated check box in ASP.Net'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-115178931316872804</id><published>2006-07-01T14:28:00.000-07:00</published><updated>2006-07-01T14:28:33.220-07:00</updated><title type='text'>AT&amp;T's Big Brother Policy</title><content type='html'>Sony puts rootkits on their CD, now AT&amp;amp;T violates basic privacy&lt;br&gt;&lt;br&gt;&lt;a href="http://www.sfgate.com/cgi-bin/article.cgi?f=/c/a/2006/06/21/BUG9VJHB9C1.DTL&amp;amp;hw=at&amp;amp;sn=002&amp;amp;sc=870"&gt;http://www.sfgate.com/cgi-bin/article.cgi?f=/c/a/2006/06/21/BUG9VJHB9C1.DTL&amp;amp;hw=at&amp;amp;sn=002&amp;amp;sc=870 &lt;/a&gt;&lt;br&gt;&lt;br&gt;Should we just throw our TVs, Phones, Computers and live on a deserted island to keep our&lt;br&gt;basic rights?&lt;br&gt;&lt;br&gt;I have had bad experiences with AT&amp;amp;T so this is not surprising&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-115178931316872804?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/115178931316872804/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=115178931316872804' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/115178931316872804'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/115178931316872804'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2006/07/atts-big-brother-policy.html' title='AT&amp;T&apos;s Big Brother Policy'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-115178695161805035</id><published>2006-07-01T13:49:00.000-07:00</published><updated>2006-07-01T13:49:11.670-07:00</updated><title type='text'>An alternative to Page.RegisterClientScriptBlock</title><content type='html'>When you make a custom control that requires custom javascript you usually have to make sure that &lt;br&gt;you output the javascript code once and once only. If you don't, the same javascript is downloaded to the browser and waste bandwith. There are also issues with global variables declared multiple times etc.. &lt;br&gt;&lt;br&gt;ASP.Net provides a Page.RegisterClientScriptBlock that allows you to register a piece of code once and the framework will output it once on the page. This works fine and I have been using it a lot. &lt;br&gt;The issue with this is that you must generate the javascript in code like this. &lt;br&gt;&lt;br&gt;protected override void OnInit(EventArgs e)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; string strCode = @&amp;quot;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;&amp;lt;script language='javascript'&amp;gt;&amp;quot;&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;+&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;function ChangeImage(ImageRef)&amp;quot; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; +&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;{&amp;quot;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; +&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;ImageRef.src = '&lt;a href="http://www.google.com/images/firefox/fox1.gif"&gt;http://www.google.com/images/firefox/fox1.gif&lt;/a&gt;'&amp;quot;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; +&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;quot;}&amp;quot; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; +&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;quot;&amp;lt;/script&amp;gt;&amp;quot;;&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; Page.RegisterClientScriptBlock(&amp;quot;SomeUniqueKeyOfYourChoosing&amp;quot;,strCode);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;This works fine but it would be cool if I could still put this code in the ascx and still make sure it is output &lt;br&gt;once. The advantage is that it is easier to edit ascx inline than editing the C# code to craft the javascript.&lt;br&gt;&lt;br&gt;I came up with this simple solution. The idea is this. We need to keep track of the fact that we have or have not output the javascript section already. ViewState is out of the question since it is scoped to each control. SessionState is also out of the question. SessionState should be use sparingly and we should stay away from it if we can. We just need to keep track of the javascript for this page only so we can use the Items collection that lives only for the duration of the request. After we output the page, we do not need to keep count so this is a good solution. &lt;br&gt;&lt;br&gt;We are half way there. We now need to not output the javascript. Here is the trick. We will wrap the script with a &amp;lt;div&amp;gt; tag with runat=&amp;quot;server&amp;quot;. Inside the &amp;lt;div&amp;gt; is the javascript code! We just need to control the visibility of the div! &lt;br&gt;&lt;br&gt;Here is the complete control code. It is just an image that changes when you click on it. We call&lt;br&gt;a javascript ChangeImage() function in javascript when the image is clicked. &lt;br&gt;&lt;br&gt;Cool &amp;lt;div&amp;gt; isn't it?&lt;br&gt; &lt;br&gt;&amp;lt;%@ Control Language=&amp;quot;C#&amp;quot; ClassName=&amp;quot;SimpleControl&amp;quot; %&amp;gt;&lt;br&gt;&amp;lt;asp:Image runat=&amp;quot;server&amp;quot; ID=&amp;quot;_Image&amp;quot; /&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;script runat=&amp;quot;server&amp;quot;&amp;gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void Page_Load(object s, EventArgs e) &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _Image.ImageUrl = &amp;quot;&lt;a href="http://www.google.com/images/logo_sm.gif"&gt;http://www.google.com/images/logo_sm.gif&lt;/a&gt;&amp;quot;;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; string JavascriptKey&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; get&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; return this.GetType().FullName + &amp;quot;JS&amp;quot;;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; void HandleJavascriptCodeStreaming()&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HttpContext ctx = HttpContext.Current;&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; bool? JavascriptAlreadyOutput = (bool?)  ctx.Items[JavascriptKey];&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; JavascriptCode.Visible = !JavascriptAlreadyOutput.HasValue;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ctx.Items[JavascriptKey] = true;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; protected override void OnPreRender(EventArgs e)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; { &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; base.OnPreRender(e);&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; _Image.Attributes[&amp;quot;onclick&amp;quot;] = &amp;quot;ChangeImage(this)&amp;quot;;&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; HandleJavascriptCodeStreaming();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp; &amp;nbsp;&lt;br&gt;&amp;lt;/script&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;div runat=&amp;quot;server&amp;quot; id=&amp;quot;JavascriptCode&amp;quot;&amp;gt; &lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;!-- We use the Div to Control The Visibility of the javascript code --&amp;gt;&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;script language=&amp;quot;javascript&amp;quot;&amp;gt;&lt;br&gt;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; function ChangeImage(ImageRef)&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; {&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; ImageRef.src  = &amp;quot;&lt;a href="http://www.google.com/images/firefox/fox1.gif"&gt;http://www.google.com/images/firefox/fox1.gif&lt;/a&gt;&amp;quot;&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;lt;/script&amp;gt;&lt;br&gt;&lt;br&gt;&amp;lt;/div&amp;gt;&lt;br&gt;&lt;br&gt; &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-115178695161805035?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/115178695161805035/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=115178695161805035' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/115178695161805035'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/115178695161805035'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2006/07/alternative-to-pageregisterclientscrip.html' title='An alternative to Page.RegisterClientScriptBlock'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-115145964434491091</id><published>2006-06-27T18:54:00.000-07:00</published><updated>2006-07-01T12:57:49.820-07:00</updated><title type='text'>Making Dynamic CSS content with ASP.Net</title><content type='html'>I had the situation where there was a need to modify a css file on the fly.&lt;br /&gt;It is like the poor man's Theme but it is slightly different.&lt;br /&gt;Let's say you want the H1 background color to be configurable by the user. This&lt;br /&gt;can be achieved via the Profile and by some other means.&lt;br /&gt;For the sake of this demo, I will use the Session state. Let's say I have&lt;br /&gt;a stylesheet like this&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;H1 { background-color:Red; } &lt;/span&gt;&lt;br /&gt;&lt;br /&gt;in a file called StyleSheet.css in the application root.&lt;br /&gt;&lt;br /&gt;What I want to do is to replace the "Red" with "Blue" for instance according to&lt;br /&gt;some value in the Session. The first naive approach is to read the css in memory and&lt;br /&gt;do a string replace. This is very brittle and just a bad hack. Some may get smarter&lt;br /&gt;and use a regular expression.&lt;br /&gt;&lt;br /&gt;The approach I am taking here is the following. We already have something in ASP.Net&lt;br /&gt;that does text substitution! Yep, an aspx page does just that with server side &lt;br /&gt;code injection. So, conceptually what we want is this:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;H1 { background-color:&amp;lt;%= ColorManager.Color %&amp;gt; ; }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Where ColorManager is some class we write to get the color from the Session.&lt;br /&gt;&lt;br /&gt;As you are aware, css does not support this kind of syntax. Can we just fool the&lt;br /&gt;system to do this? If you are in love with the ASP.Net pipeline, you can....&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Step 1&lt;/span&gt; : &lt;br /&gt;We rename StyleSheet.css to StyleSheet.aspx and make a 'page' like this&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;&amp;lt;%@ Page Language="C#" %&amp;gt;&lt;/span&gt;   &lt;span style="font-weight: bold;"&gt;H1 { background-color:&amp;lt;%= ColorManager.Color %&amp;gt;; }&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Step 2&lt;/span&gt;:&lt;br /&gt;We make ColorManager.cs and put it in App_Code. A static class will do.&lt;br /&gt;For now you can just stub this out like this&lt;br /&gt;&lt;br /&gt;public static class ColorManager&lt;br /&gt;{&lt;br /&gt;    static public string Color&lt;br /&gt;    {&lt;br /&gt;        get&lt;br /&gt;        {&lt;br /&gt;            if (HttpContext.Current.Session["H1COLOR"] == null)&lt;br /&gt;                return "red";&lt;br /&gt;            return (string)HttpContext.Current.Session["H1COLOR"];&lt;br /&gt;        }&lt;br /&gt;        set&lt;br /&gt;        {&lt;br /&gt;            HttpContext.Current.Session["H1COLOR"] = value;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;Step 3&lt;/span&gt;:&lt;br /&gt;We need to add a link to our dynamic stylesheet from a test page.&lt;br /&gt;The perfect spot to put it is in the &amp;lt;HEAD&amp;gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt; &amp;lt;head runat="server"&amp;gt;&lt;/span&gt; &lt;span style="font-weight: bold;"&gt;    &amp;lt;link rel="stylesheet" href="StyleSheet.aspx" type="text/css" /&amp;gt;    &lt;/span&gt;  &lt;span style="font-weight: bold;"&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The href is pointing to our StyleSheet.aspx. The browser could not care less about the&lt;br /&gt;address here as long as the type is correctly set to "text/css". The browser will&lt;br /&gt;interpret the web response as a css text (which it is).&lt;br /&gt;&lt;br /&gt;Here is the kicker, you can still use Themes with this approach. By using Themes, the&lt;br /&gt;framework will add the css from the Theme directory as &amp;lt;link&amp;gt; in the &amp;lt;HEAD runat="server"&amp;gt;&lt;br /&gt;after our own dynamic css.&lt;br /&gt;&lt;br /&gt;Here is a test page to tie all this together. Each time you click on the button&lt;br /&gt;the H1 color changes and you can even see the dynamic css by clicking on the "See CSS".&lt;br /&gt;&lt;br /&gt;So much power in ASP.Net. The question is how we can take advantage of it.&lt;br /&gt;&lt;br /&gt;CF&lt;br /&gt;&lt;br /&gt;default.aspx:&lt;br /&gt;&lt;br /&gt;&amp;lt;%@ Page Language="C#" AutoEventWireup="true"  %&amp;gt;&lt;br /&gt;&amp;lt;script runat="server"&amp;gt;&lt;br /&gt;    protected void Bt1_Click(object sender, EventArgs e)&lt;br /&gt;    {&lt;br /&gt;        ColorManager.Color = (ColorManager.Color == "red") ? "blue" : "red";&lt;br /&gt;    }&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;html xmlns=" &lt;a href="http://www.w3.org/1999/xhtml"&gt;http://www.w3.org/1999/xhtml&lt;/a&gt;" &amp;gt;&lt;br /&gt;&amp;lt;head runat="server"&amp;gt;&lt;br /&gt;    &amp;lt;link rel="stylesheet" href="StyleSheet.aspx" type="text/css" /&amp;gt;    &lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body&amp;gt;&lt;br /&gt;    &amp;lt;form id="form1" runat="server"&amp;gt;   &lt;br /&gt;        &amp;lt;H1&amp;gt;Hello World!&amp;lt;/H1&amp;gt;           &lt;br /&gt;        &amp;lt;asp:Button runat="server" ID="Bt1" OnClick="Bt1_Click" Text="Change Color" /&amp;gt;        &lt;br /&gt;        &amp;lt;asp:Hyperlink Text="See CSS" runat="server" ID="ToCSS" NavigateUrl="~/StyleSheet.aspx" /&amp;gt;       &lt;br /&gt;    &amp;lt;/form&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-115145964434491091?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/115145964434491091/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=115145964434491091' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/115145964434491091'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/115145964434491091'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2006/06/making-dynamic-css-content-with-aspnet.html' title='Making Dynamic CSS content with ASP.Net'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-115038762683188913</id><published>2006-06-15T09:07:00.000-07:00</published><updated>2006-06-15T09:07:06.866-07:00</updated><title type='text'>A Master Page GotCha...</title><content type='html'>&lt;br&gt;I was messing around with master pages and found something very strange...&lt;br&gt;&lt;br&gt;I have a page1.aspx referencing master.master.&lt;br&gt;&lt;br&gt;I made an override &lt;br&gt;CreateChildControls()&lt;br&gt;{&lt;br&gt;&amp;nbsp;&amp;nbsp; base.CreateChildControls();&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; Controls.InsertAt(0,_MyErrorLink = new HyperLink());&lt;br&gt;}&lt;br&gt;&lt;br&gt;I just want to show this debug link on top all the time...&lt;br&gt;&lt;br&gt;The page comes up but when the page posts, the rendered page is completely blank! No bytes are sent out whatsoever (as Trace="true" proves).&lt;br&gt;&lt;br&gt;There is no exception raised, it is just blank.&lt;br&gt;&lt;br&gt;So it seems that the top level of the control hierarchy should always be the master page and monkeying with the sequence in the CreateChildControls is not a good idea.&lt;br&gt;&lt;br&gt;What I am doing I think is legal since the controls collection is created the same&amp;nbsp; way everytime.&lt;br&gt;&lt;br&gt;A bug/limitation I guess. Conclusion, don't do  it&lt;br&gt;&lt;br&gt;CF&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;p&gt;&amp;#32;__________________________________________________&lt;br&gt;Do You Yahoo!?&lt;br&gt;Tired of spam?  Yahoo! Mail has the best spam protection around &lt;br&gt;http://mail.yahoo.com &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-115038762683188913?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/115038762683188913/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=115038762683188913' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/115038762683188913'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/115038762683188913'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2006/06/master-page-gotcha.html' title='A Master Page GotCha...'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-114754671205626824</id><published>2006-05-13T11:58:00.000-07:00</published><updated>2006-05-13T11:58:32.113-07:00</updated><title type='text'>Another Book / Understanding COM+</title><content type='html'>&lt;br&gt;I taught ASP.Net in New-York last week. I wanted to bring a book to read in the plane but I wanted a light one (in weight). Have you noticed computer books are just way too thick/heavy?&lt;br&gt;&lt;br&gt;I browsed through my library and found "Understanding COM+ (1999)" that I actually never read. I was lucky enough to get into Windows programming at the end of the COM days (or it was a misfortune?).&lt;br&gt;&lt;br&gt;I touched enough of COM to hate it. The infamous 0x8000xxxx errors , E_FAIL (also known as the "oh crap error") and other niceties like the registry being all messed up. Put COM+ on top of this shaky ground and it is even harder.&lt;br&gt;Not knowing what the fuss was about at the time, combined with reading the wrong #$@#$% book (I can't remember the title), I just did not get it.&lt;br&gt;&lt;br&gt;After reading "Understanding COM+", my hate turned into "that's a pretty good idea". The .Net ease of programming can now be a real incentive to use some of the services of COM+. Maybe I will change  my views and instead of avoiding COM+ at all cost, I may take advantage of it with .Net.&lt;br&gt;&lt;br&gt;If only I had read that book first. So, yes, it is a 1999 book and it is not a thick book, but the why of things is clearly explained. If you are looking for sample code with QueryInterface all over, you will be disappointed. &lt;br&gt;If you want to understand what problems COM+ is trying to solve then read this.&lt;br&gt;I am glad I did.&lt;br&gt;&lt;br&gt;And BTW, COM is not dead. If you want to host the CLR on some exotic plateform, you have to use a bunch of COM interfaces. But that's another story....&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;p&gt; 		&lt;hr size=1&gt;Get amazing travel prices for air and hotel in one click on &lt;a href="http://farechase.yahoo.com/;_ylc=X3oDMTFpMnJnZ3IxBF9TAzk3NDA3NTg5BHNlYwNtYWlsLXRhZ2xpbmVzBHNsawNmYXJlY2hhc2UtMDQyNzA2 "&gt;Yahoo! FareChase&lt;/a&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-114754671205626824?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/114754671205626824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=114754671205626824' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/114754671205626824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/114754671205626824'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2006/05/another-book-understanding-com.html' title='Another Book / Understanding COM+'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-114754528156940491</id><published>2006-05-13T11:34:00.000-07:00</published><updated>2006-05-13T12:03:21.533-07:00</updated><title type='text'>Expert ASP.Net 2.0 (Advanced Application Design) Book</title><content type='html'>Just finished reading this book. One of the problems in Windows is the numerous different ways you can design your app. The new .Net era brought us some new goodies like managed code and a huge library of classes among various things. Should we then forget the old days of COM+? What about queuing? JITA? etc...&lt;br /&gt;How does this play with ASP.Net, Web Services?&lt;br /&gt;&lt;br /&gt;Some of the older technologies are really not dead and can be leveraged in .Net.&lt;br /&gt;All of this is very confusing. This books lays a path through all this legacy and the new stuff. It is not an in depth book on all the subjects covered (nor should it be). It provides a high level view on how all this stuff can interact. It is really good to see this big picture before diving down details.&lt;br /&gt;&lt;br /&gt;Cool stuff&lt;br /&gt;&lt;p&gt;   &lt;/p&gt;&lt;hr size="1"&gt;&lt;a href="http://us.rd.yahoo.com/mail_us/taglines/postman3/*http://us.rd.yahoo.com/evt=39666/*http://messenger.yahoo.com"&gt;Yahoo! Messenger with Voice.&lt;/a&gt; PC-to-Phone calls for ridiculously low rates.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-114754528156940491?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/114754528156940491/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=114754528156940491' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/114754528156940491'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/114754528156940491'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2006/05/expert-aspnet-20-advanced-application.html' title='Expert ASP.Net 2.0 (Advanced Application Design) Book'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-113219207433891836</id><published>2005-11-16T17:47:00.000-08:00</published><updated>2005-11-16T17:47:54.353-08:00</updated><title type='text'>Won't buy Sony any more</title><content type='html'>&lt;div id="RTEContent"&gt;Here is why.&lt;br&gt;  &lt;br&gt;  http://www.sysinternals.com/Blog/&lt;br&gt;  &lt;br&gt;  or &lt;br&gt;  &lt;br&gt;  http://www.sonybmg.com/&lt;br&gt;  &lt;br&gt;  Customers should not stand for this. What is this ? Big brother?&lt;br&gt;  &lt;br&gt;  click on "Information on XCP content protection"&lt;br&gt;  &lt;br&gt;  I am now scanning my PC for rootkits. See www.sysinternals.com for details. They have a tool to scan your machine.&lt;br&gt;  &lt;font size="+1"&gt;&lt;br&gt;  &lt;br&gt;  &lt;/font&gt;&lt;/div&gt;&lt;p&gt; 		&lt;hr size=1&gt; &lt;a href="http://us.lrd.yahoo.com/_ylc=X3oDMTFqODRtdXQ4BF9TAzMyOTc1MDIEX3MDOTY2ODgxNjkEcG9zAzEEc2VjA21haWwtZm9vdGVyBHNsawNmYw--/SIG=110oav78o/**http%3a//farechase.yahoo.com/"&gt;Yahoo! FareChase - Search multiple travel sites in one click.&lt;/a&gt;      &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-113219207433891836?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/113219207433891836/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=113219207433891836' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/113219207433891836'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/113219207433891836'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2005/11/wont-buy-sony-any-more.html' title='Won&apos;t buy Sony any more'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-112878179229431527</id><published>2005-10-08T07:29:00.000-07:00</published><updated>2005-10-08T07:29:52.503-07:00</updated><title type='text'>Book Review / The Pragmatic Programmer</title><content type='html'>&lt;p class="mobile-post"&gt; &lt;br /&gt;An interesting title. After browsing a few pages at&lt;br /&gt;the book store I bought it, and read it pretty&lt;br /&gt;quickly. An easy read but a good one. I have to say&lt;br /&gt;that I was pleased to find out that some people see&lt;br /&gt;the light. &lt;/p&gt;&lt;p class="mobile-post"&gt;Most people look at a design / piece of code and do&lt;br /&gt;not even see what's wrong. Worse, they see what's&lt;br /&gt;wrong and do not do anything about it.&lt;/p&gt;&lt;p class="mobile-post"&gt;I agree with pretty much anything this book promotes.&lt;br /&gt;I am no longer alone in the universe thinking this&lt;br /&gt;way. For a while I thought I was an anomaly of nature.&lt;/p&gt;&lt;p class="mobile-post"&gt;The book is a collection of tips that can only be&lt;br /&gt;acquired by years of experience. Experienced&lt;br /&gt;programmers should read it to get a clear description&lt;br /&gt;of what we sometimes do instinctively.&lt;/p&gt;&lt;p class="mobile-post"&gt;Newbies should read it too and learn from the older&lt;br /&gt;guys and become good programmers quicker.&lt;/p&gt;&lt;p class="mobile-post"&gt;There are a lot of good analogies in this book as well&lt;br /&gt;as quotes that I really liked. &lt;/p&gt;&lt;p class="mobile-post"&gt;The abstract nature of our craft deserved a human side&lt;br /&gt;that this book provides.&lt;/p&gt;&lt;p class="mobile-post"&gt;		&lt;br /&gt;__________________________________ &lt;br /&gt;Yahoo! Music Unlimited &lt;br /&gt;Access over 1 million songs. Try it free.&lt;br /&gt;http://music.yahoo.com/unlimited/&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-112878179229431527?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/112878179229431527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=112878179229431527' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/112878179229431527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/112878179229431527'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2005/10/book-review-pragmatic-programmer.html' title='Book Review / The Pragmatic Programmer'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-112636853953949682</id><published>2005-09-10T09:07:00.000-07:00</published><updated>2005-09-10T09:10:28.990-07:00</updated><title type='text'>Writing JSP pages in C#</title><content type='html'>Enough said. Go to my web site here.&lt;br /&gt;http://www.t-d-n-g.com/default.aspx?P=AboutJsp&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-112636853953949682?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/112636853953949682/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=112636853953949682' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/112636853953949682'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/112636853953949682'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2005/09/writing-jsp-pages-in-c.html' title='Writing JSP pages in C#'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-112575607953222390</id><published>2005-09-03T06:55:00.000-07:00</published><updated>2005-09-03T07:01:19.716-07:00</updated><title type='text'>New Samples on my web site</title><content type='html'>I am giving a talk at Microsoft (C# users group) on Tuesday about httpHandlers.&lt;br /&gt;Since they are going to ask me where they can get the samples, I added them to my web site. Here is the link http://www.t-d-n-g.com/default.aspx?P=CodeSamples&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-112575607953222390?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/112575607953222390/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=112575607953222390' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/112575607953222390'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/112575607953222390'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2005/09/new-samples-on-my-web-site.html' title='New Samples on my web site'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-111413904742847094</id><published>2005-04-21T19:42:00.000-07:00</published><updated>2005-04-21T20:08:06.556-07:00</updated><title type='text'>Make your own webhandler factory, why? Because you can!</title><content type='html'>In ASP.Net, the framework provide a default handler for ashx files. It is called&lt;br /&gt;"System.Web.UI.SimpleHandlerFactory". You can find the mapping in machine.config.&lt;br /&gt;The main job of this handler is to compile an ashx file, find the class that implements IHttpHandler, instanciate it and call its Process request so your handler can do its job.&lt;br /&gt;This "System.Web.UI.SimpleHandlerFactory" does all this for you. I wanted to make my own, just for fun... Actually for my students who want to know a little more of what is going on behind the scene.&lt;br /&gt;&lt;br /&gt;There are 3 parts to this:&lt;br /&gt;- 1: A standard ashx file to make sure my new factory can create my handler and pass the request through.&lt;br /&gt;- 2: A factory class that needs to be compiled as a library and placed in the bin directory. The name of the assembly needs to be webhandler.dll for this demo.&lt;br /&gt;- 3: A web.config to remap the standard "System.Web.UI.SimpleHandlerFactory" to "DM.SimpleWebHandlerFactory"&lt;br /&gt;&lt;br /&gt;Enjoy!&lt;br /&gt;&lt;br /&gt;Part 1: Here is a standard ashx file&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;%@  WebHandler Language="C#"   class="SimplestHandlerEver"   %&gt;&lt;br /&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Web;&lt;br /&gt;&lt;br /&gt;class SimplestHandlerEver : IHttpHandler&lt;br /&gt;{&lt;br /&gt; public SimplestHandlerEver()&lt;br /&gt; {&lt;br /&gt; }&lt;br /&gt; &lt;br /&gt; public void ProcessRequest(HttpContext context)&lt;br /&gt; {&lt;br /&gt;  context.Response.Write(this.GetType().FullName + " called");&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public bool IsReusable&lt;br /&gt; {&lt;br /&gt;  get&lt;br /&gt;  {    &lt;br /&gt;   return false;&lt;br /&gt;  }&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;//--- End of File&lt;br /&gt;&lt;br /&gt;Part 2: Here is the custom factory that you need to compile and place in the bin directory.&lt;br /&gt;&lt;br /&gt;using System;&lt;br /&gt;using System.Text;&lt;br /&gt;using System.Web;&lt;br /&gt;using Microsoft.CSharp;&lt;br /&gt;&lt;br /&gt;namespace DM&lt;br /&gt;{&lt;br /&gt; /// &lt;summary&gt;&lt;br /&gt; /// Author: C. Fouquet&lt;br /&gt; /// This is a very simple handler factory that can be used to replace the&lt;br /&gt; /// standard System.Web.UI.SimpleHandlerFactory that is mapped to &lt;br /&gt; /// the .ashx extension in the machine.config&lt;br /&gt; /// Needless to say, this is a very crude implementation of an IHttpHandlerFactory.&lt;br /&gt; /// This is just to illustrate the rough steps the actual System.Web.UI.SimpleHandlerFactory&lt;br /&gt; /// goes through to create the handler.&lt;br /&gt; /// It is very inefficient. The code is compiled every time, the generated assembly is&lt;br /&gt; /// loaded every time.&lt;br /&gt; /// Also, look at the web.config to see how we remap the default handler factory&lt;br /&gt; /// &lt;/summary&gt;&lt;br /&gt; public class SimpleWebHandlerFactory : IHttpHandlerFactory&lt;br /&gt; {  &lt;br /&gt;&lt;br /&gt;  public SimpleWebHandlerFactory()&lt;br /&gt;  {&lt;br /&gt;   &lt;br /&gt;  }&lt;br /&gt;  #region IHttpHandlerFactory Members&lt;br /&gt;&lt;br /&gt;  public void ReleaseHandler(IHttpHandler handler)&lt;br /&gt;  {&lt;br /&gt;   &lt;br /&gt;  }&lt;br /&gt;  &lt;br /&gt;  &lt;br /&gt;  public IHttpHandler GetHandler(HttpContext context, string requestType, string url, string pathTranslated)&lt;br /&gt;  {&lt;br /&gt;   string HandlerRequested = pathTranslated;&lt;br /&gt;   string Language ;&lt;br /&gt;   string Class;&lt;br /&gt;&lt;br /&gt;   // Open the .ashx file being hit&lt;br /&gt;   using(System.IO.StreamReader fs = System.IO.File.OpenText(HandlerRequested))&lt;br /&gt;   {&lt;br /&gt;&lt;br /&gt;    // The first line is the webhandler directive. Or so we hope!&lt;br /&gt;    string Directive = fs.ReadLine();&lt;br /&gt;&lt;br /&gt;    // Extract the information we are looking for from the directive&lt;br /&gt;    if(ProcessDirective(Directive, out Language, out Class))&lt;br /&gt;    {&lt;br /&gt;     if(Language.ToUpper() != "C#" &amp;&amp; Language.ToUpper()!="CSHARP")&lt;br /&gt;     {&lt;br /&gt;      throw new Exception(Language + " Language Not Supported");&lt;br /&gt;     }&lt;br /&gt;    }&lt;br /&gt;    else&lt;br /&gt;    {&lt;br /&gt;     throw new Exception("missing or badly formatted webhandler directive");&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    string TheCode = fs.ReadToEnd(); // This is the rest of the code&lt;br /&gt;&lt;br /&gt;    string Target = System.IO.Path.GetTempFileName(); // We need an output&lt;br /&gt;    // file name so let the OS pick it.&lt;br /&gt;&lt;br /&gt;    // For simplicity here, we just include what we need. Obviously&lt;br /&gt;    // we would have to process the import directives but .. not today&lt;br /&gt;    // This is just a demo remember?&lt;br /&gt;    string[] Imports = new string[] {&lt;br /&gt;             "System.Web.dll"&lt;br /&gt;            };&lt;br /&gt;&lt;br /&gt;    System.Collections.Specialized.ListDictionary options = new System.Collections.Specialized.ListDictionary();&lt;br /&gt;    options.Add("target","library"); // equivalent of doing csc /t:library ...&lt;br /&gt;&lt;br /&gt;    CompilerError[] Errors = Compiler.Compile(&lt;br /&gt;     new string[] { TheCode },&lt;br /&gt;     new string[] { "TheCode" },&lt;br /&gt;     Target,&lt;br /&gt;     Imports,&lt;br /&gt;     options);&lt;br /&gt;&lt;br /&gt;    // Now we can load it&lt;br /&gt;    System.Reflection.Assembly HandlerAssembly = System.Reflection.Assembly.LoadFile(Target);      &lt;br /&gt;&lt;br /&gt;    // And find the type we listed in the directive&lt;br /&gt;    IHttpHandler TheActualHandler = (IHttpHandler) HandlerAssembly.CreateInstance(Class);&lt;br /&gt;      &lt;br /&gt;    return TheActualHandler;&lt;br /&gt;   }&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  &lt;br /&gt; // This parses the Directive. It is a little heavy on regex.. but regex are so much fun!&lt;br /&gt; &lt;br /&gt;  private bool ProcessDirective(string Directive, out string Language, out string Class)&lt;br /&gt;  {&lt;br /&gt;   Language = Class = string.Empty;&lt;br /&gt;   &lt;br /&gt;   string BackSlash ="\\";&lt;br /&gt;   string DoubleQuote ="\"";&lt;br /&gt;   &lt;br /&gt;   StringBuilder sb = new StringBuilder();&lt;br /&gt;   sb.Append("&lt;%@");&lt;br /&gt;   sb.Append(BackSlash);sb.Append("s+");&lt;br /&gt;   sb.Append("WebHandler");&lt;br /&gt;   sb.Append(BackSlash);sb.Append("s+");&lt;br /&gt;   &lt;br /&gt;&lt;br /&gt;   // Language="C#" &lt;br /&gt;   sb.Append("Language=");sb.Append(DoubleQuote);&lt;br /&gt;   sb.Append("(?&lt;Language&gt;[A-Za-z0-9]");sb.Append(BackSlash);sb.Append("#?)");&lt;br /&gt;   sb.Append(DoubleQuote);&lt;br /&gt;&lt;br /&gt;   // Any space&lt;br /&gt;   sb.Append(BackSlash);sb.Append("s+");&lt;br /&gt;&lt;br /&gt;   // class="xyx"&lt;br /&gt;   sb.Append("class=");sb.Append(DoubleQuote);&lt;br /&gt;   sb.Append("(?&lt;Class&gt;");sb.Append(BackSlash);sb.Append("w+)"); &lt;br /&gt;   sb.Append(DoubleQuote);&lt;br /&gt;&lt;br /&gt;   // Any space&lt;br /&gt;   sb.Append(BackSlash);sb.Append("s+");&lt;br /&gt;&lt;br /&gt;   sb.Append("%&amp;lt;");&lt;br /&gt;&lt;br /&gt;   string regex = sb.ToString();&lt;br /&gt;&lt;br /&gt;   System.Text.RegularExpressions.RegexOptions options = ((System.Text.RegularExpressions.RegexOptions.IgnorePatternWhitespace | System.Text.RegularExpressions.RegexOptions.Singleline) &lt;br /&gt;    | System.Text.RegularExpressions.RegexOptions.IgnoreCase);&lt;br /&gt;   System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(regex, options);&lt;br /&gt;&lt;br /&gt;   System.Text.RegularExpressions.Match m = reg.Match(Directive);&lt;br /&gt;   if(m.Success)&lt;br /&gt;   {&lt;br /&gt;    Language = m.Groups["Language"].Value;&lt;br /&gt;    Class = m.Groups["Class"].Value;&lt;br /&gt;    return true;&lt;br /&gt;   }&lt;br /&gt;&lt;br /&gt;   return false;&lt;br /&gt;   &lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;  #endregion&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;Part 3: The web.config&lt;br /&gt;&lt;br /&gt;&amp;lt;configuration&amp;gt;&lt;br /&gt;  &amp;lt;system.web&amp;gt;&lt;br /&gt; &amp;lt;httpHandlers&amp;gt;&lt;br /&gt;  &amp;lt;remove verb="*" path="*.ashx"/&amp;gt;&lt;br /&gt;  &amp;lt;add verb="*" path="*.ashx" type="&lt;span style="font-weight:bold;"&gt;DM.SimpleWebHandlerFactory&lt;/span&gt;, &lt;span style="font-weight:bold;"&gt;webhandler&lt;/span&gt;"/&amp;gt;&lt;br /&gt; &amp;lt;/httpHandlers&amp;gt;&lt;br /&gt; &amp;lt;/system.web&amp;gt;&lt;br /&gt;&amp;lt;/configuration&amp;gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-111413904742847094?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/111413904742847094/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=111413904742847094' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/111413904742847094'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/111413904742847094'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2005/04/make-your-own-webhandler-factory-why.html' title='Make your own webhandler factory, why? Because you can!'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-111413740376974335</id><published>2005-04-21T19:17:00.000-07:00</published><updated>2005-04-21T19:36:43.773-07:00</updated><title type='text'>I got burnt by ToString()</title><content type='html'>I have encountered a gotcha that I want to share. Strong typing is my thing. There is nothing that &lt;br /&gt;bothers me more than seeing hardcoded strings in code. &lt;br /&gt;&lt;br /&gt;In ADO.Net it is common to do something like this&lt;br /&gt;Data ds = GetDataSetFromDB()&lt;br /&gt;...&lt;br /&gt;DataRow dr = ...&lt;br /&gt;&lt;br /&gt;string Name = (string) dr[&lt;span style="font-weight:bold;"&gt;"Name"&lt;/span&gt;];&lt;br /&gt;&lt;br /&gt;If you mistype "Name" you are doomed. So I used to do this: define an enum called "Columns" that had all the&lt;br /&gt;column names I am interested in.&lt;br /&gt;enum Columns&lt;br /&gt;{&lt;br /&gt; Name,&lt;br /&gt; Email,&lt;br /&gt; Zip&lt;br /&gt;        // etc...   &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;I can check the names once (visually and programmtically against the database) and in the code use this&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;string Name = (string) dr[&lt;span style="font-weight:bold;"&gt;Columns.Name.ToString()&lt;/span&gt;];&lt;br /&gt;&lt;br /&gt;As long as you remember to use the enum, you can't mess up.&lt;br /&gt;&lt;br /&gt;Now, before you go do this, it is very very slow. You would think that it is straightforward for the runtime&lt;br /&gt;to convert an enum into its string representation. That's not the case.&lt;br /&gt;&lt;br /&gt;if you compile this into an exe&lt;br /&gt;&lt;br /&gt;using System;&lt;br /&gt;&lt;br /&gt;public class HelloClient&lt;br /&gt;{&lt;br /&gt;&lt;br /&gt; public enum Columns&lt;br /&gt; {&lt;br /&gt;  Name&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt;   public static void Main()&lt;br /&gt;   {&lt;br /&gt;     Console.WriteLine(Columns.Name.ToString());&lt;br /&gt;   }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;and look at the ToString() with Reflector here is what you get. This is the ToString() from the &lt;br /&gt;Enum type.&lt;br /&gt;&lt;br /&gt;public override string ToString()&lt;br /&gt;{&lt;br /&gt;      Type type1 = base.GetType();&lt;br /&gt;      FieldInfo info1 = Enum.GetValueField(type1);&lt;br /&gt;      object obj1 = ((RuntimeFieldInfo) info1).InternalGetValue(this, false);&lt;br /&gt;      return Enum.InternalFormat(type1, obj1);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;and look at what GetValueField does...&lt;br /&gt;&lt;br /&gt;private static FieldInfo GetValueField(Type type)&lt;br /&gt;{&lt;br /&gt;      FieldInfo[] infoArray1;&lt;br /&gt;      if (type is RuntimeType)&lt;br /&gt;      {&lt;br /&gt;            infoArray1 = ((RuntimeType) type).InternalGetFields(BindingFlags.NonPublic | (BindingFlags.Public | BindingFlags.Instance), false);&lt;br /&gt;      }&lt;br /&gt;      else&lt;br /&gt;      {&lt;br /&gt;            infoArray1 = type.GetFields(BindingFlags.NonPublic | (BindingFlags.Public | BindingFlags.Instance));&lt;br /&gt;      }&lt;br /&gt;      if ((infoArray1 == null) || (infoArray1.Length != 1))&lt;br /&gt;      {&lt;br /&gt;            throw new ArgumentException(Environment.GetResourceString("Arg_EnumMustHaveUnderlyingValueField"));&lt;br /&gt;      }&lt;br /&gt;      return infoArray1[0];&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Arg!!! Reflexion all over the place. No wonder it is slow....&lt;br /&gt;&lt;br /&gt;Now, this is the generic Enum.ToString(). I would hope that it does not do that for Booleans... Let's check.&lt;br /&gt;&lt;br /&gt;// Part of Boolean&lt;br /&gt;&lt;br /&gt;public override string ToString()&lt;br /&gt;{&lt;br /&gt;      if (!this.m_value)&lt;br /&gt;      {&lt;br /&gt;            return bool.FalseString;&lt;br /&gt;      }&lt;br /&gt;      return bool.TrueString;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public static readonly string FalseString;&lt;br /&gt;public static readonly string TrueString;&lt;br /&gt;&lt;br /&gt;// End of Boolean&lt;br /&gt;&lt;br /&gt; &lt;br /&gt;Good!! Somebody is thinking.&lt;br /&gt;&lt;br /&gt;Well, I guess we are stuck with the implementation of ToString() for our custom Enums. It would be nice though to let the &lt;br /&gt;compiler know to inline the Enum's ToString() like a custom attribute. For instance:&lt;br /&gt;&lt;br /&gt;[HeyCompilerBeSmartAboutTheToStringMethodPleaaaaseAttribute()]&lt;br /&gt;enum Columns&lt;br /&gt;{&lt;br /&gt; Name,&lt;br /&gt; Email &lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;It would be nice indeed.&lt;br /&gt;&lt;br /&gt;So I am stuck and went back to using strings like this&lt;br /&gt;&lt;br /&gt;string Name = (string) dr[&lt;span style="font-weight:bold;"&gt;"Name"&lt;/span&gt;];&lt;br /&gt;&lt;br /&gt;Cool. If you use reflector again you will see that a hashtable look up is done every time&lt;br /&gt;you access that column. I did some timing and it is still slow for my standards!&lt;br /&gt;&lt;br /&gt;Let's push it further. What we want is brute speed like this.&lt;br /&gt;&lt;br /&gt;string Name = (string) dr[&lt;span style="font-weight:bold;"&gt;3&lt;/span&gt;]; // 3 == "Name"&lt;br /&gt;&lt;br /&gt;That is fast but brittle. If you move the column around in your table, you are out of synch and you will&lt;br /&gt;most likelt get a beautiful exception.&lt;br /&gt;&lt;br /&gt;This is why you need to use the "Ordinal" property on the "DataColumn".&lt;br /&gt;&lt;br /&gt;If you want speed, you need to precompute the ordinals when the application starts and then use them.&lt;br /&gt;&lt;br /&gt;You need to use a few tricks to do this on start up but it is worth it. Now my code is fast. I am a happy man.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-111413740376974335?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/111413740376974335/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=111413740376974335' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/111413740376974335'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/111413740376974335'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2005/04/i-got-burnt-by-tostring.html' title='I got burnt by ToString()'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-111360365156026846</id><published>2005-04-15T15:18:00.000-07:00</published><updated>2005-09-10T11:22:27.216-07:00</updated><title type='text'>Computer History is available for you to see</title><content type='html'>I found this. It is an archive of all the TV shows of the "Computer Chronicles".&lt;br /&gt;You probably remember the guy always introducing himself the same way. It is fun to&lt;br /&gt;see the old machines and the discussions of the time.&lt;br /&gt;&lt;br /&gt;http://www.archive.org/details/computerchronicles&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-111360365156026846?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/111360365156026846/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=111360365156026846' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/111360365156026846'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/111360365156026846'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2005/04/computer-history-is-available-for-you.html' title='Computer History is available for you to see'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-110796473945083678</id><published>2005-02-09T07:58:00.000-08:00</published><updated>2005-02-09T07:58:59.450-08:00</updated><title type='text'>An old friend, the ZX81</title><content type='html'>A friend of mine read my bio on the Developmentor web site and reminded me that I forgot to mention the ZX81 in my history of technologies I worked with. If you remember this machine, it was popular in the early 80s. It had 1K RAM , expandable to 16K (which I had bought). It seems so amazing that we could even do anything with it but we did. Saving the programs on an audio tape was really a pain but cheap. The internet was not even there but I managed to transfer a program through the air! A friend of mine was doing some radio show on a local FM station. We decided to tell our audience to start recording on tape the ZX81’s super cool program I had written. As he broadcasted 5 minutes of awful sounds, I recorded it and could reload my own program on my ZX81. Thinking of it, I was probably the only one listening to this anyway! The ultimate geeky evening but it was a lot of fun. Here is a link for the ZX81 &lt;a href="http://www.zx81.nl/"&gt;http://www.zx81.nl/&lt;/a&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-110796473945083678?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/110796473945083678/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=110796473945083678' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/110796473945083678'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/110796473945083678'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2005/02/old-friend-zx81.html' title='An old friend, the ZX81'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-110360107102180392</id><published>2004-12-20T19:51:00.000-08:00</published><updated>2005-02-09T07:58:15.763-08:00</updated><title type='text'>FireFox is cool</title><content type='html'>&lt;?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" /&gt;&lt;o:smarttagtype name="PersonName" namespaceuri="urn:schemas-microsoft-com:office:smarttags"&gt;&lt;/o:smarttagtype&gt;&lt;o:smarttagtype name="PostalCode" namespaceuri="urn:schemas-microsoft-com:office:smarttags"&gt;&lt;/o:smarttagtype&gt;&lt;o:smarttagtype name="State" namespaceuri="urn:schemas-microsoft-com:office:smarttags"&gt;&lt;/o:smarttagtype&gt;&lt;o:smarttagtype name="City" namespaceuri="urn:schemas-microsoft-com:office:smarttags"&gt;&lt;/o:smarttagtype&gt;&lt;o:smarttagtype name="place" namespaceuri="urn:schemas-microsoft-com:office:smarttags"&gt;&lt;/o:smarttagtype&gt;&lt;o:smarttagtype name="Street" namespaceuri="urn:schemas-microsoft-com:office:smarttags"&gt;&lt;/o:smarttagtype&gt;&lt;o:smarttagtype name="address" namespaceuri="urn:schemas-microsoft-com:office:smarttags"&gt;&lt;/o:smarttagtype&gt; &lt;style&gt;  st1\:*{behavior:url(#default#ieooui) }  &lt;/style&gt;&lt;br /&gt;&lt;style&gt;  &lt;!--   /* Font Definitions */   @font-face  	{font-family:"MS Mincho";  	panose-1:2 2 6 9 4 2 5 8 3 4;  	mso-font-alt:"?l?r ??Âfc";  	mso-font-charset:128;  	mso-generic-font-family:modern;  	mso-font-pitch:fixed;  	mso-font-signature:-1610612033 1757936891 16 0 131231 0;}  @font-face  	{font-family:"\@MS Mincho";  	panose-1:2 2 6 9 4 2 5 8 3 4;  	mso-font-charset:128;  	mso-generic-font-family:modern;  	mso-font-pitch:fixed;  	mso-font-signature:-1610612033 1757936891 16 0 131231 0;}   /* Style Definitions */   p.MsoNormal, li.MsoNormal, div.MsoNormal  	{mso-style-parent:"";  	margin:0in;  	margin-bottom:.0001pt;  	mso-pagination:widow-orphan;  	font-size:12.0pt;  	font-family:"Times New Roman";  	mso-fareast-font-family:"MS Mincho";}  h1  	{mso-style-update:auto;  	mso-style-next:Normal;  	margin-top:12.0pt;  	margin-right:0in;  	margin-bottom:3.0pt;  	margin-left:.5in;  	text-indent:-.25in;  	mso-pagination:widow-orphan;  	page-break-after:avoid;  	mso-outline-level:1;  	mso-list:l1 level1 lfo2;  	tab-stops:list .5in;  	font-size:16.0pt;  	font-family:Arial;  	mso-font-kerning:16.0pt;}  h2  	{mso-style-update:auto;  	mso-style-next:Normal;  	margin-top:12.0pt;  	margin-right:0in;  	margin-bottom:3.0pt;  	margin-left:.5in;  	text-indent:-.25in;  	mso-pagination:widow-orphan;  	page-break-after:avoid;  	mso-outline-level:2;  	mso-list:l0 level1 lfo1;  	tab-stops:list .5in;  	font-size:14.0pt;  	font-family:Arial;  	font-style:italic;}  a:link, span.MsoHyperlink  	{color:blue;  	text-decoration:underline;  	text-underline:single;}  a:visited, span.MsoHyperlinkFollowed  	{color:purple;  	text-decoration:underline;  	text-underline:single;}  span.EmailStyle17  	{mso-style-type:personal-compose;  	mso-style-noshow:yes;  	mso-ansi-font-size:10.0pt;  	mso-bidi-font-size:10.0pt;  	font-family:Arial;  	mso-ascii-font-family:Arial;  	mso-hansi-font-family:Arial;  	mso-bidi-font-family:Arial;  	color:windowtext;}  span.SpellE  	{mso-style-name:"";  	mso-spl-e:yes;}  @page Section1  	{size:8.5in 11.0in;  	margin:1.0in 1.25in 1.0in 1.25in;  	mso-header-margin:.5in;  	mso-footer-margin:.5in;  	mso-paper-source:0;}  div.Section1  	{page:Section1;}   /* List Definitions */   @list l0  	{mso-list-id:190925335;  	mso-list-type:hybrid;  	mso-list-template-ids:709686990 -931255532 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}  @list l0:level1  	{mso-level-style-link:"Heading 2";  	mso-level-tab-stop:.5in;  	mso-level-number-position:left;  	text-indent:-.25in;}  @list l1  	{mso-list-id:1581870189;  	mso-list-type:hybrid;  	mso-list-template-ids:-1381310316 359796552 67698713 67698715 67698703 67698713 67698715 67698703 67698713 67698715;}  @list l1:level1  	{mso-level-style-link:"Heading 1";  	mso-level-tab-stop:.5in;  	mso-level-number-position:left;  	text-indent:-.25in;}  ol  	{margin-bottom:0in;}  ul  	{margin-bottom:0in;}  --&gt;  &lt;/style&gt;&lt;br /&gt;&lt;div class="Section1"&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;span style="font-family:Arial;font-size:10;"&gt;I am using &lt;span class="SpellE"&gt;FireFox&lt;/span&gt; more and more. I have seen it crash but thatâs expected from something that new.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;span style="font-family:Arial;font-size:10;"&gt;The thing I really like is that is allows me to check my email through a web enabled Outlook access much better.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;span style="font-family:Arial;font-size:10;"&gt;Using the web interface for Outlook through IE is just plain painful and almost useable.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;span style="font-family:Arial;font-size:10;"&gt;Switching to &lt;span class="SpellE"&gt;FireFox&lt;/span&gt; makes it more than usable and it is very close to having the feel of a real mail client.&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;span style="font-family:Arial;font-size:10;"&gt;Try it!&lt;o:p&gt;&lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;span style="font-family:Arial;font-size:10;"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p class="MsoNormal"&gt;&lt;span style="font-family:Arial;font-size:85%;"&gt;&lt;span style="font-family:Arial;font-size:10;"&gt;&lt;o:p&gt; &lt;/o:p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;/div&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-110360107102180392?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/110360107102180392/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=110360107102180392' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/110360107102180392'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/110360107102180392'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2004/12/firefox-is-cool.html' title='FireFox is cool'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-8150162.post-110356809710591360</id><published>2004-12-20T10:35:00.000-08:00</published><updated>2004-12-20T10:41:37.106-08:00</updated><title type='text'>Keith Brown .Net Security Book</title><content type='html'>I am currently ready it (&lt;a href="http://www.amazon.com/exec/obidos/ASIN/0321228359/ccomput-20/103-4748007-2595816?creative=327641&amp;camp=14573&amp;amp;link_code=as1"&gt;http://www.amazon.com/exec/obidos/ASIN/0321228359/ccomput-20/103-4748007-2595816?creative=327641&amp;camp=14573&amp;amp;link_code=as1&lt;/a&gt;)&lt;br /&gt;&lt;br /&gt;Now, if you want to get scared about the safety of your data/machine then read it too. I always wanted to get into security since it is an obscure science (at least for me). This book is giving a taste of what's going on inside Windows. Some of it makes sense. Some of it is really mind boggling. If I am learning one lesson from this is that I am running all my stuff as Admin which is really, really a bad idea.&lt;br /&gt;&lt;br /&gt;I made myself a "MeWithNoPrivileges" account under my machine that I now try to use as much as possible especially when surfing the web.&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/8150162-110356809710591360?l=cfouquet.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://cfouquet.blogspot.com/feeds/110356809710591360/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='https://www.blogger.com/comment.g?blogID=8150162&amp;postID=110356809710591360' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/110356809710591360'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/8150162/posts/default/110356809710591360'/><link rel='alternate' type='text/html' href='http://cfouquet.blogspot.com/2004/12/keith-brown-net-security-book.html' title='Keith Brown .Net Security Book'/><author><name>Christophe Fouquet</name><uri>http://www.blogger.com/profile/02184300932462169431</uri><email>noreply@blogger.com</email><gd:extendedProperty xmlns:gd='http://schemas.google.com/g/2005' name='OpenSocialUserId' value='15748279825107590858'/></author><thr:total xmlns:thr='http://purl.org/syndication/thread/1.0'>1</thr:total></entry></feed>