<?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' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-18669442</id><updated>2012-01-02T16:48:01.402Z</updated><category term='C#'/><category term='Vista'/><category term='Visual Studio'/><category term='Flash'/><category term='SMTP'/><category term='Microsoft'/><category term='SQL'/><category term='WCF'/><category term='Javascript'/><category term='Outlook'/><category term='Office'/><category term='Business logic'/><category term='Tools'/><category term='Paypal'/><category term='Velodoc'/><category term='IIS'/><category term='Yahoo'/><category term='Ajax'/><category term='Google'/><category term='Data access'/><category term='.NET'/><category term='ASP.NET'/><category term='DOS'/><category term='GUI'/><title type='text'>Shared .NET stuff</title><subtitle type='html'>Share, discuss and improve</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>64</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-18669442.post-7389757316527943958</id><published>2008-12-11T21:20:00.001Z</published><updated>2008-12-11T21:20:29.117Z</updated><title type='text'>ArgumentNullException raised by Profile when deploying a web project</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;Your ASP.NET web site works perfectly in your development environment and you build a Visual Studio Web Deployment Project to deploy it in a production environment.  You launch the default page and you get:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='color:#c0504d; font-size:14pt'&gt;Value cannot be null.&lt;br/&gt;Parameter name: type &lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. &lt;br /&gt;&lt;/p&gt;&lt;p&gt;Exception Details: System.ArgumentNullException: Value cannot be null.&lt;br/&gt;Parameter name: type&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Source Error: &lt;br /&gt;&lt;/p&gt;&lt;p style='background: #ffffcc'&gt;An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.  &lt;br /&gt;&lt;/p&gt;&lt;p&gt;Stack Trace: &lt;br /&gt;&lt;/p&gt;&lt;p style='background: #ffffcc'&gt;[ArgumentNullException: Value cannot be null. Parameter name: type]&lt;br/&gt;System.Activator.CreateInstance(Type type, Boolean nonPublic) +2843963&lt;br/&gt;System.Web.Profile.ProfileBase.CreateMyInstance(String username, Boolean isAuthenticated) +76&lt;br/&gt;System.Web.Profile.ProfileBase.Create(String username, Boolean isAuthenticated) +312&lt;br/&gt;System.Web.HttpContext.get_Profile() +108&lt;br/&gt;Global.Application_AcquireRequestState(Object sender, EventArgs e) +72&lt;br/&gt;System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +92&lt;br/&gt;System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean&amp;amp; completedSynchronously) +64&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The solution to this problem is hidden in the Web Deployment Project property pages. Select the "Output Assemblies" node under "Configuration Properties" and below the "Merge all outputs to a single assembly" option, uncheck "Treat as library component (remove App_code.compiled file)".&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;			&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-7389757316527943958?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/7389757316527943958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=7389757316527943958' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/7389757316527943958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/7389757316527943958'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2008/12/argumentnullexception-raised-by-profile.html' title='ArgumentNullException raised by Profile when deploying a web project'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-408688029265829691</id><published>2008-11-28T08:56:00.007Z</published><updated>2009-01-03T08:49:28.603Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>How to configure a membership provider programmatically</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;The following C# sample code demonstrates how to configure a .NET membership provider programmatically. This code requires that you also &lt;a href="http://jlchereau.blogspot.com/2008/11/how-to-create-connection-string.html"&gt;configure a connection string&lt;/a&gt; named MyDatabase.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#2b91af;"&gt;NameValueCollection&lt;/span&gt; objConfig = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;NameValueCollection&lt;/span&gt;();&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;objConfig.Add(&lt;span style="color:#a31515;"&gt;"connectionStringName"&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;"MyDatabase"&lt;/span&gt;&lt;span style="color:#000000;"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;span style="font-size:85%;color:green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objConfig.Add(&lt;span style="color:#a31515;"&gt;"enablePasswordRetrieval"&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;"false"&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objConfig.Add(&lt;span style="color:#a31515;"&gt;"enablePasswordReset"&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;"true"&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objConfig.Add(&lt;span style="color:#a31515;"&gt;"requiresQuestionAndAnswer"&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;"true"&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objConfig.Add(&lt;span style="color:#a31515;"&gt;"applicationName"&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;"MyApp"&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objConfig.Add(&lt;span style="color:#a31515;"&gt;"requiresUniqueEmail"&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;"true"&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objConfig.Add(&lt;span style="color:#a31515;"&gt;"maxInvalidPasswordAttempts"&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;"5"&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objConfig.Add(&lt;span style="color:#a31515;"&gt;"passwordAttemptWindow"&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;"10"&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objConfig.Add(&lt;span style="color:#a31515;"&gt;"commandTimeout"&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;"30"&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objConfig.Add(&lt;span style="color:#a31515;"&gt;"passwordFormat"&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;"Hashed"&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objConfig.Add(&lt;span style="color:#a31515;"&gt;"name"&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;"AspNetSqlMembershipProvider"&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objConfig.Add(&lt;span style="color:#a31515;"&gt;"minRequiredPasswordLength"&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;"8"&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objConfig.Add(&lt;span style="color:#a31515;"&gt;"minRequiredNonalphanumericCharacters"&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;"2"&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objConfig.Add(&lt;span style="color:#a31515;"&gt;"passwordStrengthRegularExpression"&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;"(?=^.{8,25}$)(?=.*\\d)(?=.*[a-z])(?=.*[A-Z])(?=.*[!@#$%^&amp;amp;*()_+}{\\":;'?/&amp;gt;.&amp;lt;,])(?!.*\\s).*$"&lt;/span&gt;));&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#2b91af;"&gt;SqlMembershipProvider&lt;/span&gt; objSqlMembershipProvider = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;SqlMembershipProvider&lt;/span&gt;();&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objSqlMembershipProvider.Initialize(objConfig[&lt;span style="color:#a31515;"&gt;"name"&lt;/span&gt;], objConfig);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#2b91af;"&gt;MembershipProviderCollection&lt;/span&gt; colMembershipProviders = &lt;span style="color:blue;"&gt;new&lt;/span&gt; &lt;span style="color:#2b91af;"&gt;MembershipProviderCollection&lt;/span&gt;();&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;colMembershipProviders.Add(objSqlMembershipProvider);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;colMembershipProviders.SetReadOnly();&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#2b91af;"&gt;BindingFlags&lt;/span&gt; enuBindingFlags = &lt;span style="color:#2b91af;"&gt;BindingFlags&lt;/span&gt;.NonPublic | &lt;span style="color:#2b91af;"&gt;BindingFlags&lt;/span&gt;.Static;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#2b91af;"&gt;Type&lt;/span&gt; objMembershipType = &lt;span style="color:blue;"&gt;typeof&lt;/span&gt;(&lt;span style="color:#2b91af;"&gt;Membership&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objMembershipType.GetField(&lt;span style="color:#a31515;"&gt;"s_Initialized"&lt;/span&gt;, enuBindingFlags).SetValue(&lt;span style="color:blue;"&gt;null&lt;/span&gt;, &lt;span style="color:blue;"&gt;true&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objMembershipType.GetField(&lt;span style="color:#a31515;"&gt;"s_InitializeException"&lt;/span&gt;, enuBindingFlags).SetValue(&lt;span style="color:blue;"&gt;null&lt;/span&gt;, &lt;span style="color:blue;"&gt;null&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objMembershipType.GetField(&lt;span style="color:#a31515;"&gt;"s_HashAlgorithmType"&lt;/span&gt;, enuBindingFlags).SetValue(&lt;span style="color:blue;"&gt;null&lt;/span&gt;, &lt;span style="color:#a31515;"&gt;"SHA1"&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objMembershipType.GetField(&lt;span style="color:#a31515;"&gt;"s_HashAlgorithmFromConfig"&lt;/span&gt;, enuBindingFlags).SetValue(&lt;span style="color:blue;"&gt;null&lt;/span&gt;, &lt;span style="color:blue;"&gt;false&lt;/span&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objMembershipType.GetField(&lt;span style="color:#a31515;"&gt;"s_UserIsOnlineTimeWindow"&lt;/span&gt;, enuBindingFlags).SetValue(&lt;span style="color:blue;"&gt;null&lt;/span&gt;, 15);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objMembershipType.GetField(&lt;span style="color:#a31515;"&gt;"s_Provider"&lt;/span&gt;, enuBindingFlags).SetValue(&lt;span style="color:blue;"&gt;null&lt;/span&gt;, objSqlMembershipProvider);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objMembershipType.GetField(&lt;span style="color:#a31515;"&gt;"s_Providers"&lt;/span&gt;, enuBindingFlags).SetValue(&lt;span style="color:blue;"&gt;null&lt;/span&gt;, colMembershipProviders);&lt;/span&gt;&lt;/p&gt;&lt;p&gt;This code assumes you have the following statements in your cs file: &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; System.Web.Security;&lt;/span&gt;&lt;span style="font-size:85%;color:green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; System.Collections.Specialized;&lt;/span&gt;&lt;span style="font-size:85%;color:green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; System.Reflection;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Then you can use Membership functions like Membership.ValidateUser, Membership.GetUser and Membership.CreateUser.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-408688029265829691?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/408688029265829691/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=408688029265829691' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/408688029265829691'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/408688029265829691'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2008/11/how-to-configure-membership-provider.html' title='How to configure a membership provider programmatically'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-4161470544556036527</id><published>2008-11-17T08:17:00.004Z</published><updated>2008-11-28T09:07:03.283Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>How to create a connection string programmatically</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;The code snippet for creating a connection string programmatically in .NET C# follows:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:85%;color:green;"&gt;/*&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;color:green;"&gt;// Opening the configuration file for a DLL, i.e. %ProgramFiles%\Memba\Velodoc\Management Console\Memba.Console.dll.config&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;color:green;"&gt;ExeConfigurationFileMap objExeConfigurationFileMap = new ExeConfigurationFileMap();&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;color:green;"&gt;objExeConfigurationFileMap.ExeConfigFilename = System.Reflection.Assembly.GetExecutingAssembly().Location + ".config";&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;color:green;"&gt;Configuration objExeConfiguration = ConfigurationManager.OpenMappedExeConfiguration(objExeConfigurationFileMap, ConfigurationUserLevel.None);&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;color:green;"&gt;*/&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:85%;color:green;"&gt;// Opening the configuration file for an executable, i.e. C:\Windows\System32\mmc.config&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#2b91af;"&gt;Configuration&lt;/span&gt; objExeConfiguration = &lt;span style="color:#2b91af;"&gt;ConfigurationManager&lt;/span&gt;.OpenExeConfiguration(&lt;span style="color:#2b91af;"&gt;ConfigurationUserLevel&lt;/span&gt;.None);&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:85%;color:green;"&gt;// Creating a connection string element from the connection string in web.config&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#2b91af;"&gt;ConnectionStringSettings&lt;/span&gt; objConnectionStringSettings = &lt;span style="color:blue;"&gt;new&lt;/span&gt;&lt;br /&gt;&lt;span style="color:#2b91af;"&gt;ConnectionStringSettings&lt;/span&gt;(&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#a31515;"&gt;"MyDatabase"&lt;/span&gt;,&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#a31515;"&gt;"Data Source=.;Initial Catalog=MyDatabase;Integrated Security=True;Connect Timeout=30"&lt;/span&gt;,&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;color:#a31515;"&gt;"System.Data.SqlClient"&lt;/span&gt;&lt;span style="font-size:85%;color:green;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:85%;color:green;"&gt;// Get the connection strings section&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#2b91af;"&gt;ConnectionStringsSection&lt;/span&gt; objConnectionStringsSection = objExeConfiguration.ConnectionStrings;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:85%;color:green;"&gt;// Add the new element&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objConnectionStringsSection.ConnectionStrings.Clear();&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objConnectionStringsSection.ConnectionStrings.Add(objConnectionStringSettings);&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:85%;color:green;"&gt;// Save the configuration file&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;objExeConfiguration.Save(&lt;span style="color:#2b91af;"&gt;ConfigurationSaveMode&lt;/span&gt;.Modified);&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:85%;color:green;"&gt;// Refresh and check&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#2b91af;"&gt;ConfigurationManager&lt;/span&gt;.RefreshSection(objConnectionStringsSection.SectionInformation.Name); &lt;/span&gt;&lt;span style="font-size:85%;color:green;"&gt;// IMPORTANT!&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#2b91af;"&gt;Debug&lt;/span&gt;.Assert(&lt;span style="color:#2b91af;"&gt;ConfigurationManager&lt;/span&gt;.ConnectionStrings.Count == 1);&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#2b91af;"&gt;Debug&lt;/span&gt;.Assert(&lt;span style="color:#2b91af;"&gt;ConfigurationManager&lt;/span&gt;.ConnectionStrings[0].Name == objConnectionStringSettings.Name);&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#2b91af;"&gt;Debug&lt;/span&gt;.Assert(&lt;span style="color:#2b91af;"&gt;ConfigurationManager&lt;/span&gt;.ConnectionStrings[0].ConnectionString == objConnectionStringSettings.ConnectionString);&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#2b91af;"&gt;Debug&lt;/span&gt;.Assert(&lt;span style="color:#2b91af;"&gt;ConfigurationManager&lt;/span&gt;.ConnectionStrings[0].ProviderName == objConnectionStringSettings.ProviderName);&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-size:85%;"&gt;Note that this code assumes you have the following statements in your .cs file:&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; System.Configuration;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:blue;"&gt;using&lt;/span&gt; System.Diagnostics;&lt;/span&gt;&lt;span style="font-size:85%;color:green;"&gt;&lt;/p&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-4161470544556036527?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/4161470544556036527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=4161470544556036527' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/4161470544556036527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/4161470544556036527'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2008/11/how-to-create-connection-string.html' title='How to create a connection string programmatically'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-670737656196634513</id><published>2008-11-14T10:24:00.002Z</published><updated>2008-11-28T09:07:27.443Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Sharing data between processes</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;&lt;a href="http://www.velodoc.com/download"&gt;Memba Velodoc Outlook Add-In&lt;/a&gt; lets you send large files from Outlook. The first component is a VSTO add-in running in the Outlook process, which provides a user interface like WinZip and WinRar to add large files to a transfer package and hyperlinks in the email body to download these files. The second component is an executable called transfer controller which actually uploads this package to a file transfer server in the background. The transfer controller provides a user interface to monitor the progress of transfers and pause, resume and cancel transfers. A plug-in architecture makes the transfer controller compatible with several file transfer protocols and server platforms including FTP. The VSTO add-in and the transfer controller communicate together via .NET remoting which is the standard inter-process communication (IPC) mechanism in .NET.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;In all builds including and prior to build #081107 of release 1.0, the TCP port opened for .NET remoting on the transfer controller is hard coded. This has proved to be an issue when using windows fast user switching and terminal services sessions because each user needs his/her own instance of the transfer controller to access the user interface and they are all competing to listen on the same port.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;First, ensuring one and only one instance of the transfer controller process per user session is achieved using a local mutex. Note that &lt;a href="http://odetocode.com/Blogs/scott/archive/2004/08/20/401.aspx"&gt;using a global mutex is a well-known design pattern to ensure one instance of a process per machine&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Second, we needed a way to configure .NET remoting in the transfer controller to listen on the first available port and notify the VSTO add-in to communicate on the same port. Actually the problem is even more complicated as we cannot tell which between the VSTO add-in and the transfer controller is started first because normally the VSTO add-in starts the transfer controller, but then Outlook might be closed and re-opened while the transfer controller is already loaded. Accordingly, we needed a way to scan for an available TCP port, cache it and share it between processes. We could have used the current user registry, but since the user registry is persistent there is a risk to lock the processes into a port which is no more available. So we needed to ensure that even in the case of a crash the port used would not persist once the add-in processes had exited. We have opted for shared memory.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;In Windows, &lt;a href="http://msdn.microsoft.com/en-us/library/ms810613.aspx"&gt;shared memory is a special case of memory mapped files&lt;/a&gt;, where the file mapping object accesses memory backed by the system paging file. However, the lifetime of this memory ends when the last process connected to the shared memory object closes connection or the application exits, so there is no data persistence. If an application creates shared memory, fills it with data and exits, the data is lost and this is exactly what we need.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Memory mapped files are implemented using the following Win32 kernel APIs: &lt;a href="http://www.pinvoke.net/default.aspx/kernel32/CreateFileMapping.html"&gt;CreateFileMapping&lt;/a&gt;, &lt;a href="http://www.pinvoke.net/default.aspx/kernel32/OpenFileMapping.html"&gt;OpenFileMapping&lt;/a&gt;, &lt;a href="http://www.pinvoke.net/default.aspx/kernel32/MapViewOfFile.html"&gt;MapViewOfFile&lt;/a&gt;, &lt;a href="http://www.pinvoke.net/default.aspx/kernel32/MapViewOfFileEx.html"&gt;MapViewOfFileEx&lt;/a&gt;, &lt;a href="http://www.pinvoke.net/default.aspx/kernel32/UnmapViewOfFile.html"&gt;UnmapViewOfFile&lt;/a&gt;, &lt;a href="http://www.pinvoke.net/default.aspx/kernel32/FlushViewOfFile.html"&gt;FlushViewOfFile&lt;/a&gt; and &lt;a href="http://www.pinvoke.net/default.aspx/kernel32/CloseHandle.html"&gt;CloseHandle&lt;/a&gt;. Note that the naming convention used in &lt;a href="http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx"&gt;CreateFileMapping&lt;/a&gt; and &lt;a href="http://msdn.microsoft.com/en-us/library/aa366791(VS.85).aspx"&gt;OpenFileMapping&lt;/a&gt; follows the convention of mutexes where a name prefixed with Global\ creates the object in the global address space (machine) and a name prefixed with Local\ or not prefixed at all creates the object in the local address space (user session).&lt;br /&gt;&lt;/p&gt;&lt;p&gt;This will feature in the next build of the &lt;a href="http://www.codeplex.com/velodocaddin"&gt;Memba Velodoc Outlook Add-In&lt;/a&gt; due by the end of the year. In the meantime we provide here a &lt;a href="http://www.memba.com/download/081114.blog.zip"&gt;prototype in the form of a Visual Studio 2008 console application project&lt;/a&gt;. The first instance of the console application which you may launch should scan for an available TCP port, store it in shared memory and display it. All other instances should find that port in shared memory and display it. As a consequence, all instances of the console application should display the same shared TCP port. &lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-670737656196634513?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/670737656196634513/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=670737656196634513' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/670737656196634513'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/670737656196634513'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2008/11/sharing-data-between-processes.html' title='Sharing data between processes'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-5447220579370710330</id><published>2008-11-10T10:14:00.002Z</published><updated>2008-11-28T09:06:22.845Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='DOS'/><title type='text'>Starting batch files in the current directory</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;Our development projects include batch files to build, install and clean the project. Projects are shared with source control and developers and testers have each developed their own directory structures where they store projects on their computer. Accordingly it is important that these batches work whatever their location.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The magic DOS command which achieves just that is &lt;span style="font-family:Courier New;font-size:10;"&gt;&lt;strong&gt;cd /d %~dp0&lt;/strong&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;This command actually changes the current directory to the directory where the batch file is located.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-5447220579370710330?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/5447220579370710330/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=5447220579370710330' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/5447220579370710330'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/5447220579370710330'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2008/11/starting-batch-files-in-current.html' title='Starting batch files in the current directory'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-4335744389361025886</id><published>2008-10-02T11:30:00.002+01:00</published><updated>2008-11-28T09:05:44.913Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='C#'/><title type='text'>Debugging installer classes</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;There are many blog posts which describe clumsy workarounds to debug installer classes but certainly not the best way to achieve it.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;There are two scenarios:&lt;br /&gt;&lt;/p&gt;&lt;ol style="MARGIN-LEFT: 38pt"&gt;&lt;li&gt;You really need to debug your installer class in the msiexec.exe process, and you need to buy some time to be able to attach the Visual Studio debugger to this process (menu Debug -&amp;gt; Attach to Process… in Visual Studio). One way to buy time is to popup a message box to halt the execution of the install method while you are attaching your debugger to the process. For more information, see &lt;a href="http://msdn.microsoft.com/en-us/library/c6wf8e4z.aspx"&gt;http://msdn.microsoft.com/en-us/library/c6wf8e4z.aspx&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;div&gt;You can also conveniently run your installer class using the &lt;a href="http://msdn.microsoft.com/en-us/library/50614e95(VS.80).aspx"&gt;installer tool&lt;/a&gt; (InstallUtil.exe). If this scenario works for your debugging requirements:&lt;br /&gt;&lt;/div&gt;&lt;ol&gt;&lt;li&gt;Open the properties of the project containing your installer class (right-click the project in the solution explorer of Visual Studio and select contextual menu option Properties);&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Check the assembly name on the Application tab. In our example, the assembly name is "AssemblyName", and since our project is a class library the assembly is "AssemblyName.dll";&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Go to the Debug tab and in the Start Action, select Start external program and enter "C:\Windows\Microsoft.NET\Framework\v2.0.50727\InstallUtil.exe";&lt;br /&gt;&lt;/li&gt;&lt;li&gt;On the same tab, in the start Options, enter the following command line arguments: "AssemblyName.dll /LogToConsole=true" according to point b.&lt;br /&gt;Open your installer class in the code editor and at the top of the install method (assuming you are debugging the installation) add:&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:10;"&gt;&lt;span style="color:olive;"&gt;#if&lt;/span&gt; DEBUG&lt;br /&gt;&lt;span style="color:blue;"&gt;if&lt;/span&gt; (System.Diagnostics.&lt;span style="color:#2b91af;"&gt;Debugger&lt;/span&gt;.IsAttached)&lt;br /&gt;System.Diagnostics.&lt;span style="color:#2b91af;"&gt;Debugger&lt;/span&gt;.Break();&lt;br /&gt;&lt;span style="color:olive;"&gt;#endif&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Set your project as startup project, press F5 or start debugging in Visual Studio and the debugger will automatically stop on the Debugger.Break() statement. &lt;/li&gt;&lt;/ol&gt;&lt;/li&gt;&lt;/ol&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-4335744389361025886?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/4335744389361025886/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=4335744389361025886' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/4335744389361025886'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/4335744389361025886'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2008/10/debugging-installer-classes.html' title='Debugging installer classes'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-5893740470490491578</id><published>2008-07-28T11:56:00.002+01:00</published><updated>2008-11-28T09:05:17.978Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>ASP.NET Debugging Timeout</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;When you debug ASP.NET applications in IIS using Debug -&amp;gt; Attach To Process… and you keep the w3wp.exe process hanged on a code line for too long, it is automatically recycled and you lose your debugging session. To avoid that, go to the IIS Management Console, edit the application pool properties and set Ping Enabled = false.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-5893740470490491578?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/5893740470490491578/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=5893740470490491578' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/5893740470490491578'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/5893740470490491578'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2008/07/aspnet-debugging-timeout.html' title='ASP.NET Debugging Timeout'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-4618581127972497897</id><published>2008-07-04T10:59:00.007+01:00</published><updated>2008-11-28T09:07:55.950Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='ASP.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>ASP.NET projects deployed with Web Deployment Project 2005 do not load localized resources</title><content type='html'>&lt;p&gt;Scott Guthrie explains &lt;a href="http://weblogs.asp.net/scottgu/archive/2005/11/06/429723.aspx"&gt;how to use VS 2005 Web Deployment Project in his blog&lt;/a&gt;. But if you use global resources to localize your ASP.NET application and sign and version your web deployment assembly, these localized resources will not load. If you look at the fusion log, you will find an entry like follows:&lt;/p&gt;&lt;code&gt;Calling assembly : Memba.WebSite.XP, Version=1.1.0.0, Culture=neutral, PublicKeyToken=a4ae091aa8097a5a.&lt;br /&gt;===&lt;br /&gt;LOG: This bind starts in default load context.&lt;br /&gt;LOG: Using application configuration file: C:\inetpub\wwwroot\VelodocXP\web.config.&lt;br /&gt;LOG: Using host configuration file: C:\Windows\Microsoft.NET\Framework\v2.0.50727\Aspnet.config.&lt;br /&gt;LOG: Using machine configuration file from C:\Windows\Microsoft.NET\Framework\v2.0.50727\config\machine.config.&lt;br /&gt;LOG: Post-policy reference: Memba.WebSite.XP.resources, Version=0.0.0.0, Culture=fr, PublicKeyToken=a4ae091aa8097a5a&lt;br /&gt;LOG: The same bind was seen before, and was failed with hr = 0x80131040.&lt;br /&gt;ERR: Unrecoverable error occurred during pre-download check (hr = 0x80131040).&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;The problem comes from the fact that aspnet_merge.exe versions your satellite resource assemblies as "0.0.0.0" whatever the version number you set for your web deployment strong named assembly.&lt;br /&gt;&lt;p&gt;I have not found any way to version satellite assemblies according to the main assembly, but the following workaround works:&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Create an AssemblyInfo.cs class file in your App_Code directory;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Include the typical information including versioning information;&lt;/li&gt;&lt;li&gt;Add &lt;span style="font-family:Courier New;"&gt;[assembly: System.Resources.&lt;span style="COLOR: rgb(43,145,175)"&gt;SatelliteContractVersion&lt;/span&gt; (&lt;span style="COLOR: rgb(163,21,21)"&gt;"0.0.0.0"&lt;/span&gt;)]&lt;/span&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-4618581127972497897?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/4618581127972497897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=4618581127972497897' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/4618581127972497897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/4618581127972497897'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2008/07/aspnet-projects-deployed-with-web.html' title='ASP.NET projects deployed with Web Deployment Project 2005 do not load localized resources'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-1145386197084057581</id><published>2008-05-27T17:14:00.004+01:00</published><updated>2008-08-26T09:04:47.607+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Velodoc'/><title type='text'>Write about Velodoc, get a free license and a chance to win $100 cash</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;To celebrate the new releases of &lt;a href="http://www.velodoc.net/"&gt;Velodoc Enterprise Edition&lt;/a&gt;, &lt;a href="http://www.codeplex.com/velodocxp"&gt;Velodoc XP Edition&lt;/a&gt; and &lt;a href="http://www.codeplex.com/velodocaddin"&gt;Velodoc Outlook Add-In&lt;/a&gt; due in September, we will reward the best articles and blog posts written about Velodoc with a $100 cash payment to a Paypal account. The contest will run for the months of September, October and November 2008 and one article or blog post will be rewarded with the $100 cash prize each month. Better, all participants who have submitted a compliant article or blog post will get a full license serial number of Memba Velodoc Outlook Add-In worth $37 for free.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;How does it work?&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;div&gt;Write and publish a new 'How-to' article or blog post comprising (definition of a compliant blog post):&lt;br /&gt;&lt;/div&gt;&lt;ul&gt;&lt;li&gt;At least 250 words giving advice, tips or a tutorial on any Velodoc product in any language that we can translate with &lt;a href="http://www.google.com/translate_t"&gt;Google translation tools&lt;/a&gt;,&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;a screenshot of Memba Velodoc,&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;3 hyperlinks, respectively to &lt;a href="http://www.velodoc.com/"&gt;www.velodoc.com&lt;/a&gt;, &lt;a href="http://www.velodoc.net/"&gt;www.velodoc.net&lt;/a&gt;, and &lt;a href="http://www.memba.com/"&gt;www.memba.com&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;Submit a comment here with a link to your blog post and how to contact you if you are the winner.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;All participants commit to keep the blog post published for a year. Participation is limited to one original blog post per individual.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;We require at least 5 participating blog posts in a month to allocate the prize. Otherwise these blog posts will compete with the blog posts submitted on the following month. If this occurs in November, the contest will continue until we have 5 participating blog posts, so there should be a winner anyway.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Participating blog posts will be judged on (1) quality of content and (2) number of referrals sent to our web sites as reported by our traffic analysis tools.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The winning blog posts will be published here below.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;At the end of the contest, full licenses of Memba Velodoc Outlook Add-In will be made available to all participants who have submitted a compliant blog post.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;For any question, &lt;a href="http://www.velodoc.com/en/contact.htm"&gt;use our contact form&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Note that the process is completely transparent: all participating and winning blog posts will be available here as hyperlinks for anyone to read them.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;September winner:&lt;/strong&gt; &amp;lt;to be announced&amp;gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;strong&gt;October winner:&lt;/strong&gt; &amp;lt;to be announced&amp;gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;November&lt;/span&gt;&lt;strong&gt; winner:&lt;/strong&gt; &amp;lt;to be announced&amp;gt;&lt;br /&gt;&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-1145386197084057581?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/1145386197084057581/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=1145386197084057581' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/1145386197084057581'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/1145386197084057581'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2008/05/write-about-velodoc-get-free-license.html' title='Write about Velodoc, get a free license and a chance to win $100 cash'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-2716728499836506079</id><published>2008-05-13T09:36:00.004+01:00</published><updated>2008-11-28T09:04:34.497Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SMTP'/><category scheme='http://www.blogger.com/atom/ns#' term='Outlook'/><category scheme='http://www.blogger.com/atom/ns#' term='Velodoc'/><title type='text'>The Velodoc Outlook Add-In is being released</title><content type='html'>We are currently releasing the Outlook Add-In for Velodoc. We have posted a quick video tour on YouTube. This video demonstrates how to send large files to email contacts using Memba Velodoc Outlook Add-In and various file transfer server platforms including Velodoc servers, FTP servers, UNC File Shares, Microsoft BITS Servers and Amazon S3.&lt;br /&gt;&lt;br /&gt;&lt;object height="350" width="425"&gt;&lt;param name="movie" value="http://www.youtube.com/v/0c-qivirz8Q"&gt;&lt;br /&gt;   &lt;embed src="http://www.youtube.com/v/0c-qivirz8Q" type="application/x-shockwave-flash" width="425" height="350"&gt;&lt;/embed&gt;  &lt;/object&gt;&lt;br /&gt;&lt;br /&gt;You can also find the &lt;a href="http://silverlight.services.live.com/invoke/66737/VelodocAddIn/iframe.html"&gt;high-definition version of the video tour on Silverlight Streaming Services&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;Memba Velodoc Outlook Add-In is open-source and you can download the code from:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.codeplex.com/velodocaddin"&gt;Codeplex&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/velodocaddin/"&gt;Google code&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://sourceforge.net/projects/velodocaddin"&gt;Sourceforge.net&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-2716728499836506079?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/2716728499836506079/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=2716728499836506079' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/2716728499836506079'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/2716728499836506079'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2008/05/velodoc-outlook-add-in-is-being.html' title='The Velodoc Outlook Add-In is being released'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-3412280471847231791</id><published>2008-04-21T14:10:00.002+01:00</published><updated>2008-05-13T09:35:45.492+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='Office'/><title type='text'>Error 1316 when installing Office 2007 PIA’s</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;If you build a setup for an Office 2007 VSTO add-in following the steps described in &lt;a href="http://msdn2.microsoft.com/en-us/library/bb332051.aspx"&gt;Deploying Visual Studio 2005 Tools for Office Second Edition Solutions Using Windows Installer&lt;/a&gt;, your setup may report that the installation of the Office 2007 PIA's have failed. Looking at the log or installing o2007PIA.msi separately, you will get "Error 1316. Setup cannot read from file &amp;lt;tempdir&amp;gt;\PIARedist.msi. Check your connection to the network, or CD-ROM drive. For other potential solutions to this problem, see SETUP.CHM".&lt;br /&gt;&lt;/p&gt;&lt;p&gt;This occurs on fresh installs of Office 2007 with Microsoft Business Contact Manager and more generally, it seems to occur on any computer which has the Office 2007 PIA's installed using another installer than &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=59daebaa-bed4-4282-a28c-b864d8bfa513&amp;amp;displaylang=en"&gt;o2007pia.msi&lt;/a&gt;, which is the one Microsoft recommends using.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;There seems to be a workaround which is to rename o2007pia.msi into PIARedist.msi both in the file system where bootstrapper packages are stored and in the product.xml file as shown below:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&amp;lt;PackageFiles&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&amp;lt;PackageFile Name="PIARedist.msi"/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&amp;lt;PackageFile Name="ComponentCheck.exe"/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;&amp;lt;/PackageFiles&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;...&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&amp;lt;Command PackageFile="PIARedist.msi"&lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;Arguments=""&lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;EstimatedInstalledBytes="30000000"&lt;br /&gt;    &lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;EstimatedInstallSeconds="60"&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;You will need to rebuild your setup project. &lt;/p&gt;&lt;p&gt;Please let me know if this workaround does not work for you.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-3412280471847231791?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/3412280471847231791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=3412280471847231791' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/3412280471847231791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/3412280471847231791'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2008/04/error-1316-when-installing-office-2007.html' title='Error 1316 when installing Office 2007 PIA’s'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-1732329098580916842</id><published>2008-03-31T09:01:00.002+01:00</published><updated>2008-03-31T11:53:28.959+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SMTP'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='Office'/><title type='text'>Validating email notification HTML for Outlook 2007</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;Velodoc issues numerous email notifications. The presentation uses the latest CSS tags and sophisticated layered HTML. Everything worked fine in Outlook 2003 which uses Internet Explorer as the HTML rendering engine. Outlook 2007 and its Word 2007 rendering engine broke many little things.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Although it is definitely a step back in terms of HTML rendering capability for emails, everything is explained in &lt;a href='http://msdn2.microsoft.com/en-us/library/aa338201.aspx'&gt;Word 2007 HTML and CSS Rendering Capabilities in Outlook 2007&lt;/a&gt;. The article comes with a very &lt;a href='http://www.microsoft.com/downloads/details.aspx?FamilyId=0B764C08-0F86-431E-8BD5-EF0E9CE26A3A'&gt;handy tool to validate HTML and CSS in your development environment&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I have not been able to install the tool for Visual Studio 2005 SP1 on Windows Vista Ultimate x64 because I could not instantly find the registry keys described in the setup instructions, but it works perfectly with Dreamweaver 8 provided you replace "Dreamweaver MX 2004" by "Dreamweaver 8" in the default installation path.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-1732329098580916842?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/1732329098580916842/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=1732329098580916842' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/1732329098580916842'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/1732329098580916842'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2008/03/validating-email-notification-html-for.html' title='Validating email notification HTML for Outlook 2007'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-6034122412573980541</id><published>2008-03-31T08:46:00.002+01:00</published><updated>2008-03-31T11:54:00.646+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>FileNotFoundException in Visual Studio Setup Project</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;The &lt;a href='http://www.velodoc.com'&gt;Velodoc XP&lt;/a&gt; setup project would consistently fail on a specific Windows Server 2003 server of ours but not on other computers of our network. The complete issue is described at &lt;a href='http://www.codeplex.com/VelodocXP/WorkItem/View.aspx?WorkItemId=1005'&gt;http://www.codeplex.com/VelodocXP/WorkItem/View.aspx?WorkItemId=1005&lt;/a&gt;. The error message was:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Exception occurred while initializing the installation: System.IO.FileNotFoundException: Could not load file or assembly 'file:///C:\WINDOWS\system32\and' or one of its dependencies. The system cannot find the file specified.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Obviously, there is no such "C:\WINDOWS\system32\and" file in our application or on the system. MSI logs and fusion logs would not give any more information.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;We have been puzzled by this issue for quite some time. We have finally removed features from our setup one by one until we have been able to identify that a specific custom action was at the source of the problem.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;In the literature and samples that you will find regarding developing Visual Studio setup projects, custom action data is passed in the form /NAME = VALUE which works fine unless value contains a space.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The reference documentation at &lt;a href='http://msdn2.microsoft.com/en-us/library/2w2fhwzz.aspx'&gt;http://msdn2.microsoft.com/en-us/library/2w2fhwzz.aspx&lt;/a&gt; states that in setup custom actions, data should be passed as:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;/NAME = VALUE if not a directory and value has no space&lt;br/&gt;/NAME = "VALUE" if spaces are expected in a value which is not a directory&lt;br/&gt;/NAME = "VALUE\" if the expected value is a directory&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I wish we had not simply read how-to articles and sample code, but also the reference documentation.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-6034122412573980541?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/6034122412573980541/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=6034122412573980541' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/6034122412573980541'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/6034122412573980541'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2008/03/filenotfoundexception-in-visual-studio.html' title='FileNotFoundException in Visual Studio Setup Project'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-4728348384578775520</id><published>2008-03-17T11:30:00.002Z</published><updated>2008-03-31T11:54:50.853+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><category scheme='http://www.blogger.com/atom/ns#' term='WCF'/><title type='text'>Installing Visual Studio Extensions for WCF after an upgrade to .NET 3.0 Service Pack 1</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;Yesterday, I got stuck installing &lt;a href='http://www.microsoft.com/downloads/details.aspx?FamilyId=F54F5537-CC86-4BF5-AE44-F5A1E805680D&amp;amp;displaylang=en'&gt;Visual Studio 2005 extensions for .NET Framework 3.0 (WCF &amp;amp; WPF), November 2006 CTP&lt;/a&gt; after my computer had been upgraded to .NET Framework 3.0 Service Pack 1. The installation fails with a warning that a prerequisite, i.e. Microsoft .NET framework 3.0, is missing.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;A quick search on the Internet gave me the following trick which works:&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Add the following key and value to the registry aimed at luring the installer:&lt;br/&gt;[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{15095BF3-A3D7-4DDF-B193-3A496881E003}]&lt;br/&gt;"DisplayName"="Microsoft .NET Framework 3.0"&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Install vsextwfx.msi.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Remove the key above.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Source: &lt;a href='http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2550726&amp;amp;SiteID=1'&gt;http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2550726&amp;amp;SiteID=1&lt;/a&gt;.&lt;br/&gt;Thanks Erich.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-4728348384578775520?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/4728348384578775520/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=4728348384578775520' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/4728348384578775520'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/4728348384578775520'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2008/03/installing-visual-studio-extensions-for.html' title='Installing Visual Studio Extensions for WCF after an upgrade to .NET 3.0 Service Pack 1'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-8757341641535921600</id><published>2007-12-20T14:51:00.002Z</published><updated>2008-11-28T09:09:04.463Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Velodoc'/><title type='text'>New series of articles in relation to Velodoc XP Edition</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;We have released a series of articles on codeproject.com in relation to Velodoc XP Edition:&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/ajax/InfoBox.aspx"&gt;An information box control to display messages using Ajax&lt;/a&gt;,&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/ajax/progressreport.aspx"&gt;Using Ajax to display the progress of an ASP.NET server task&lt;/a&gt;,&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/ajax/ImageList.aspx"&gt;An Ajax image list control to manage lists of items displayed with icons&lt;/a&gt;,&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/ajax/MultiUpload.aspx"&gt;MultiUpload, a smarter file upload server control using Ajax&lt;/a&gt;,&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/KB/ajax/ProUpload.aspx"&gt;Professional file uploads with the MultiUpload and ImageList server controls&lt;/a&gt;.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Enjoy the reading.&lt;br /&gt;&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-8757341641535921600?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/8757341641535921600/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=8757341641535921600' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/8757341641535921600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/8757341641535921600'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/12/new-series-of-articles-in-relation-to.html' title='New series of articles in relation to Velodoc XP Edition'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-6979344667656926971</id><published>2007-11-30T09:35:00.002Z</published><updated>2008-11-28T09:08:44.207Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Velodoc'/><title type='text'>Velodoc XP Edition released as open-source</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;Customers have been asking us about building Velodoc functionality into their own .NET applications. This is now possible with Velodoc XP Edition which has been released as an open-source project and published on:&lt;br /&gt;&lt;/p&gt;&lt;ul style="MARGIN-LEFT: 38pt"&gt;&lt;li&gt;&lt;a href="http://www.codeplex.com/VelodocXP"&gt;http://www.codeplex.com/VelodocXP&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/velodocxp"&gt;http://code.google.com/p/velodocxp&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://velodocxp.sourceforge.net/"&gt;http://velodocxp.sourceforge.net&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Velodoc XP Edition includes:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;ASP.NET Ajax server controls, http modules and http handlers which provide file upload and download functionality;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;A sample application for sending and receiving large files;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;A comprehensive documentation kit.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;By releasing the core of the Velodoc platform as an open-source project, we expect to gather more customer intelligence and improve the software, so please provide feedback.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-6979344667656926971?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/6979344667656926971/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=6979344667656926971' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/6979344667656926971'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/6979344667656926971'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/11/velodoc-xp-edition-released-as-open.html' title='Velodoc XP Edition released as open-source'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-3291983684328122763</id><published>2007-10-23T08:10:00.001+01:00</published><updated>2007-10-23T08:10:34.185+01:00</updated><title type='text'>The Ajax Control Toolkit NoBot control and session state</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;You need to prevent hackers using robots to run dictionaries of user names and passwords against your login pages. The most common way to achieve that is the use of Captchas ("Completely Automated Public Turing test to tell Computers and Humans Apart"), which display an image with a code which you need to type in a text box. Captchas are often difficult to read and push away genuine users with disabilities. More elaborated Captchas include sound but they are not mainstream.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The &lt;a href='http://www.asp.net/AJAX/AjaxControlToolkit/Samples/NoBot/NoBot.aspx'&gt;NoBot control&lt;/a&gt; in the Microsoft Ajax Control Toolkit can be used for any type of request and in particular to protect the sign in function of a login page:&lt;br /&gt;&lt;/p&gt;&lt;ol style='margin-left: 38pt'&gt;&lt;li&gt;It makes sure too many requests (to sign in) are not issued from the same IP address;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It provides an automated challenge response mechanism to ensure the request (to sign in) is issued by the (login) page;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;It enforces a delay between the time the (login) page is displayed and the request (to sign in) is issued.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The benefit of the NoBot control is that this is transparent to the user, contrary to Captchas.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;You implement the NoBot control on your ASP.NET page as follows:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;&amp;lt;&lt;/span&gt;&lt;span style='color:#a31515'&gt;ajaxToolkit&lt;/span&gt;&lt;span style='color:blue'&gt;:&lt;/span&gt;&lt;span style='color:#a31515'&gt;NoBot&lt;/span&gt;&lt;br /&gt;					&lt;span style='color:red'&gt;ID&lt;/span&gt;&lt;span style='color:blue'&gt;="PageNoBot"&lt;/span&gt;&lt;br /&gt;					&lt;span style='color:red'&gt;runat&lt;/span&gt;&lt;span style='color:blue'&gt;="server"&lt;/span&gt;&lt;br /&gt;					&lt;span style='color:red'&gt;OnGenerateChallengeAndResponse&lt;/span&gt;&lt;span style='color:blue'&gt;="PageNoBot_GenerateChallengeAndResponse"&lt;/span&gt;&lt;br /&gt;					&lt;span style='color:red'&gt;ResponseMinimumDelaySeconds&lt;/span&gt;&lt;span style='color:blue'&gt;="3"&lt;/span&gt;&lt;br /&gt;					&lt;span style='color:red'&gt;CutoffMaximumInstances&lt;/span&gt;&lt;span style='color:blue'&gt;="5"&lt;/span&gt;&lt;br /&gt;					&lt;span style='color:red'&gt;CutoffWindowSeconds&lt;/span&gt;&lt;span style='color:blue'&gt;="60"&lt;/span&gt;&lt;br /&gt;					&lt;span style='color:blue'&gt;/&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;You implement the OnGenerateChallengeAndResponse event handler in code as follows:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;protected&lt;/span&gt;&lt;br /&gt;					&lt;span style='color:blue'&gt;void&lt;/span&gt; PageNoBot_GenerateChallengeAndResponse(&lt;span style='color:blue'&gt;object&lt;/span&gt; sender, AjaxControlToolkit.&lt;span style='color:#2b91af'&gt;NoBotEventArgs&lt;/span&gt; e)&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;{&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;br /&gt;					&lt;span style='color:#2b91af'&gt;Random&lt;/span&gt; r = &lt;span style='color:blue'&gt;new&lt;/span&gt;&lt;br /&gt;					&lt;span style='color:#2b91af'&gt;Random&lt;/span&gt;();&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;br /&gt;					&lt;span style='color:blue'&gt;int&lt;/span&gt; iFirst = r.Next(100);&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;br /&gt;					&lt;span style='color:blue'&gt;int&lt;/span&gt; iSecond = r.Next(100);&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;    e.ChallengeScript = &lt;span style='color:#2b91af'&gt;String&lt;/span&gt;.Format(&lt;span style='color:#a31515'&gt;"eval('{0}+{1}')"&lt;/span&gt;, iFirst, iSecond);&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;    e.RequiredResponse = &lt;span style='color:#2b91af'&gt;Convert&lt;/span&gt;.ToString(iFirst + iSecond);&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Then the documentation tells you to implement the click event handler of the sign in button as follows:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;if&lt;/span&gt; (!PageNoBot.IsValid()) {&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;br /&gt;					&lt;span style='color:green'&gt;//Display a message that a robot has been detected and the request cannot be processed&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;else&lt;/span&gt; {&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;br /&gt;					&lt;span style='color:green'&gt;//Process the postback event&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;On most sites users are redirected to the login page when sessions time out. Because the NoBot control stores the calculation in session state and session state is reset in this case, the calculation challenge response would fail teh next time the user logs in unless he/she refreshes the page.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The following solves the problem from the user perspective, but it also opens the door to hackers:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:10pt'&gt;&lt;span style='color:blue'&gt;if&lt;/span&gt; ((!Page.Session.IsNewSession) &amp;amp;&amp;amp; (!PageNoBot.IsValid()))&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Apart from redesigning the NoBot control, not to use session state but to use the context cache instead, I have not found a really good solution to solve this issue.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-3291983684328122763?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/3291983684328122763/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=3291983684328122763' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/3291983684328122763'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/3291983684328122763'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/10/ajax-control-toolkit-nobot-control-and.html' title='The Ajax Control Toolkit NoBot control and session state'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-7110597774302499679</id><published>2007-09-12T12:27:00.001+01:00</published><updated>2007-09-12T13:50:31.087+01:00</updated><title type='text'>Nesting the Ajax Control Toolkit Accordion control and the ASP.NET Repeater control</title><content type='html'>&lt;h4&gt;Requirements&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;Install ASP.NET Ajax extensions 1.0.&lt;/p&gt;&lt;br /&gt;&lt;h4&gt;The ASP.NET page&lt;/h4&gt;&lt;br /&gt;&lt;p&gt;Create an ASP.NET Ajax web site (see ASP.NET Ajax extensions) and reference the Ajax Control Toolkit in your project.&lt;/p&gt;&lt;br /&gt;&lt;p&gt;Add the following statement at the top of your web page:&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;%@ Import Namespace=&amp;quot;System.Collections.Generic&amp;quot; %&amp;gt; &lt;/pre&gt;&lt;br /&gt;&lt;p&gt;Then insert the following code between the form tags of your web page.&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;&amp;lt;asp:ScriptManager ID=&amp;quot;ScriptManager&amp;quot; runat=&amp;quot;server&amp;quot; &amp;gt;&amp;lt;/asp:ScriptManager&amp;gt;&lt;br /&gt;&amp;lt;ajaxToolkit:Accordion ID=&amp;quot;Accordion1&amp;quot; runat=&amp;quot;server&amp;quot; SelectedIndex=&amp;quot;0&amp;quot;&lt;br /&gt;  FadeTransitions=&amp;quot;true&amp;quot; FramesPerSecond=&amp;quot;40&amp;quot; TransitionDuration=&amp;quot;250&amp;quot;&lt;br /&gt;  AutoSize=&amp;quot;None&amp;quot; &amp;gt;&lt;br /&gt;  &amp;lt;Panes&amp;gt;&amp;lt;/Panes&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;HeaderTemplate&amp;gt;&lt;br /&gt;&amp;lt;div style=&amp;quot;color:white;background-color:blue;cursor:pointer;&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;%# ((KeyValuePair&amp;lt;String, List&amp;lt;File&amp;gt;&amp;gt;)(Container.DataItem)).Key %&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;  &amp;lt;/HeaderTemplate&amp;gt;&lt;br /&gt;&lt;br /&gt;  &amp;lt;ContentTemplate&amp;gt;&lt;br /&gt;    &amp;lt;asp:repeater id=&amp;quot;child&amp;quot; datasource='&amp;lt;%# (List&amp;lt;File&amp;gt;)(((KeyValuePair&amp;lt;String, List&amp;lt;File&amp;gt;&amp;gt;)(Container.DataItem)).Value) %&amp;gt;' runat=&amp;quot;server&amp;quot;&amp;gt;&lt;br /&gt;&lt;br /&gt;      &amp;lt;HeaderTemplate&amp;gt;&lt;br /&gt;&amp;lt;table border=&amp;quot;0&amp;quot; cellpadding=&amp;quot;0&amp;quot; cellspacing=&amp;quot;5&amp;quot; style=&amp;quot;width:100%&amp;quot;&amp;gt;&lt;br /&gt;&amp;lt;thead&amp;gt;&amp;lt;tr&amp;gt;&lt;br /&gt;&amp;lt;th&amp;gt;Id&amp;lt;/th&amp;gt;&amp;lt;th&amp;gt;Name&amp;lt;/th&amp;gt;&lt;br /&gt;&amp;lt;th&amp;gt;Description&amp;lt;/th&amp;gt;&lt;br /&gt;&amp;lt;th&amp;gt;Date&amp;lt;/th&amp;gt;&lt;br /&gt;&amp;lt;/tr&amp;gt;&amp;lt;/thead&amp;gt;&lt;br /&gt;&amp;lt;tbody&amp;gt;&lt;br /&gt;      &amp;lt;/HeaderTemplate&amp;gt;&lt;br /&gt;&lt;br /&gt;      &amp;lt;ItemTemplate&amp;gt;&lt;br /&gt;&amp;lt;tr&amp;gt;&lt;br /&gt;&amp;lt;td&amp;gt;&amp;lt;%# ((File)(Container.DataItem)).id.ToString() %&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;&amp;lt;td&amp;gt;&amp;lt;%# ((File)(Container.DataItem)).Name %&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;&amp;lt;td&amp;gt;&amp;lt;%# ((File)(Container.DataItem)).Description %&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;&amp;lt;td&amp;gt;&amp;lt;%# ((File)(Container.DataItem)).Date.ToString() %&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;&amp;lt;/tr&amp;gt;&lt;br /&gt;      &amp;lt;/ItemTemplate&amp;gt;&lt;br /&gt;&lt;br /&gt;      &amp;lt;FooterTemplate&amp;gt;&lt;br /&gt;&amp;lt;/tbody&amp;gt;&lt;br /&gt;&amp;lt;/table&amp;gt;&lt;br /&gt;      &amp;lt;/FooterTemplate&amp;gt;&lt;br /&gt;&lt;br /&gt;    &amp;lt;/asp:repeater&amp;gt;&lt;br /&gt;  &amp;lt;/ContentTemplate&amp;gt;&lt;br /&gt;&amp;lt;/ajaxToolkit:Accordion&amp;gt;&lt;/pre&gt;&lt;br /&gt;&lt;h4&gt;The code-behind file &lt;/h4&gt;&lt;br /&gt;&lt;p&gt;Add the following in the code-behind file of your web page&lt;/p&gt;&lt;br /&gt;&lt;pre&gt;protected class File&lt;br /&gt;{&lt;br /&gt;  public Guid id;&lt;br /&gt;  public string Name;&lt;br /&gt;  public string Description; &lt;br /&gt;  public DateTime Date;&lt;br /&gt;  public File()&lt;br /&gt;  {&lt;br /&gt;    id = Guid.NewGuid();&lt;br /&gt;    Date = DateTime.Now;&lt;br /&gt;  }&lt;br /&gt;} &lt;/pre&gt;&lt;br /&gt;&lt;pre&gt;protected void Page_Load(object sender, EventArgs e)&lt;br /&gt;{&lt;br /&gt;  if (!IsPostBack)&lt;br /&gt;  {&lt;br /&gt;    const string C = &amp;quot;Category {0}&amp;quot;;&lt;br /&gt;    const string N = &amp;quot;File {0}&amp;quot;;&lt;br /&gt;    const string D = &amp;quot;Description {0}&amp;quot;;&lt;br /&gt;    Dictionary&amp;lt;String, List&amp;lt;File&amp;gt;&amp;gt; dicCategories = new Dictionary&amp;lt;String, List&amp;lt;File&amp;gt;&amp;gt;();&lt;br /&gt;    for (int i = 0; i &amp;lt; 5; i++)&lt;br /&gt;    {&lt;br /&gt;      List&amp;lt;File&amp;gt; objList = new List&amp;lt;File&amp;gt;();&lt;br /&gt;      for (int j = 0; j &amp;lt; 10; j++)&lt;br /&gt;      {&lt;br /&gt;        File objFile = new File();&lt;br /&gt;        objFile.Name = String.Format(N, j);&lt;br /&gt;        objFile.Description = String.Format(D, j);&lt;br /&gt;        objList.Add(objFile);&lt;br /&gt;      }&lt;br /&gt;      dicCategories.Add(String.Format(C, i), objList);&lt;br /&gt;    }&lt;br /&gt;    Accordion1.DataSource = dicCategories;&lt;br /&gt;    Accordion1.DataBind();&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-7110597774302499679?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/7110597774302499679/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=7110597774302499679' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/7110597774302499679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/7110597774302499679'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/09/nesting-ajax-control-toolkit-accordion.html' title='Nesting the Ajax Control Toolkit Accordion control and the ASP.NET Repeater control'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-7994086045330440465</id><published>2007-08-31T16:14:00.001+01:00</published><updated>2007-08-31T16:14:01.519+01:00</updated><title type='text'>Getting Velodoc notifications out of junk email folders</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;Some Velodoc users have complained that they did not receive our email notifications.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;We have looked into our application logs and these notifications have definitely been sent. Looking more closely at our SMTP server logs, we have found some entries similar to the following:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style='font-family:Courier New; font-size:9pt'&gt;2007-08-28 09:07:16 65.55.245.8 OutboundConnectionResponse SMTPSVC1 SV1 - 25 - - 550+Your+e-mail+was+rejected+for+policy+reasons+on+this+gateway.++Reasons+for+rejection+may+be+related+to+content+with+spam-like+characteristics+or+IP/domain+reputation+problems.++If+you+are+not+an+e-mail/network+admin+please+contact+your+E-mail/Internet+Service+Provider+for+help.++For+e-mail+delivery+information,+please+go+to+http://postmaster.live.com 0 0 355 0 578 SMTP - - - -&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;I have confirmed myself that notifications sent to Live Hotmail addresses were not received, even in the junk e-mail folder.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Although I was pretty sure about the result, I have checked that Velodoc.net was not recorded in any spam database, using &lt;a href='http://www.dnsstuff.com/tools/ip4r.ch?ip=velodoc.net'&gt;http://www.dnsstuff.com/tools/ip4r.ch?ip=velodoc.net&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Going to &lt;a href='http://postmaster.live.com'&gt;http://postmaster.live.com&lt;/a&gt; as suggested, I have read about SPF and Sender ID. I already knew about it, but our DNS Servers have been hosted by Network Solutions and they do not support SPF records. They know their stuff, don't they? I have even contacted their support team and I have been told that they get little demand for it.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Enquiring further, we have realized that more and more e-mail servers implement &lt;a href='http://www.microsoft.com/senderid'&gt;SPF/Sender ID&lt;/a&gt;. Some are now considering &lt;a href='http://antispam.yahoo.com/domainkeys'&gt;DKIM/DomainKeys&lt;/a&gt; to sign emails. So we have taken the decision to move our DNS to &lt;a href='http://www.dnsmadeeasy.com'&gt;DNS Made Easy&lt;/a&gt; and to add SPF records to our domains. Note that we could have used &lt;a href='http://www.ultradns.com'&gt;UltraDNS&lt;/a&gt; or &lt;a href='http://www.easydns.com/'&gt;EasyDNS&lt;/a&gt;, which offer similar services.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;We have used &lt;a href='http://www.dnsreport.com'&gt;http://www.dnsreport.com&lt;/a&gt; to identify other DNS issues. We were only missing a PTR record pointing to mail.velodoc.net. Because each of our web servers has its own SMTP server, we have changed the MX record to &lt;a href='http://www.velodoc.net'&gt;www.velodoc.net&lt;/a&gt; which already has a PTR record and changed the HELO greeting of the SMTP servers to display the correct fully qualified domain name. Live Hotmail users now receive our email notifications.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;In the near future we will be looking at DomainKeys, but contrary to Sender ID, DomainKeys have an impact on the infrastructure because they require that we change our SMTP Servers. If you have some experience with DKIM/DomainKeys and can recommend SMTP servers that implement email authentication, please leave a comment.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-7994086045330440465?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/7994086045330440465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=7994086045330440465' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/7994086045330440465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/7994086045330440465'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/08/getting-velodoc-notifications-out-of.html' title='Getting Velodoc notifications out of junk email folders'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-4920534232545833658</id><published>2007-08-29T10:29:00.001+01:00</published><updated>2007-08-29T10:29:00.960+01:00</updated><title type='text'>Turning the Velodoc Flash applet into a Yahoo widget</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;Yahoo widget documentation is available at &lt;a href='http://widgets.yahoo.com/workshop/'&gt;http://widgets.yahoo.com/workshop/&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Yahoo widgets cannot host the browser to display Flash applets. All Yahoo widgets based on Flash require the use of a third party component called WebBrowser4Widgets available at &lt;a href='http://www.centraltopic.com'&gt;http://www.centraltopic.com&lt;/a&gt;. Installing a Yahoo widget which uses this component is a very poor user experience. Several security warnings are displayed, which are too many reasons not to install the widget. Check samples at &lt;a href='http://widgets.yahoo.com/gallery/?author=14327'&gt;http://widgets.yahoo.com/gallery/?author=14327&lt;/a&gt;&lt;br /&gt;			&lt;/p&gt;&lt;p&gt;For this reason, we have postponed the packaging of the &lt;a href='http://www.velodoc.net'&gt;Velodoc&lt;/a&gt; applet as a Yahoo widget and wait until Yahoo widget implements a native mechanism to host Flash applets. Considering the success of Video sites like YouTube, I cannot think of any reason why they should not do it very soon.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-4920534232545833658?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/4920534232545833658/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=4920534232545833658' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/4920534232545833658'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/4920534232545833658'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/08/turning-velodoc-flash-applet-into-yahoo.html' title='Turning the Velodoc Flash applet into a Yahoo widget'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-10852163905619110</id><published>2007-08-21T08:33:00.001+01:00</published><updated>2007-08-21T08:45:01.720+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>Adobe Captivate or Techsmith Camtasia?</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;Although most of my friends seem to prefer &lt;a href="http://www.techsmith.com/"&gt;Camtasia&lt;/a&gt;, I have been a long-time fan of RoboDemo, now &lt;a href="http://www.adobe.com/products/captivate"&gt;Captivate&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The main difference between the two products is:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Camtasia records a full-motion video;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Captivate records still images, keyboard strokes and mouse movements which it assembles into a video;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The two approaches have their own strengths and weaknesses:&lt;br /&gt;&lt;/p&gt;&lt;ul style="MARGIN-LEFT: 38pt"&gt;&lt;li&gt;Camtasia is better at recording and displaying scrolling panes, progress bars and drag-and-drop operations;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Captivate gives a lot more control on the output. In fact, Captivate produces not only demonstrations but also true e-learning content.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The new Captivate 3.0 closes the gap and introduces full-motion recording, not in replacement but in addition to still images. Captivate is clever enough to trigger the full-motion recording when it detects a scrolling pane or a drag-and-drop. Anyway you can trigger it manually anytime.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;In my opinion, Captivate 3.0 is now far superior to Camtasia on all grounds except price. The Captivate product remains significantly more expansive but it is now justified.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-10852163905619110?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/10852163905619110/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=10852163905619110' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/10852163905619110'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/10852163905619110'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/08/adobe-captivate-or-techsmith-camtasia.html' title='Adobe Captivate or Techsmith Camtasia?'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-3508345111251642237</id><published>2007-08-17T16:48:00.001+01:00</published><updated>2007-08-20T10:06:52.001+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Velodoc'/><category scheme='http://www.blogger.com/atom/ns#' term='Vista'/><category scheme='http://www.blogger.com/atom/ns#' term='Flash'/><title type='text'>Turning the Velodoc Flash applet into a Vista Sidebar gadget</title><content type='html'>&lt;span xmlns=""&gt;&lt;h4&gt;Documentation&lt;/h4&gt;&lt;p&gt;Step-by-step instructions on how to develop a sidebar gadget are available at:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://microsoftgadgets.com/Sidebar/DevelopmentOverview.aspx"&gt;http://microsoftgadgets.com/Sidebar/DevelopmentOverview.aspx&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://microsoftgadgets.com/Build/SidebarTutorial.zip"&gt;http://microsoftgadgets.com/Build/SidebarTutorial.zip&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn2.microsoft.com/en-us/library/ms723694.aspx"&gt;http://msdn2.microsoft.com/en-us/library/ms723694.aspx&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/msdnmag/issues/07/08/sidebar/default.aspx"&gt;http://msdn.microsoft.com/msdnmag/issues/07/08/sidebar/default.aspx&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Reference documentation is available at &lt;a href="http://msdn2.microsoft.com/en-us/library/bb508511.aspx"&gt;http://msdn2.microsoft.com/en-us/library/bb508511.aspx&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;Implementation&lt;/h4&gt;&lt;p&gt;I am always trying to start this type of RAD development from an existing example. The sample that you build in &lt;a href="http://microsoftgadgets.com/Sidebar/DevelopmentOverview.aspx"&gt;http://microsoftgadgets.com/Sidebar/DevelopmentOverview.aspx&lt;/a&gt; is a good starting point.&lt;/p&gt;&lt;p&gt;In our final gadget, the html is simply a div which is filled by Javascript code when the gadget loads:&lt;/p&gt;&lt;ul style="MARGIN-LEFT: 38pt"&gt;&lt;li&gt;The Javascript event handlers are hooked as described in &lt;a href="http://msdn.microsoft.com/msdnmag/issues/07/08/sidebar/default.aspx"&gt;http://msdn.microsoft.com/msdnmag/issues/07/08/sidebar/default.aspx&lt;/a&gt;&lt;/li&gt;&lt;li&gt;On page load we do one of three options:&lt;/li&gt;&lt;ul&gt;&lt;li&gt;If running on Windows 64 bits, we display a message because &lt;a href="http://kb.adobe.com/selfservice/viewContent.do?externalId=6b3af6c9&amp;sliceId=1"&gt;Flash does not support 64-bit systems&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;If connection is offline, we display a message&lt;/li&gt;&lt;li&gt;Otherwise, we display the applet&lt;/li&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;p&gt;The recommended approach to test a 64-bit platform is to use the &lt;a href="http://msdn2.microsoft.com/en-us/library/ms723259.aspx"&gt;System.Machine.processorArchitecture&lt;/a&gt; property but this always returns [Object error] on my 64-bit DELL Precision M65. So I have used &lt;a href="http://msdn2.microsoft.com/en-us/library/ms723686.aspx"&gt;System.Environment.getEnvironmentVariable("PROCESSOR_ARCHITECTURE")&lt;/a&gt; which seems to work consistently over the few Vista computers that I have tested.&lt;/p&gt;&lt;p&gt;There is apparently no function in the framework to check if the network connection is online, so I have used the same approach used in the &lt;a href="http://jlchereau.blogspot.com/2007/08/turning-velodoc-flash-applet-into.html"&gt;Google Desktop Gadget&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I have only experienced one hitch in the implementation: the Flash applet catches the mouse events before the Sidebar. As a consequence, the gadget toolbar at the top right of the gadget is never displayed, which prevents from closing or moving the gadget. The workaround I have found is to add an image at the top of the Flash applet, so that when the mouse goes over this image, the gadget toolbar is displayed.&lt;/p&gt;&lt;img id="BLOGGER_PHOTO_ID_5099699031958645554" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://4.bp.blogspot.com/_CBeG1tyR9Ck/RsXFQA1MazI/AAAAAAAAAAU/rObqfl7f2Xg/s200/070817.png" border="0" /&gt; &lt;p&gt;&lt;/p&gt;&lt;h4&gt;Packaging&lt;/h4&gt;&lt;p&gt;You can package your sidebar gadgets as .zip files or .cab files renamed into .gadget files. I have used the following batch file to produce a proper package from sources located in "D:\Documents\Velodoc Sidebar Gadget\Sources". The batch file should be located in the parent directory:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;rem ** remove/create a test gadget folder&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;rd "%LOCALAPPDATA%\Microsoft\Windows Sidebar\Gadgets\Velodoc.gadget\" /s /q&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;md "%LOCALAPPDATA%\Microsoft\Windows Sidebar\Gadgets\Velodoc.gadget\"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;rem ** copy all of the files into test area&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;xcopy .\Sources "%LOCALAPPDATA%\Microsoft\Windows Sidebar\Gadgets\Velodoc.gadget\" /y /s /q /EXCLUDE:exclude.txt&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;%SystemDrive%&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;cd "%LOCALAPPDATA%\Microsoft\Windows Sidebar\Gadgets\Velodoc.gadget\"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:Courier New;"&gt;"%VS80COMNTOOLS%Bin\cabarc.exe" -r -p n "D:\Documents\Velodoc Sidebar Gadget\Velodoc.gadget" *&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;pause&lt;/span&gt;&lt;/span&gt;&lt;/p&gt;&lt;h4&gt;Test and debugging&lt;/h4&gt;&lt;p&gt;Testing and debugging is relatively easy, considering the logic is in the Flash applet. Simply double click the gadget file to install and test. There is no need to uninstall before a new install, provided the gadget is removed from the Sidebar.&lt;/p&gt;&lt;h4&gt;Distribution&lt;/h4&gt;&lt;p&gt;Once your gadget is ready, follow the instructions at &lt;a href="http://gallery.live.com/submit.aspx"&gt;http://gallery.live.com/submit.aspx&lt;/a&gt; to publish it on the Live web site.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-3508345111251642237?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/3508345111251642237/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=3508345111251642237' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/3508345111251642237'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/3508345111251642237'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/08/turning-velodoc-flash-applet-into-vista.html' title='Turning the Velodoc Flash applet into a Vista Sidebar gadget'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_CBeG1tyR9Ck/RsXFQA1MazI/AAAAAAAAAAU/rObqfl7f2Xg/s72-c/070817.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-2096174884966848613</id><published>2007-08-16T19:02:00.001+01:00</published><updated>2007-08-17T15:06:54.376+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Velodoc'/><category scheme='http://www.blogger.com/atom/ns#' term='Flash'/><title type='text'>Turning the Velodoc Flash applet into a Google Desktop Gadget</title><content type='html'>&lt;span xmlns=""&gt;&lt;h4&gt;Documentation&lt;br /&gt;&lt;/h4&gt;&lt;p&gt;The Goggle Desktop SDK can be found at &lt;a href="http://desktop.google.com/dev/index.html"&gt;http://desktop.google.com/dev/index.html&lt;/a&gt;. The documentation is rudimentary, but there are several samples worth exploring. Besides gadgets are packaged in .gg files which can be renamed into .zip files, so that the content can be explored.&lt;/p&gt;&lt;p&gt;A lot of information can also be found in the forums at &lt;a href="http://groups.google.com/group/Google-Desktop-Developer?lnk=lr&amp;hl=en-GB"&gt;http://groups.google.com/group/Google-Desktop-Developer?lnk=lr&amp;amp;hl=en-GB&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;Implementation&lt;br /&gt;&lt;/h4&gt;&lt;p&gt;My initial track was to run the Flash applet in the Sidebar as explained in &lt;a href="http://groups.google.com/group/Google-Desktop-Developer/browse_thread/thread/2ee23c46237e5408?hl=en-GB"&gt;http://groups.google.com/group/Google-Desktop-Developer/browse_thread/thread/2ee23c46237e5408?hl=en-GB&lt;/a&gt;. My gadget was very simple: a manifest, a localized string.xml file, the main.xml file represented below and a couple of images.&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;&amp;lt;view height="240" width="240"&amp;gt;&lt;br /&gt;&amp;lt;div id="flashcontainer" style="text-align: center;"&amp;gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;lt;object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="240" height="240"&amp;gt;&lt;br /&gt;&amp;lt;param name="movie" value="http://www.velodoc.net/Gadgets/Velodoc.Gadget.swf" /&amp;gt;&lt;br /&gt;&amp;lt;param name="wmode" value="transparent" /&amp;gt;&lt;br /&gt;&amp;lt;param name="allowScriptAccess" value="sameDomain" /&amp;gt;&lt;br /&gt;&amp;lt;param name="quality" value="high" /&amp;gt;&lt;br /&gt;&amp;lt;param name="bgcolor" value="#000000" /&amp;gt;&lt;br /&gt;&amp;lt;/object&amp;gt;&lt;br /&gt;&amp;lt;/view&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;In particular, there was no Javascript file in this implementation.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;This track is a dead end because there is too much interactivity in the Flash applet and Google Desktop seems to get the events before the applet code gets an opportunity to handle them, which results in an unresponsive applet. Accordingly, the only way is to run the applet in a details view.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The best example to start from is HtmlDetailsView which is part of the SDK. Do not forget to change the guid in the manifest, otherwise you won't be able to submit your project to Google at the end. The code is pretty straightforward, so please download the gadget at &lt;a href="http://www.velodoc.net/gadgets/GDesktop/Velodoc.GDesktop.gg"&gt;http://www.velodoc.net/gadgets/GDesktop/Velodoc.GDesktop.gg&lt;/a&gt;, rename it into a .zip file and explore.&lt;br /&gt;&lt;/p&gt;&lt;img id="BLOGGER_PHOTO_ID_5099363367379561250" style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://2.bp.blogspot.com/_CBeG1tyR9Ck/RsST9w1MayI/AAAAAAAAAAM/FXpdxhg_6oQ/s320/070816.png" border="0" /&gt; &lt;p&gt;The only issue I have faced is the use of the &lt;span style="font-family:Courier New;"&gt;system.network.online&lt;/span&gt; property to detect the online/offline status. After simply disconnecting my network cable, the value returned was still true. So I have created the isOnline() function which uses a synchronous XMLHttpRequest of type HEAD to confirm access to the Flash applet. I did not feel that an asynchronous request was justified in this case. For more information see &lt;a href="http://www.jibbering.com/2002/4/httprequest.html"&gt;http://www.jibbering.com/2002/4/httprequest.html&lt;/a&gt; and &lt;a href="http://ajaxpatterns.org/XMLHttpRequest_Call"&gt;http://ajaxpatterns.org/XMLHttpRequest_Call&lt;/a&gt;.&lt;/p&gt;&lt;h4&gt;Test and debugging&lt;/h4&gt;&lt;p&gt;Testing is easy and does not require packaging the gadget. Double-click the gadget.manifest file and the gadget is installed in the sidebar.&lt;/p&gt;&lt;h4&gt;Packaging and Distribution&lt;br /&gt;&lt;/h4&gt;&lt;p&gt;To package your applet, simply archive all the files in a zip file. Keep the directory structure where the manifest is at the root of the archive. Then rename the .zip extension into .gg and test. You can install your packaged gadget by double-clicking the gg file.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;If you upload your gadget to an IIS 6 server, you will get an error 404 when downloading it. By default IIS blocks files which have no known mime type. See: &lt;a href="http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/0f4ac79a-dc2b-4a5f-89c1-d57266aa6ffe.mspx?mfr=true"&gt;http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/0f4ac79a-dc2b-4a5f-89c1-d57266aa6ffe.mspx?mfr=true&lt;/a&gt;. To be able to download your gadget from an IIS server, you need to create a MIME type for the .gg extension. You can map the .gg extension to "application/octet-stream".&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Then the last step is to submit your gadget at &lt;a href="http://desktop.google.com/pluginsubmit?hl=en-GB"&gt;http://desktop.google.com/pluginsubmit?hl=en-GB&lt;/a&gt; to get some visibility.&lt;/p&gt;&lt;p&gt;Finally, please note that I have also opened a discussion thread regarding this gadget at &lt;a href="http://groups.google.com/group/Google-Desktop-Developer/browse_thread/thread/6776e746840080ee?hl=en-GB"&gt;http://groups.google.com/group/Google-Desktop-Developer/browse_thread/thread/6776e746840080ee?hl=en-GB&lt;/a&gt;&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-2096174884966848613?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/2096174884966848613/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=2096174884966848613' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/2096174884966848613'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/2096174884966848613'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/08/turning-velodoc-flash-applet-into.html' title='Turning the Velodoc Flash applet into a Google Desktop Gadget'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_CBeG1tyR9Ck/RsST9w1MayI/AAAAAAAAAAM/FXpdxhg_6oQ/s72-c/070816.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-7574024163758161569</id><published>2007-08-15T17:50:00.001+01:00</published><updated>2007-08-15T17:59:01.629+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Velodoc'/><category scheme='http://www.blogger.com/atom/ns#' term='Flash'/><title type='text'>Developing a file upload applet for Velodoc with Flash</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;This article follow a recent article entitled &lt;a href="http://jlchereau.blogspot.com/2006/10/designing-windows-sidebar-gadget-for.html"&gt;Designing gadgets and widgets for uploading files to Memba Velodoc&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;ActionScript 2 and the Flash 8 IDE&lt;/h4&gt;&lt;p&gt;This project was my first trial at Flash and in my opinion, Flash 8 presents two main difficulties for .NET developers:&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The IDE offers rudimentary development and debugging features;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Scope and addressing of objects (relative or absolute, using _parent or this) is not always clear. Sometimes relative won't work, and this is fixed with absolute addressing. The rule seems to be using relative unless you cannot get around it.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Apart from that, Flash is not a great development tool and I would not consider large projects in Flash, but it does a nice job for small applets.&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;Flash security&lt;/h4&gt;&lt;p&gt;As always, sandboxed security is not intuitive and error messages are unfriendly when you get them, so be prepared to spend a significant amount of development time on security. Most issues are explained at:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.adobe.com/devnet/flash/articles/fplayer_security.html"&gt;http://www.adobe.com/devnet/flash/articles/fplayer_security.html&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.adobe.com/devnet/flash/articles/fplayer8_security.html"&gt;http://www.adobe.com/devnet/flash/articles/fplayer8_security.html&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;You can also get information about the IE content activation issue at:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=7c29e252"&gt;http://www.adobe.com/cfusion/knowledgebase/index.cfm?id=7c29e252&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;The user interface logic&lt;/h4&gt;&lt;p&gt;I have opted for a form application with the following forms:&lt;br /&gt;&lt;/p&gt;&lt;ul style="MARGIN-LEFT: 39pt"&gt;&lt;li&gt;The &lt;strong&gt;application form&lt;/strong&gt; contains the background elements and the action script.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The &lt;strong&gt;outbox form&lt;/strong&gt; contains a To, Subject and Message text inputs and a "Select file" button. It also contains a label to display the file name and a Send button.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The &lt;strong&gt;progress form&lt;/strong&gt; contains a progress bar and a Cancel button&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The &lt;strong&gt;settings form&lt;/strong&gt; allows you to define your settings.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The &lt;strong&gt;success form&lt;/strong&gt; confirms when a use case completed ok.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The &lt;strong&gt;error form&lt;/strong&gt; displays an error message when needed.&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Except a couple of behaviours, all our script is written in Frame1 of the application form. Navigation between forms is easy to build and does not raise any major issue.&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;The file upload process&lt;/h4&gt;&lt;p&gt;The file upload process using FileReference is simple and fairly well documented in the following documentation:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://livedocs.macromedia.com/labs/as3preview/docs/00000142.html"&gt;http://livedocs.macromedia.com/labs/as3preview/docs/00000142.html&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/aspnet/FlashUpload.asp"&gt;http://www.codeproject.com/aspnet/FlashUpload.asp&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://markshu.ca/imm/flash/tutorial/fileReference.html"&gt;http://markshu.ca/imm/flash/tutorial/fileReference.html&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.flash-db.com/Tutorials/upload/"&gt;http://www.flash-db.com/Tutorials/upload/&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Nevertheless, two trick needs to be pointed out:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;First, FileReference posts a 0 byte request to the designated URL before posting the file. You need to make sure that your server code does not store a 0 byte file in this case.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Second, FileReference emits an invalid multipart request and our server logic got caught. At the end of the request, you will find something like:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;------------GI3ae0Ef1GI3cH2KM7gL6ae0GI3Ef1&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;Content-Disposition: form-data; name="Upload"&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;Submit Query&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;------------GI3ae0Ef1GI3cH2KM7gL6ae0GI3Ef1&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;which should have been:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;------------GI3ae0Ef1GI3cH2KM7gL6ae0GI3Ef1&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;Content-Disposition: form-data; name="Upload"&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt; &lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;Submit Query&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;------------GI3ae0Ef1GI3cH2KM7gL6ae0GI3Ef1--&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The differences being an additional \r\n between the form-data and value and a missing double hyphen at the end of the request. Note that this happens when the applet runs in the Flash environment, it does not happen when the applet runs as a gadget within the Vista sidebar, but in this case, there is an additional random character at the end. We have updated our server code to handle these specificities.&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;Calling web services&lt;/h4&gt;&lt;p&gt;There are three ways to call web services in Flash:&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Remoting is the most flexible, most complicated way. It is the low level stuff.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The web service component is a data binding control which does not require any programming. You get it to work just by settings properties in dialogs.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Finally mx.services.* have high level classes that make calling web services from ActionScript really easy.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;Our requirements are not terribly complex and the mx.services.* classes have been the way to go. There is only one trick, which I have not been able to find either on the web or in the flash documentation, which is how to pass complex objects as parameters.&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;Styling our Flash gadget&lt;/h4&gt;&lt;p&gt;Styling the flash applet certainly represents the largest amount of code and time spent. We needed gradients and bevel effects that would resize. To achieve that, I have used the Flash Drawing APIs described at &lt;a href="http://www.adobe.com/devnet/flash/articles/precision_drawing.html"&gt;http://www.adobe.com/devnet/flash/articles/precision_drawing.html&lt;/a&gt; and skinning techniques described at &lt;a href="http://www.adobe.com/devnet/flash/articles/skinning_3.0.html"&gt;http://www.adobe.com/devnet/flash/articles/skinning_3.0.html&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I have decided to postpone changing colours and localization to a future version.&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;Debugging and testing&lt;/h4&gt;&lt;p&gt;For debugging and testing, you will find the following tools helpful:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Get a debug version of the Flash player at &lt;a href="http://download.macromedia.com/pub/flashplayer/updaters/9/flashplayer_9_plugin_debug.exe"&gt;http://download.macromedia.com/pub/flashplayer/updaters/9/flashplayer_9_plugin_debug.exe&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Get Flash switcher at &lt;a href="https://addons.mozilla.org/fr/firefox/addon/3649"&gt;https://addons.mozilla.org/fr/firefox/addon/3649&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Get Flash tracer at &lt;a href="https://addons.mozilla.org/fr/firefox/addon/3469"&gt;https://addons.mozilla.org/fr/firefox/addon/3469&lt;/a&gt; (With Flash 9, you need to change the path in Flash Tracer Options to C:\Documents and Settings\&amp;lt;user&amp;gt;\Application Data\Macromedia\Flash Player\Logs\flashlog.txt)&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The applet works fine in Internet Explorer. There is a bug which we have experimented in Firefox: You get a US keyboard if you define wmode="transparent". This is documented at &lt;a href="http://blog.headlondon.com/archives/no-wmode-please-were-british/"&gt;http://blog.headlondon.com/archives/no-wmode-please-were-british/&lt;/a&gt; but seems to have been corrected . Other issues that you may experience are documented at &lt;a href="http://www.asserttrue.com/articles/2006/11/17/firefox-and-flash-swf-selection-and-focus-problems"&gt;http://www.asserttrue.com/articles/2006/11/17/firefox-and-flash-swf-selection-and-focus-problems&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;Result&lt;/h4&gt;&lt;p&gt;The result is available at &lt;a href="http://www.velodoc.net/Gadgets/Velodoc.Gadget.aspx"&gt;http://www.velodoc.net/Gadgets/Velodoc.Gadget.aspx&lt;/a&gt;.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;If you want to participate and improve this applet, please contact me. I'll be very happy to share the code with active contributors.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Next, I'll explain how to turn this applet into gadgets and widgets for all major platforms.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-7574024163758161569?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/7574024163758161569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=7574024163758161569' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/7574024163758161569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/7574024163758161569'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/08/developing-file-upload-applet-for.html' title='Developing a file upload applet for Velodoc with Flash'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-7999235392309683203</id><published>2007-08-13T18:30:00.001+01:00</published><updated>2007-08-13T19:18:34.978+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><category scheme='http://www.blogger.com/atom/ns#' term='Yahoo'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><title type='text'>The future of Internet TV</title><content type='html'>&lt;p&gt;Following aerial TV and cable TV, the next revolution is Internet TV or IPTV, which makes the cost of distributing TV programs even lower, allowing for much more targeted and specialized content. There are currently four types of actors that have a chance to play a major role in this exciting revolution:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;The major TV broadcasters&lt;/li&gt;&lt;li&gt;The major telecom providers&lt;/li&gt;&lt;li&gt;The online merchants including &lt;a href="http://www.itunes.com/"&gt;iTunes&lt;/a&gt;&lt;/li&gt;&lt;li&gt;The video web sites including &lt;a href="http://www.youtube.com/"&gt;YouTube&lt;/a&gt;&lt;/li&gt;&lt;li&gt;The peer-to-peer newcomers including &lt;a href="http://www.joost.com/"&gt;Joost&lt;/a&gt; and &lt;a href="http://www.babelgum.com/"&gt;Babelgum&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The following criteria will make the difference between the platforms and eventually specialize them:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Capacity to attract advertising dollars, which is a mix of size and segmentation of the audience&lt;/li&gt;&lt;li&gt;Capacity to attract paid subscriptions, which is related to the quality and exclusivity of the content and ultimately to the remuneration and protection of content producers&lt;/li&gt;&lt;li&gt;Capacity to display hi-res content, which is mainly a technical issue&lt;/li&gt;&lt;li&gt;Ease of use, especially to search for or subscribe to archived content&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;p&gt;Let’s now review the various platforms and trends:&lt;/p&gt;&lt;table cellspacing="0" cellpadding="0" border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" colspan="2"&gt;&lt;p align="center"&gt;Ad Dollars&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" colspan="2"&gt;&lt;p align="center"&gt;Paid Subs.&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" colspan="2"&gt;&lt;p align="center"&gt;Hi-Res&lt;/p&gt;&lt;/td&gt;&lt;td valign="top" colspan="2"&gt;&lt;p align="center"&gt;Search&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;&lt;p&gt;Major TV Broadcasters&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;5&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↓&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;5&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↓&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;4&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↑&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;0&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↑&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;&lt;p&gt;Major telecom providers&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;0&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↑&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;5&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↑&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;4&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↑&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;2&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↑&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;&lt;p&gt;Online Merchants&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;0&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↑&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;5&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↑&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;5&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↑&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;5&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↑&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;&lt;p&gt;Video web sites&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;2&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↑&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;1&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↑&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;1&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↑&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;4&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↑&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;&lt;p&gt;P2P newcomers&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;1&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↑&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;0&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↑&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;3&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↑&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;2&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;↑&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;p&gt;&lt;/p&gt;&lt;br /&gt;&lt;table cellspacing="0" cellpadding="0" border="1"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;Weak point&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;Strong point&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;Best fit&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;&lt;p&gt;Major TV Broadcasters&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;Transition to Internet&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;Quality content and revenue stream&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;News and other short-life content&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;&lt;p&gt;Major telecom providers&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;Content&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;Infrastructure&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;Mobile phones&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;&lt;p&gt;Online Merchants&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;Purchasing process&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;Hi-Res content&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;Films&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;&lt;p&gt;Video web sites&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;Streaming bandwidth&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;Navigate and search&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;Short low-res content&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td valign="top"&gt;&lt;p&gt;P2P newcomers&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;Works on PC + Content&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;Hi-Res content&lt;/p&gt;&lt;/td&gt;&lt;td valign="top"&gt;&lt;p align="center"&gt;Documentary&lt;/p&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;br /&gt;&lt;p&gt;As more platforms will become available, the split between content producers and broadcasters will become more obvious. In this respect, I do not think that the major telecom providers, online merchants, video web sites and P2P newcomers will ever produce content, but will rather enter into agreements to obtain content. In this respect, the major TV broadcasters which both produce and broadcast content will enter in “co-opetition” agreements, for example to broadcast their programs on mobile phones.&lt;/p&gt;&lt;p&gt;Telecom providers are probably the biggest threat to TV broadcasters as many content producers will see in them a new channel for their content. This is probably the main reason for &lt;a href="http://packages.sky.com/"&gt;Sky&lt;/a&gt; to offer broadband and telephone or for Microsoft to target &lt;a href="http://www.microsoft.com/tv/default.mspx"&gt;MediaRoom&lt;/a&gt; at service providers.&lt;/p&gt;&lt;p&gt;Considering the purchasing process, online merchants will probably focus on music and films for quite some time and do not represent a significant threat for TV broadcasters and telecom providers.&lt;/p&gt;&lt;p&gt;I cannot imagine video web sites getting enough money from advertising to sustain their activity, they have to remain free for users and they will not be able to compete on high-quality content with TV broadcasters and telecom providers. In my opinion, their only option to survive is to get subscriptions from companies to get their own channel, for example:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;A BMW channel where BMW would present educative content regarding its range of cars;&lt;/li&gt;&lt;li&gt;A L’OREAL channel where L’OREAL would give advice to women how to make the most of their makeup using its products;&lt;/li&gt;&lt;li&gt;A DANONE channel where a chef would give recipes using DANONE products;&lt;/li&gt;&lt;li&gt;A NIKE channel which would give training advice for running the marathon.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;p&gt;The video web site could even provide links to purchase the products demonstrated, competing with video shopping channels.&lt;/p&gt;&lt;p&gt;P2P newcomers will have to review their business model. They are currently in a vicious circle:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;they do not remunerate content producers because they are free and they do not have enough advertising;&lt;/li&gt;&lt;li&gt;they do not have enough advertising because they do not have enough quality content attracting users;&lt;/li&gt;&lt;li&gt;finally, they do not have enough quality content because they do not remunerate content producers.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;P2P newcomers definitely need some free content to let users evaluate their technology and make the numbers, but they have a vocation at being a video encyclopedia capable of making available not only the blockbusters but more importantly confidential content like documentaries or TV archives and they won’t be able to achieve that without user subscriptions and retributions to content providers.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-7999235392309683203?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/7999235392309683203/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=7999235392309683203' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/7999235392309683203'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/7999235392309683203'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/08/future-of-internet-tv.html' title='The future of Internet TV'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-7628708064337262612</id><published>2007-07-30T23:04:00.001+01:00</published><updated>2007-08-15T17:35:37.627+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='SMTP'/><title type='text'>Developing a quick and dirty bulk email infrastructure to clean your lists</title><content type='html'>&lt;span xmlns=''&gt;&lt;p&gt;If you want to send an email newsletter, I can only recommend you use:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;An email marketing software: &lt;a href='http://email-marketing-software-review.toptenreviews.com/'&gt;http://email-marketing-software-review.toptenreviews.com&lt;/a&gt;&lt;br /&gt;    &lt;/li&gt;&lt;li&gt;Or preferably an email marketing service: &lt;a href='http://email-marketing-service-review.toptenreviews.com'&gt;http://email-marketing-service-review.toptenreviews.com&lt;/a&gt;&lt;br /&gt;    &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In our research for the ideal tool, we have found that services are weak on editing and layout and strong on reporting, whereas software is strong on editing and weak on opt-in/opt-out use cases and cleaning contact lists. There is no perfect tool. There is in my opinion an advantage to email marketing services because there is a workaround to their weaknesses which is to compose the newsletter in an HTML editing tool like Dreamweaver.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;You may choose not to use these software and services, either to spare your marketing dollars or because you need specific features that these tools do not provide. In this case you will need to assess the following requirements and you will find that developing a bulk email infrastructure is no easy task:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Editing and layout&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Contact list management&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Mail merge&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Bulk send performances&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Opt-in/opt-out use cases&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Cleaning contact list (email bounces)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Reporting&lt;br /&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;In our case, we had to find a way to clean our contact list before considering a subscription to an email marketing service because their pricing is per contact and some contacts in our list were fairly old. To achieve that, we have spent a couple of days building a quick and dirty bulk email infrastructure comprising:&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;An SMTP server with two mailboxes, &lt;a href='mailto:newsletter@domain.tld'&gt;newsletter@domain.tld&lt;/a&gt; and &lt;a href='mailto:dsn@domain.tld'&gt;dsn@domain.tld&lt;/a&gt;, where the first one has an autoresponder; &lt;br /&gt;&lt;/li&gt;&lt;li&gt;A bulk email tool including management of bouncing emails, which is only a GUI around &lt;a href='http://www.devbiz.com/'&gt;devMail&lt;/a&gt;;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;An opt-in/opt-out web page;&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Integration with Google Analytics for reporting (not in the sample).&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;The process to build, send and analyse a newsletter is the following:&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Design the newsletter in Dreamweaver (use %%dbfield%% for mail merge)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Check the newsletter against the SPAM checker of &lt;a href='http://www.iContact.com'&gt;iContact&lt;/a&gt; using a trial account&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Open the newsletter in IE and save as web archive (*.MHT) with embedded images&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Open the MHT file in the bulk email tool (configured to use a specific database and SMTP server)&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Build the text version of the HTML newsletter&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Click send&lt;br /&gt;&lt;/li&gt;&lt;li&gt;A few days later, open the tool and click Analyze to interpret delivery status notifications and tag bouncing emails&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Open the mailbox in Outlook  to handle manually the notifications which could not be interpreted&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;You can download the source code here. This tool does not measure up with the software and services mentioned above, but it offers a convenient way to purge a contact list before subscribing to an email marketing service.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-7628708064337262612?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/7628708064337262612/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=7628708064337262612' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/7628708064337262612'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/7628708064337262612'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/07/developing-quick-and-dirty-bulk-email.html' title='Developing a quick and dirty bulk email infrastructure to clean your lists'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-1724999963066405502</id><published>2007-07-06T14:12:00.001+01:00</published><updated>2007-07-06T14:43:51.018+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Schedule your backup transfers</title><content type='html'>&lt;p&gt;This is a follow-up of my recent article entitled "Automated SQL Server backups".&lt;/p&gt;&lt;p&gt;After automating SQL server backups on a remote server, you will probably want to transfer them to an FTP server and you will want this to be automatically done every day.&lt;/p&gt;&lt;h4&gt;Using FTP&lt;/h4&gt;&lt;p&gt;Windows command-line FTP.exe has the ability to use scripts like in &lt;strong&gt;FTP –script:"C:\backup.ftp"&lt;/strong&gt; where backup.ftp is a text file containing a series of FTP commands:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;open &lt;a href="ftp://ftp.yourdomain.tld/"&gt;ftp://ftp.yourdomain.tld/&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;username&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;password&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bin&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;cd /backup&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;put "&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;C:\Program Files\Microsoft SQL Server\MSSQL\BACKUP\DBName Mondays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;quit&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Accordingly, you can schedule the following VB script to execute daily using windows task scheduler:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;Dim ftp, dir1,&lt;/span&gt; &lt;span style="font-family:Courier New;"&gt;dir2,&lt;/span&gt; &lt;span style="font-family:Courier New;"&gt;s, d, bak, fso, sf, shell, cmd&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;ftp = &lt;a href="ftp://ftp.exe/"&gt;ftp://ftp.exe/&lt;/a&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;dir1 = "C:\Program Files\Microsoft SQL Server\MSSQL\BACKUP\" '—- Local dir&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;dir2 = "/backup" '—- FTP dir (do not include / at the end)&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;s= "backup.ftp"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;d=weekday(date)&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;select case d&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;case 1&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bak="DBName Sundays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;case 2&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bak="DBName Mondays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;case 3&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bak="DBName Tuesdays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;case 4&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bak="DBName Wednesdays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;case 5&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bak="DBName Thursdays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;case 6&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bak="DBName Fridays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;case else&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bak="DBName Saturdays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;end select&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;Set fso = CreateObject("Scripting.FileSystemObject")&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;Set sf = fso.CreateTextFile(dir1 + s, True)&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;sf.WriteLine("open ftp.yourdomain.tld")&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;sf.WriteLine("username")&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;sf.WriteLine("password")&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;sf.WriteLine("bin")&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;sf.WriteLine("cd " + dir2)&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;sf.WriteLine("put " + chr(34) + dir1 + bak + chr(34))&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;sf.WriteLine("quit")&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;sf.Close&lt;br /&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;Set shell = CreateObject("WScript.Shell")&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;cmd = chr(34) + ftp + chr(34) + " -s:" + chr(34) + dir1 + s + chr(34)&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;shell.Run cmd, 8, true&lt;/span&gt;&lt;/p&gt;&lt;h4&gt;Workaround when Passive FTP is required&lt;br /&gt;&lt;/h4&gt;&lt;p&gt;When running the command above, you may get the following FTP error "425 – Could not open data connection to port 2512: connection refused" depending on the infrastructure.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;There is a good chance that you need passive FTP. &lt;a href="http://www.iss.net/security_center/advice/Services/FTP/PASV/default.htm"&gt;Contrary to what some people say&lt;/a&gt;, &lt;a href="http://support.microsoft.com/kb/247132"&gt;windows command-line FTP is capable of passive mode&lt;/a&gt;, but the "literal PASV" command returns a port number which has to be opened using "literal PORT" and this cannot be easily scripted.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The workaround is to use &lt;a href="http://www.ncftp.com/ncftp/"&gt;ncftp software&lt;/a&gt; and the following VB script instead of the script above:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;Dim ftp, dir1, dir2, d, bak, shell, cmd&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;ftp = "C:\Program Files\NcFTP\ncftpput.exe"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;dir1 = "C:\Program Files\Microsoft SQL Server\MSSQL\BACKUP\" '—- Local dir&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;dir2 = "/backup" '—- FTP dir (do not include / at the end)&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;d=weekday(date)&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;select case d&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;case 1&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bak="DBName Sundays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;case 2&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bak="DBName Mondays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;case 3&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bak="DBName Tuesdays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;case 4&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bak="DBName Wednesdays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;case 5&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bak="DBName Thursdays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;case 6&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bak="DBName Fridays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;case else&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bak="DBName Saturdays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;end select&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;Set shell = CreateObject("WScript.Shell")&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;cmd = chr(34) + ftp + chr(34) + " -u username -p password ftp.yourdomain.tld " + dir2 + " " + chr(34) + dir1 + bak + chr(34)&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;shell.Run cmd, 8, true&lt;/span&gt;&lt;/p&gt;&lt;h4&gt;Downloading backups from your FTP server to your workstation or a local server&lt;/h4&gt;&lt;p&gt;A similar approach can be used to schedule backup downloads from the FTP server to your workstation or a local server which has tape backup.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;Dim ftp, dir1, dir2, shell, cmd&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;ftp = "C:\Program Files\NcFTP\ncftpget.exe"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;dir1 = "/backup/" '-- FTP dir&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;dir2 = "C:\BACKUP" '-- Local dir (do not include \ at the end)&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;Dim bakArray(6)&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;'-- Sundays&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bakArray(0) = "DBName Sundays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bakArray(1) = "DBName Mondays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bakArray(2) = "DBName Tuesdays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bakArray(3) = "DBName Wednesdays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bakArray(4) = "DBName Thursdays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bakArray(5) = "DBName Fridays.bak"&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;bakArray(6) = "DBName Saturdays.bak"&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;"&gt;Set shell = CreateObject("WScript.Shell")&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;cmd = chr(34) + ftp + chr(34) + " -u username -p password ftp.yourdomain.tld " + chr(34) + dir2 + chr(34) + " "&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:Courier New;"&gt;For Each bak In bakArray&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;'ncftpget is sufficiently intelligent to only download newer files&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;cmd = cmd + chr(34) + dir1 + bak + chr(34) + " "&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;Next&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;cmd = Trim(cmd)&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:Courier New;"&gt;shell.Run cmd, 8, true&lt;/span&gt;&lt;/p&gt;&lt;h4&gt;What is next?&lt;/h4&gt;&lt;p&gt;The above can be improved one step further by launching the script directly from SQL Server jobs using an Execute T-SQL Statement Task which would possibly generate and call the script with master.dbo.xp_cmdshell. This would secure the FTP credentials in SQL Server and launch the transfer immediately at the end of a back-up.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-1724999963066405502?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/1724999963066405502/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=1724999963066405502' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/1724999963066405502'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/1724999963066405502'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/07/schedule-your-backup-transfers.html' title='Schedule your backup transfers'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-3579116822025101868</id><published>2007-07-06T14:10:00.001+01:00</published><updated>2007-07-06T14:42:55.071+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='SQL'/><title type='text'>Automated SQL Server Backups</title><content type='html'>&lt;span xmlns=''&gt;&lt;h4&gt;SQL Server 2000&lt;br /&gt;&lt;/h4&gt;&lt;ol&gt;&lt;li&gt;Open SQL Server Enterprise Manager&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Register your server&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Right-click the node Management &amp;gt; Backup, then select menu Add backup devices... We create devices "DBName Mondays.bak" to "DBName Sundays.bak" corresponding to each day of the week but you can use your own naming convention. We have assumed that DBName is the name of the database to backup.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Right-click the node Databases &amp;gt; DBName, then select menu option All Tasks &amp;gt; Backup database...&lt;br /&gt;&lt;/li&gt;&lt;li&gt;The SQL Server Backup – DBName dialog box is displayed.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;On the General tab, rename the backup "DBName Mondays", click the Remove button if an item appears in the backup to list, then click Add... &lt;br /&gt;&lt;/li&gt;&lt;li&gt;In the Select Backup Destination backup select Backup Device and "DBName Mondays" then click OK.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Make sure Database - complete and Overwrite existing media are selected.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Check schedule and click ... to edit. Rename the schedule "DBName Mondays" and schedule to occur weekly on Mondays. Click OK.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;On the Options tab, click Verify backup upon completion and Remove inactive entries from transaction log. Keep other options unchecked.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Go through steps 4 to 10 with "DBName Tuesdays" to "DBName Sundays".&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Go to the Management &amp;gt; SQL Server Agent &amp;gt; Jobs node, refresh the list and check the 7 backup jobs which you have just created.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h4&gt;SQL Server 2005&lt;br /&gt;&lt;/h4&gt;&lt;p&gt;This is slightly more complicated in SQL Server 2005 because you cannot use the backup dialog which has no scheduling option. You need to use a maintenance plan. A maintenance plan is an SSIS package, which means you either need SSIS or SP2 installed, because SP2 includes a limited version of SSIS for maintenance tasks including backups.&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Open SQL Server Management Studio (Run as Administrator on Windows Vista).&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Right-click the node Server Objects &amp;gt; Backup Devices and select menu "Add Backup Device...".&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Name your backup device "DBName Mondays" and make it a file named "DBName Mondays.bak".&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Repeat steps 2 and 3 for "DBName Tuesdays" to "DBName Sundays". &lt;br /&gt;&lt;/li&gt;&lt;li&gt;Start and configure SQL Server Agent which is a requirement for maintenance plans.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Right click the node Management &amp;gt; Maintenance Plans and select menu "New Maintenance Plan..."&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Rename your plan "DBName Plan".&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Double-click "Subplan_1" to edit its properties.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Name it "DBName Mondays" and create a schedule of the same name recurring weekly every Monday.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Drop a "Back Up Database Task" from the toolbox onto the light yellow design surface.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Right-click the task on the design surface and select menu "Edit...".&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Select the database(s) you want to back up, check option "Back up databases across one or more files", then click button "Add..." and select the backup device called DBName Mondays.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Select "Overwrite" if backup file exists, check "Verify backup integrity" and click OK.&lt;br /&gt;&lt;/li&gt;&lt;li&gt;On top of the list of subplans of "DBName Plan", click "Add Subplan".&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Go through steps 9 to 14 with "DBName Tuesdays" to "DBName Sundays".&lt;br /&gt;&lt;/li&gt;&lt;li&gt;Go to the SQL Server Agent &amp;gt; Jobs , refresh the list and check the 7 backup jobs which you have just created.&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;For both SQL Server 2000 and SQL Server 2005, you can consider adding tasks to shrink databases, rebuild indexes, check database integrity in the scheduled jobs, but this goes beyond the scope of this article. In a following article, we will show you how to schedule FTP transfers to push and/or pull the backup files.&lt;/p&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-3579116822025101868?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/3579116822025101868/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=3579116822025101868' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/3579116822025101868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/3579116822025101868'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/07/automated-sql-server-backups.html' title='Automated SQL Server Backups'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-1900952756509138859</id><published>2007-06-27T09:57:00.001+01:00</published><updated>2007-06-27T09:59:45.257+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>Getting metrics from .NET projects</title><content type='html'>&lt;span xmlns=""&gt;&lt;p&gt;There are loads of free tools available to get metrics from Java projects. I have found much more difficult to find similar tools for .NET projects.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;When googling for ".NET project metrics" you get many references to devMetrics from a company called Anticipating Minds. I will spare you the time: Anticipating Minds is no more doing business and devMetrics does not work with .NET framework 2.0 and above.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;I have used two complementary tools which give simple but effective metrics:&lt;br /&gt;&lt;/p&gt;&lt;ol style="MARGIN-LEFT: 38pt"&gt;&lt;li&gt;A Reflector add-in called &lt;a href="http://www.codeplex.com/reflectoraddins"&gt;CodeMetrics&lt;/a&gt;, and&lt;br /&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.campwoodsw.com/sourcemonitor.html"&gt;Source Monitor&lt;/a&gt; from Campwood Software.&lt;/li&gt;&lt;/ol&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-1900952756509138859?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/1900952756509138859/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=1900952756509138859' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/1900952756509138859'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/1900952756509138859'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/06/getting-metrics-from-net-projects.html' title='Getting metrics from .NET projects'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-2697377181279749927</id><published>2007-06-22T11:27:00.001+01:00</published><updated>2007-06-28T09:40:30.926+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><category scheme='http://www.blogger.com/atom/ns#' term='Yahoo'/><category scheme='http://www.blogger.com/atom/ns#' term='Microsoft'/><title type='text'>The ad war from a user perspective</title><content type='html'>&lt;p&gt;The ad war between Google, Microsoft and Yahoo is on. This is a summary of what you have probably read in the press:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Yahoo Search Marketing (formerly Overture) has only been losing market share for a couple of years and struggles to deploy its new advertising platform, code-named Panama.&lt;/li&gt;&lt;li&gt;Microsoft’s advertising strategy has always been confused until recently. They have now decided to go into the advertising space and they want to make it big. See how much they have spent to recently acquire &lt;a href="http://www.aquantive.com/"&gt;aQuantive&lt;/a&gt;. See the pace of upgrades made to AdCenter. See also Microsoft’s track record of turning a late arrival in a competitive market into a great success: Internet Explorer, Windows Mobile, Xbox.&lt;/li&gt;&lt;li&gt;Google is the leader with a consistent strategy and a great advertising platform, which not only includes AdWords and its important counterpart AdSense, but also free services like Blogger or Gmail where advertising is leveraged. Finally they have two critical complementary tools which give them a competitive edge, Google Analytics and Google Checkout.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;It is difficult to measure how much the advertising platform weighs in the success or failure of its owner. I like to believe that it is a large part of it. I am a user of Yahoo Search Marketing, Microsoft AdCenter and Google’s suite including AdWords, AdSense, Analytics, and Blogger and I report here my experience:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Yahoo Search Marketing’s platform is simply a pain to use. Registering is overly complicated with issues regarding restrictions on billing address and currency in relation to the target market. Note that only Yahoo proposes a service fee to help you get started. Vocabulary is confusing but it has been corrected in the new platform. And the worst design issue is certainly the concept of binding an account to a national market, which remains in the new platform. In other words, if you advertise in the US and in 5 European countries, you need 6 different accounts and there is no way you can get a single view of your advertising spend with Yahoo. In my opinion, there is urgency for Yahoo to correct this if they want to survive in the advertising space.&lt;/li&gt;&lt;li&gt;Microsoft AdCenter is fairly new and gets improved regularly. It is certainly more rigid than Google. For example, an Ad has a culture which is a combination of language and country. Accordingly, if you want the same Ad to be displayed in the US and in the UK, you need to duplicate it. Google is better in this respect but I think AdCenter is deemed do a reasonable Job after a few revisions. The challenge for Microsoft is to build synergies with other tools in a reasonable time: they definitely need the equivalent of Google AdSense and Google Analytics and they also need to offer users who contribute content on their platform, including Live Spaces , the ability to generate revenue using their AdSense equivalent.&lt;/li&gt;&lt;li&gt;Google is I think two years ahead of the competition and their recent acquisition of &lt;a href="http://www.doubleclick.com/"&gt;DoubleClick&lt;/a&gt; has given them more comfort against Microsoft. I have very few complaints against their platform apart from the inability to change from credit card to bank account, the inability to get a bank account automatically debited and the incompatibility of AdSense with SSL. Google Analytics is absolutely a must have and I can’t wait for Google checkout to be available in continental Europe.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-2697377181279749927?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/2697377181279749927/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=2697377181279749927' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/2697377181279749927'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/2697377181279749927'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/06/ad-war-from-user-perspective.html' title='The ad war from a user perspective'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-394840133045633132</id><published>2007-06-21T20:23:00.000+01:00</published><updated>2007-06-27T10:00:23.927+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>Getting scheduled scans to work with Norton Antivirus 10.2 running in unmanaged mode</title><content type='html'>We use Norton Antivirus (NAV) Corporate Edition which is installed in managed mode on our LAN.&lt;br /&gt;&lt;br /&gt;We have been using an old version of NAV on dedicated hosted web servers. Recently we have realized that NAV was triggering ThreadAbortException on long running ASP.NET pages. Excluding files did not solve the problem. We have had to upgrade NAV.&lt;br /&gt;&lt;br /&gt;We have installed NAV in unmanaged mode on these servers as per the documentation, but after a couple of days, we have realized that scheduled scans were not working. The reason is explained &lt;a href="http://entkb.symantec.com/security/output/n2000042608194548.html"&gt;here&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;The workaround which is not given in the Symantec knowledge base is simply to copy (export + import) the following registry keys (and all subkeys) from a computer which has NAV in managed mode to the computer which has NAV in unmanaged mode:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\INTEL\LANDesk\VirusProtect6\CurrentVersion\LocalScans\ClientServerScheduledScan_1&lt;/li&gt;&lt;li&gt;...&lt;/li&gt;&lt;li&gt;HKEY_LOCAL_MACHINE\SOFTWARE\INTEL\LANDesk\VirusProtect6\CurrentVersion\LocalScans\ClientServerScheduledScan_n&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-394840133045633132?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/394840133045633132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=394840133045633132' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/394840133045633132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/394840133045633132'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/06/getting-scheduled-scans-to-work-with.html' title='Getting scheduled scans to work with Norton Antivirus 10.2 running in unmanaged mode'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-3258823881912025496</id><published>2007-03-29T11:11:00.000+01:00</published><updated>2007-08-15T17:36:11.571+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Ajax extensions services always report “There was an error processing the request.”</title><content type='html'>I have been puzzled by the following for quite a while.&lt;br /&gt;&lt;br /&gt;I use Microsoft Ajax extensions 1.0 to query web services which may raise exceptions. In my development environment, I would always get a nice localized error message but on the production server, the same code would produce a generic “There was an error processing the request”.&lt;br /&gt;&lt;br /&gt;After having spent enough time stepping through my code with a debugger, I have decided to look at the Ajax extensions code and I have found the following piece of code in WriteExceptionJsonString of RestHandler.cs.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;if (context.IsCustomErrorEnabled)&lt;br /&gt;{&lt;br /&gt;    writer.Write(JavaScriptSerializer.SerializeInternal(new WebServiceError(&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;        AtlasWeb.WebService_Error, String.Empty, String.Empty)));&lt;br /&gt;}&lt;br /&gt;else&lt;br /&gt;{&lt;br /&gt;    writer.Write(JavaScriptSerializer.SerializeInternal(new WebServiceError(&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;        ex.Message, ex.StackTrace, ex.GetType().FullName)));&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Where WebService_Error is a resource which is valued “There was an error processing the request.”&lt;br /&gt;&lt;br /&gt;This means that if you have enabled custom errors in your web.config on your production environment like I did, your Ajax calls will always report a generic error.&lt;br /&gt;&lt;br /&gt;Why have the Microsoft people introduced such a restriction is a mystery to me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-3258823881912025496?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/3258823881912025496/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=3258823881912025496' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/3258823881912025496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/3258823881912025496'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/03/ajax-extensions-services-always-report.html' title='Ajax extensions services always report “There was an error processing the request.”'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-6485239330670563897</id><published>2007-03-16T18:13:00.000Z</published><updated>2007-08-15T17:36:31.013+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Extender controls may not be registered before PreRender</title><content type='html'>Today, I have added new &lt;a href="http://ajax.asp.net/ajaxtoolkit"&gt;AjaxControlToolkit&lt;/a&gt; controls to &lt;a href="https://www.velodoc.net"&gt;Velodoc&lt;/a&gt; pages and I got exception “Extender controls may not be registered before PreRender” from running a page.&lt;br /&gt;&lt;br /&gt;All our pages derive from our own WebPage class which derive from the standard Page class. WebPage provides features like custom error handling and QueryString parsing into page properties.&lt;br /&gt;&lt;br /&gt;The page where we had the new extender control had the following method:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&lt;span style="color:#3333ff;"&gt;protected override void&lt;/span&gt; OnPreRender(EventArgs e)&lt;br /&gt;{&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="color:#006600;"&gt;    //The following line is required, otherwise you get "Extender controls&lt;br /&gt;    //may not be registered before PreRender."&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#3333ff;"&gt;    base&lt;/span&gt;.OnPreRender(e);&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#006600;"&gt;    //Some code that displays errors on postbacks&lt;/span&gt;&lt;br /&gt;    ...&lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;The solution to the problem above is to add &lt;span style="font-family:courier new;"&gt;base.OnPreRender(e);&lt;/span&gt; at the beginning of the method.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-6485239330670563897?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/6485239330670563897/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=6485239330670563897' title='9 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/6485239330670563897'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/6485239330670563897'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/03/extender-controls-may-not-be-registered.html' title='Extender controls may not be registered before PreRender'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>9</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-2824932911251338268</id><published>2007-01-31T10:36:00.000Z</published><updated>2007-08-15T17:36:49.597+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Functional and load testing of ASP.NET Ajax applications – part I</title><content type='html'>&lt;h4&gt;Introduction&lt;/h4&gt;&lt;p&gt;&lt;a href="https://www.velodoc.net/"&gt;Velodoc&lt;/a&gt; is developed in ASP.NET C# 2.0 with Visual Studio .NET 2005.&lt;/p&gt;&lt;p&gt;VSTS comes with unit testing, web testing and load testing, considering load testing is actually an execution environment for unit tests and web tests.&lt;/p&gt;&lt;p&gt;Unfortunately Visual Studio web tests work at the protocol level, recording HTTP traffic in order to replay it. The same applies to Redgate’s ANTSLoad and many other load testing tools. Velodoc is an Ajax application and this does not work.&lt;/p&gt;&lt;p&gt;We have started our search for a solution from the following lists of testing tools:&lt;/p&gt;&lt;ul type="disc"&gt;&lt;li&gt;&lt;a href="http://www.aptest.com/webresources.html"&gt;http://www.aptest.com/webresources.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.softwareqatest.com/qatweb1.html"&gt;http://www.softwareqatest.com/qatweb1.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.testdriven.com/modules/mylinks/viewcat.php?cid=21&amp;orderby=titleA&amp;amp;PHPSESSID=9f0501e81e532817372ad86a3dec5395"&gt;http://www.testdriven.com/modules/mylinks/viewcat.php?cid=21&amp;orderby=titleA&amp;amp;PHPSESSID=9f0501e81e532817372ad86a3dec5395&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Obviously there are tools like Mercury Winrunner/Loadrunner and the IBM Rational equivalents which certainly cope but they are too expensive.&lt;/p&gt;&lt;p&gt;Our requirements are the following:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Test ASP.NET applications&lt;/li&gt;&lt;li&gt;Works on Windows XP with IE&lt;/li&gt;&lt;li&gt;Compatible with NetAdvantage controls, iFrames, file uploads and Ajax&lt;/li&gt;&lt;li&gt;Scripts IE including IE dialogs to drive functional UI tests&lt;/li&gt;&lt;li&gt;Several instances can be executed concurrently to create load/stress tests&lt;/li&gt;&lt;li&gt;Uses a familiar technology (low learning curve)&lt;/li&gt;&lt;li&gt;Open source is a plus and a requirement if the supplier has not been around for a long time.&lt;/li&gt;&lt;ul&gt;&lt;br /&gt;&lt;/ul&gt;&lt;/ul&gt;&lt;p&gt;There are three types of solutions which cope more or less with these requirements:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Macro recorders/players&lt;/li&gt;&lt;li&gt;Test environments&lt;/li&gt;&lt;li&gt;Web application scripting frameworks&lt;/li&gt;&lt;/ul&gt;&lt;h4&gt;Macro recorders/players and test environments&lt;/h4&gt;&lt;p&gt;Searching on Tucows, Download.com and other shareware web sites reveals loads of macro recorders. Most of them hook the message pump and replay the windows messages. Obviously, the result is not good. We have tried a dozen of them but only &lt;a href="http://www.iopus.com/"&gt;iOpus iMacros&lt;/a&gt; 5.2 could do a decent job at automating a file upload from &lt;a href="https://www.velodoc.net/"&gt;https://www.velodoc.net/&lt;/a&gt;. The code is reproduced below:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;TAB T=1&lt;br /&gt;TAB CLOSEALLOTHERS&lt;br /&gt;URL GOTO=https://www.velodoc.net&lt;br /&gt;SIZE X=876 Y=627&lt;br /&gt;TAG POS=1 TYPE=INPUT:TEXT FORM=NAME:aspnetForm ATTR=ID: SenderTextBox CONTENT=test1@acme.com&lt;br /&gt;TAG POS=1 TYPE=INPUT:TEXT FORM=NAME:aspnetForm ATTR=ID: RecipientTextBox CONTENT=test2@acme.com&lt;br /&gt;TAG POS=1 TYPE=TEXTAREA FORM=NAME:aspnetForm ATTR=ID: MessageTextBox CONTENT= Test&amp;lt;SP&amp;gt;with&amp;lt;SP&amp;gt;iMacro&lt;br /&gt;FRAME F=1&lt;br /&gt;WINCLICK X=100 Y=429 CONTENT=&lt;br /&gt;WINCLICK X=100 Y=429 CONTENT=C:\test.bin&lt;br /&gt;FRAME F=0&lt;br /&gt;TAG POS=1 TYPE=INPUT:CHECKBOX FORM=NAME:aspnetForm ATTR=ID: SendTermsCheckBox&amp;&amp;amp;VALUE:on CONTENT=YES&lt;br /&gt;WINCLICK X=490 Y=513 CONTENT= &lt;/span&gt;&lt;/p&gt;&lt;p&gt;I see at least three drawbacks to using iOpus iMacros as a functional test tool:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;The lack of assertions and reporting capabilities makes it insufficient for functional testing;&lt;/li&gt;&lt;li&gt;The lack of infrastructure makes it insufficient for load testing;&lt;/li&gt;&lt;li&gt;The proprietary language reduces the possibilities despite the fact that it can call external scripts or be called via a COM component.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I have also tried several test environments mentioned in the above lists. Generally, recording the file upload test on &lt;a href="https://www.velodoc.net/"&gt;https://www.velodoc.net/&lt;/a&gt; has always proved difficult but I cannot tell whether it was feasible or not for some of them. I have limited myself to 2 hours per evaluation and the inherent complexity and learning curve was not worth digging passed first impression.&lt;/p&gt;&lt;h4&gt;Web application scripting frameworks&lt;/h4&gt;&lt;p&gt;I have looked at two open-source frameworks, which both script IE to execute functional tests on the web application:&lt;/p&gt;&lt;ul type="disc"&gt;&lt;li&gt;&lt;a href="http://ieunit.sourceforge.net/"&gt;IEUnit&lt;/a&gt; 2.3, a framework based on JavaScript&lt;/li&gt;&lt;li&gt;&lt;a href="http://watin.sourceforge.net/"&gt;WatiN&lt;/a&gt; 0.9.5, a framework based on C# .NET&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Both frameworks are very easy to start with due to a familiar language and an intuitive API. Additionally both frameworks provide the necessary assertions to report on the success or failure of a test fixture.&lt;/p&gt;&lt;p&gt;Scripting a file upload on the &lt;a href="https://www.velodoc.net/"&gt;Velodoc home page&lt;/a&gt; with IEUnit entails the following JavaScript code:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;_.openWindow(&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;https://www.velodoc.net&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;);&lt;br /&gt;_.setField("SenderTextBox", &lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;test1@acme.com&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;);&lt;br /&gt;_.setField("RecipientTextBox", &lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;test2@acme.com&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;);&lt;br /&gt;_.setTextArea("MessageTextBox", "Test with IEUnit");&lt;br /&gt;var fname = "C:\\test.bin";&lt;br /&gt;var cmdShell = new ActiveXObject("WScript.Shell");&lt;br /&gt;cmdShell.Run("C:\\EnterFileName.sbk " + fname, 0, false);&lt;br /&gt;_.setFrame(0);&lt;br /&gt;_.clickObjById("FileInput");&lt;br /&gt;_.setFrame(-1);&lt;br /&gt;_.setCheckBox("SendTermsCheckBox",true);&lt;br /&gt;_.clickObjById("SendWebImageButton");&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Where EnterFileName.sbk contains:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;var fpath = " " + WScript.Arguments(1);&lt;br /&gt;var popupWin = _.waitForWindow("Choose file", 30000);&lt;br /&gt;_.setFrame(0);&lt;br /&gt;_.findWindow(popupWin, "Edit").sendText(fpath);&lt;br /&gt;_.findWinButton(popupWin, "&amp;amp;Open").click();&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Scripting a file upload on the &lt;a href="https://www.velodoc.net/"&gt;Velodoc home page&lt;/a&gt; with WatiN entails the following C# code:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;using (IE ie = new IE(&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;https://www.velodoc.net/&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;))&lt;br /&gt;{&lt;br /&gt;ie.ShowWindow(NativeMethods.WindowShowStyle.Maximize);&lt;br /&gt;ie.TextField(Find.ById("SenderTextBox")).TypeText("&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;test1@acme.com"&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;);&lt;br /&gt;ie.TextField(Find.ById("RecipientTextBox")).TypeText("&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;test2@acme.com&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;");&lt;br /&gt;ie.TextField(Find.ById("MessageTextBox")).TypeText("Test with WatiN");&lt;br /&gt;Frame f = ie.Frame(Find.ById("FileUploadFrame"));&lt;br /&gt;FileUpload fUp = f.FileUpload(Find.ById("FileInput"));&lt;br /&gt;fUp.Set("C:\\test.bin");&lt;br /&gt;ie.CheckBox(Find.ById("SendTermsCheckBox")).Checked = true;&lt;br /&gt;//ie.TextField(Find.ById("SenderTextBox")).FireEvent("onKeyUp");&lt;br /&gt;ie.Button(Find.ById("SendWebImageButton")).ClickNoWait();&lt;br /&gt;SimpleTimer t = new SimpleTimer(60 * 60);&lt;br /&gt;Span s;&lt;br /&gt;do&lt;br /&gt;{&lt;br /&gt;s = ie.Span(Find.ById("DownloadLinkLabel"));&lt;br /&gt;if (!String.IsNullOrEmpty(s.Text))&lt;br /&gt;goto EXIT;&lt;br /&gt;System.Threading.Thread.Sleep(1000);&lt;br /&gt;} while (!t.Elapsed);&lt;br /&gt;throw new WatiN.Core.Exceptions.TimeoutException("...", 60 * 60));&lt;br /&gt;EXIT:&lt;br /&gt;Assert.AreEqual(true, s.Text.Contains(&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;https://www.velodoc.net/&lt;/span&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;));&lt;br /&gt;}&lt;/span&gt;&lt;/p&gt;&lt;h4&gt;Conclusion&lt;/h4&gt;&lt;p&gt;The beauty of WatiN is that it builds on top of C# and .NET framework. Accordingly you get not only a rich language but also a rich environment. Test code built with WatiN can be executed within NUnit and Visual Studio unit testing projects which means that they can also be executed for load tests which I am going to try next although we know already that launching several instances of IE has its own limitation.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-2824932911251338268?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/2824932911251338268/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=2824932911251338268' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/2824932911251338268'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/2824932911251338268'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/01/functional-and-load-testing-of-aspnet.html' title='Functional and load testing of ASP.NET Ajax applications – part I'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-5038869009266408262</id><published>2007-01-24T14:48:00.000Z</published><updated>2007-01-31T10:32:27.871Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><title type='text'>Remapping the universe</title><content type='html'>Following our recent post regarding &lt;a href="/2006/11/about-bumptop.html"&gt;Bumptop&lt;/a&gt;, see in the following Video Jeff Han and Phil Davidson demonstrating how a multi-touch driven computer screen will change the way we work and play.&lt;br /&gt;&lt;br /&gt;&lt;object width="400" height="330"&gt;&lt;param name="movie" value="http://www.youtube.com/v/7_mBjOmq1kY"&gt;&lt;/param&gt;&lt;param name="wmode" value="transparent"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/7_mBjOmq1kY" type="application/x-shockwave-flash" wmode="transparent" width="400" height="330"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;br /&gt;&lt;br /&gt;Source: &lt;a href="http://www.youtube.com/watch?v=7_mBjOmq1kY"&gt;YouTube&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Read the &lt;a href="http://www.fastcompany.com/subscr/112/open_features-canttouchthis.html"&gt;full article&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-5038869009266408262?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/5038869009266408262/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=5038869009266408262' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/5038869009266408262'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/5038869009266408262'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/01/remapping-universe.html' title='Remapping the universe'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-7211842970956908824</id><published>2007-01-16T07:58:00.000Z</published><updated>2007-01-16T08:05:29.621Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>SGen XmlSerializers</title><content type='html'>&lt;p&gt;My VS2005 C# web project was perfectly working in my development environment but I got the following error after deploying in a production environment:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;Configuration Error&lt;br /&gt;Parser Error Message: Cannot deserialize [C:\data.xml].&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Using the fusion log viewer (FUSLOGVW.EXE) reveals a binding exception to Assembly.XmlSerializers.dll, where Assembly is the name of the assembly which contains the classes serialized in data.xml.&lt;/p&gt;&lt;p&gt;My ASP.NET application runs as a dedicated application pool under the credentials of a windows user which has very limited rights. The problem is related to the user rights which prevent the ASP.NET process from automatically generating XmlSerializers.&lt;/p&gt;&lt;h4&gt;Visual Studio cannot generate XmlSerializers&lt;/h4&gt;&lt;p&gt;On the build tab of your VS project properties, there is an option called “Generate Serialization Assemblies” which you can set to “On”.&lt;/p&gt;&lt;p&gt;If you look at MSBuild commands in the output window, doing so actually adds a command line which looks like the following:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\bin\sgen.exe /assembly:"Assembly.dll" /proxytypes /reference:"reference1.dll" … /reference:"referenceN.dll" /compiler:/keycontainer:VS_KEY_5EFB7881D71082EDCF85DBBFCD748B9A /compiler:/delaysign- &lt;/span&gt;&lt;/p&gt;&lt;p&gt;Note the /proxytypes option which actually prevents SGen from generating your XmlSerializers as specified in the documentation for the &lt;a href="http://msdn2.microsoft.com/en-us/library/bk3w6240(vs.80).aspx"&gt;XML Serializer Generator Tool (Sgen.exe)&lt;/a&gt;.&lt;/p&gt;&lt;h4&gt;Use SGen as a post-build event&lt;/h4&gt;&lt;p&gt;As a consequence you need to add the SGen command as a custom post-build event on the Build Events tab of your VS project properties:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;"C:\Program Files\Microsoft Visual Studio 8\SDK\v2.0\Bin\sgen.exe" /force /assembly:"$(TargetPath)" /compiler:/keycontainer:VS_KEY_5EFB7881D71082EDCF85DBBFCD748B9A /compiler:/delaysign-&lt;/span&gt;&lt;/p&gt;&lt;h4&gt;Other interesting links&lt;/h4&gt;&lt;ul type="disc"&gt;&lt;li&gt;&lt;a href="http://markitup.com/Posts/Post.aspx?postId=e300699e-355d-4b04-9e6c-c43a2826faee"&gt;Using SGen.exe to Automatically pre-generate your XmlSerializers&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://weblogs.asp.net/cazzu/archive/2003/10/25/33470.aspx"&gt;XmlSerializer and XSD Type Inheritance: does it work?&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://weblogs.asp.net/cazzu/archive/2004/08/02/205732.aspx"&gt;Strongly-typed, event-rising, design-time generated custom XmlSerializers (even more than Whidbey sgen!)&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-7211842970956908824?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/7211842970956908824/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=7211842970956908824' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/7211842970956908824'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/7211842970956908824'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/01/sgen-xmlserializers.html' title='SGen XmlSerializers'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-5586101279077082306</id><published>2007-01-04T17:29:00.000Z</published><updated>2007-01-04T17:34:41.202Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>Unable to validate data error in relation to machine key</title><content type='html'>&lt;p&gt;I have experienced the following error on a production web site:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;Unable to validate data&lt;br /&gt;&lt;br /&gt;at System.Web.Configuration.MachineKey.GetDecodedData (Byte[] buf, Byte[] modifier, Int32 start, Int32 length, Int32&amp; dataLength)&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Searching on the web, many developers seem to solve the problem at least partially by generating a static key as described in &lt;a href="http://support.microsoft.com/default.aspx?scid=kb;en-us;Q312906"&gt;Microsoft's knowledge base&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;This is a workaround but not an actual solution to the problem, at least in my scenario where my application runs in a dedicated application pool under limited privileges as described in &lt;a href="http://msdn2.microsoft.com/en-us/library/ms998297.aspx"&gt;http://msdn2.microsoft.com/en-us/library/ms998297.aspx&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The fix is to run &lt;strong&gt;aspnet_regiis.exe –ga DOMAIN\USER&lt;/strong&gt; where USER is the identity of the application pool. Also make sure the user is part of the IIS_WPG group.&lt;/p&gt;&lt;p&gt;This command gives not only access to the IIS metabase but also creates the registry keys required in&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ASP.NET\2.0.50727.0\AutoGenKeys&lt;/span&gt;&lt;/p&gt;&lt;p&gt;for the application pool to generate machine keys.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-5586101279077082306?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/5586101279077082306/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=5586101279077082306' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/5586101279077082306'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/5586101279077082306'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2007/01/unable-to-validate-data-error-in.html' title='Unable to validate data error in relation to machine key'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-7464759503289220654</id><published>2006-12-22T10:39:00.000Z</published><updated>2006-12-22T10:44:44.526Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Data access'/><title type='text'>Touchy connection strings</title><content type='html'>&lt;p&gt;My ASP.NET 2.0 / SQL Server 2005 application was working perfectly in my development environment but I experienced the following error message when testing deployment in a Windows 2003 virtual machine:&lt;/p&gt;&lt;p&gt;"A connection was successfully established with the server, but then an error occurred during the login process. (provider: Shared Memory Provider, error: 0 - No process is on the other end of the pipe.)".&lt;/p&gt;&lt;p&gt;My connection string was:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;Server=localhost;Database=myDB;Integrated Security=SSPI;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Simply changing it to the following solved the issue:&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;Data Source=.;Initial Catalog=myDB;Integrated Security=True;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Considering both shared memory and TCP/IP where enabled in both environments, I can neither explain why the issue occurred or why the change above solved it. If someone can, please leave a comment.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-7464759503289220654?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/7464759503289220654/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=7464759503289220654' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/7464759503289220654'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/7464759503289220654'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/12/touchy-connection-strings.html' title='Touchy connection strings'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-6096338700327176797</id><published>2006-12-21T07:06:00.000Z</published><updated>2006-12-22T10:45:14.871Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>Diagnosing "aspnet_merge.exe exited with code 1” error in Web Deployment Projects</title><content type='html'>&lt;p&gt;For those that have problems with Error 24 "aspnet_merge.exe" exited with code 1.&lt;/p&gt;&lt;p&gt;The error is related to a duplicate class name in your web project, i.e. two files which have the same name, generally in different directories.&lt;/p&gt;&lt;p&gt;Those files could be hard to find and the following is a quick way to isolate the problem and find the duplicate names.&lt;/p&gt;&lt;p&gt;In Visual Studio 2005:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Select Tools --&gt; Options.&lt;/li&gt;&lt;li&gt;Then in the Projects and Solutions branch, select Build and Run.&lt;/li&gt;&lt;li&gt;You'll see a dropdown box for MSBuild Project Build Output Verbosity. Change this to Diagnostic, and OK.&lt;/li&gt;&lt;li&gt;Show your build output by selecting the View --&gt; Output option.&lt;/li&gt;&lt;li&gt;Make sure that in the 'Show output from' box, you've selected "Build".&lt;/li&gt;&lt;li&gt;Then just build your project, and wait for the inevitable fail. You will see where the duplicates are when it fails to build.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;This tip has been posted by Simon Morgan on &lt;a href="http://weblogs.asp.net/scottgu/archive/2005/11/06/429723.aspx"&gt;http://weblogs.asp.net/scottgu/archive/2005/11/06/429723.aspx&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-6096338700327176797?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/6096338700327176797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=6096338700327176797' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/6096338700327176797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/6096338700327176797'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/12/diagnosing-aspnetmergeexe-exited-with.html' title='Diagnosing &quot;aspnet_merge.exe exited with code 1” error in Web Deployment Projects'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-1720653821500332741</id><published>2006-12-19T21:19:00.000Z</published><updated>2007-08-15T17:39:11.676+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><title type='text'>New incompatibility between ASP.NET Ajax 1.0 RC and Google AdSense</title><content type='html'>Run the following ASP.NET page in IE7 and you will get a Javascript error:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;%@ Page Language="C#" %&amp;gt;&lt;br /&gt;&amp;lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&amp;gt;&lt;br /&gt;&amp;lt;script runat="server"&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;html xmlns="http://www.w3.org/1999/xhtml" &amp;gt;&lt;br /&gt;&amp;lt;head runat="server"&amp;gt;&lt;br /&gt;    &amp;lt;title&amp;gt;Untitled Page&amp;lt;/title&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;asp:ScriptManager ID="ScriptManager" runat="server" &amp;gt;&lt;br /&gt;    &amp;lt;Scripts&amp;gt;&lt;br /&gt;        &amp;lt;asp:ScriptReference Name="PreviewScript.js" Assembly="Microsoft.Web.Preview" /&amp;gt;&lt;br /&gt;    &amp;lt;/Scripts&amp;gt;&lt;br /&gt;&amp;lt;/asp:ScriptManager&amp;gt;&lt;br /&gt;&amp;lt;div&amp;gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&amp;gt;&amp;lt;!--&lt;br /&gt;google_ad_client = "pub-6623312146541354";&lt;br /&gt;google_ad_width = 250;&lt;br /&gt;google_ad_height = 250;&lt;br /&gt;google_ad_format = "250x250_as";&lt;br /&gt;google_ad_type = "text";&lt;br /&gt;google_ad_channel = "";&lt;br /&gt;google_color_border = "000000";&lt;br /&gt;google_color_bg = "F0F0F0";&lt;br /&gt;google_color_link = "0000FF";&lt;br /&gt;google_color_text = "000000";&lt;br /&gt;google_color_url = "008000";&lt;br /&gt;//--&amp;gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;script type="text/javascript"&lt;br /&gt;  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&amp;gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/div&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;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-1720653821500332741?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/1720653821500332741/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=1720653821500332741' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/1720653821500332741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/1720653821500332741'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/12/new-incompatibility-between-aspnet-ajax.html' title='New incompatibility between ASP.NET Ajax 1.0 RC and Google AdSense'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-1483707409831005541</id><published>2006-12-19T21:16:00.000Z</published><updated>2007-08-15T17:38:09.611+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>ASP.NET Ajax page method on login page requires setting location in web.config</title><content type='html'>I have spent quite a while on this one, so I deliver my findings here hoping that it will help.&lt;br /&gt;&lt;br /&gt;If you have an ASP.NET web site with forms authentication and your login page has an ASP.NET Ajax extensions page method, this method will not work unless you set:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;location path="login.aspx"&amp;gt;&lt;br /&gt;       &amp;lt;system.web&amp;gt;&lt;br /&gt;              &amp;lt;authorization&amp;gt;&lt;br /&gt;                     &amp;lt;allow users="*"/&amp;gt;&lt;br /&gt;              &amp;lt;/authorization&amp;gt;&lt;br /&gt;       &amp;lt;/system.web&amp;gt;&lt;br /&gt;&amp;lt;/location&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt; Otherwise, the call to ~/login.aspx/yourScriptMethod fails because it is not authenticated.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-1483707409831005541?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/1483707409831005541/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=1483707409831005541' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/1483707409831005541'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/1483707409831005541'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/12/aspnet-ajax-page-method-on-login-page.html' title='ASP.NET Ajax page method on login page requires setting location in web.config'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-6262578596298595996</id><published>2006-12-14T15:47:00.000Z</published><updated>2007-08-15T17:39:33.630+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Javascript'/><title type='text'>“debugger”, the magic JavaScript statement</title><content type='html'>&lt;em&gt;This post is dedicated to all the Javascript programmers who still use alerts to debug their code.&lt;br /&gt;&lt;/em&gt;&lt;br /&gt;Not sure about you, but I have always struggled to set and enable Visual Studio breakpoints to debug my Javascript code until I have found about a magic statement named &lt;span style="font-family:courier new;"&gt;&lt;strong&gt;debugger&lt;/strong&gt;&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;To use it:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Make sure “Disable Script Debugging” is unchecked in Internet Explorer, Tools (menu) -&gt; Internet Options… (submenu) -&gt; Advanced (tab) -&gt; Browsing (node).&lt;/li&gt;&lt;li&gt;Put the &lt;span style="font-family:courier new;"&gt;&lt;strong&gt;debugger;&lt;/strong&gt;&lt;/span&gt; statement anywhere in your code where you want the breakpoint.&lt;/li&gt;&lt;li&gt;Execute your web application and when the browser script engine interprets the statement, it launches the debugger and breaks on the statement line.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-6262578596298595996?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/6262578596298595996/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=6262578596298595996' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/6262578596298595996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/6262578596298595996'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/12/debugger-magic-javascript-statement.html' title='“debugger”, the magic JavaScript statement'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-2811113661313828652</id><published>2006-11-27T15:13:00.000Z</published><updated>2007-08-15T17:38:42.311+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Ajax'/><title type='text'>Migration from Atlas July CTP to ASP.NET Ajax Beta 2</title><content type='html'>&lt;p&gt;I am developing an application which does not really make use of Atlas controls but has a significant amount of Atlas scripting code to migrate.&lt;/p&gt;&lt;p&gt;I am not found of declarative scripting but maybe I am old-fashioned: I like to step through my code to debug it. My opinion is that declarative scripting is only good as the output of code-generation tools. It is not something that developers should write in a text editor.&lt;/p&gt;&lt;p&gt;So, I have got script to migrate and I have read the documentation available at:&lt;/p&gt;&lt;ul type="disc"&gt;&lt;li&gt;&lt;a href="http://weblogs.asp.net/scottgu/archive/2006/11/08/ASP.NET-AJAX-1.0-Beta-2-Release.aspx"&gt;http://weblogs.asp.net/scottgu/archive/2006/11/08/ASP.NET-AJAX-1.0-Beta-2-Release.aspx&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://ajax.asp.net/files/AspNet_AJAX_CTP_to_Beta_Whitepaper.doc"&gt;http://ajax.asp.net/files/AspNet_AJAX_CTP_to_Beta_Whitepaper.doc&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://ajax.asp.net/files/Migration%20Guide.doc"&gt;http://ajax.asp.net/files/Migration%20Guide.doc&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://ajax.asp.net/docs/default.aspx"&gt;http://ajax.asp.net/docs/default.aspx&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;p&gt;Downloading and installing ASP.NET Ajax Beta 2 is well explained in the documentation but I had to do a bit of guessing as well as exploring Microsoft’s code to migrate my own code. I deliver my findings below:&lt;/p&gt;&lt;h4&gt;Migrating client script&lt;/h4&gt;&lt;ol type="1"&gt;&lt;li&gt;To use client scripting of html components, you need to add a reference to PreviewScript.js in your ScriptManager as shown below:&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;        &amp;lt;asp:ScriptManager ID="ScriptManager" runat="server"&amp;gt;&lt;br /&gt;        &amp;lt;Scripts&amp;gt;&lt;br /&gt;        &amp;lt;asp:ScriptReference Assembly="Microsoft.Web.Preview"&lt;br /&gt;        Name="Microsoft.Web.Resources.ScriptLibrary.PreviewScript.js"/&amp;gt;&lt;br /&gt;        &amp;lt;/Scripts&amp;gt;&lt;br /&gt;        &amp;lt;/asp:ScriptManager&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;ol type="1" start="2"&gt;&lt;li&gt;$(id) is now $get(id)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The Sys.UI namespace is now Sys.Preview.UI&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Sys.UI.Select is now Sys.Preview.UI.Selector&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Sys.UI.CheckBox.click.add(handler) is now Sys.UI.Preview.CheckBox.add_click(handler)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Sys.UI.Select.selectionChanged.add(handler) is now Sys.Preview.UI.Selector.add_selectionChanged(handler)&lt;/li&gt;&lt;br /&gt;&lt;li&gt;$addHandler/$removeHandler is the new way to add event handlers&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Sys.UI.Control.get_enabled() and set_enabled() no more work&lt;/li&gt;&lt;/ol&gt;&lt;h4&gt;Migrating web service calls&lt;/h4&gt;&lt;ol type="1"&gt;&lt;li&gt;You need to decorate your web services and page methods with new attributes as explained in &lt;a href="http://blogs.msdn.com/sburke/archive/2006/10/21/hint-components-that-use-web-services-with-asp-net-ajax-v1-0-beta.aspx"&gt;http://blogs.msdn.com/sburke/archive/2006/10/21/hint-components-that-use-web-services-with-asp-net-ajax-v1-0-beta.aspx&lt;/a&gt;.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;The prototype of asynchronous calls to web services and page methods has been simplified, but this is well explained in the documentation listed above.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-2811113661313828652?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/2811113661313828652/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=2811113661313828652' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/2811113661313828652'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/2811113661313828652'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/11/migration-from-atlas-july-ctp-to-aspnet.html' title='Migration from Atlas July CTP to ASP.NET Ajax Beta 2'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-3024452581296618602</id><published>2006-11-24T16:43:00.000Z</published><updated>2006-11-24T16:52:40.780Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='SMTP'/><category scheme='http://www.blogger.com/atom/ns#' term='IIS'/><title type='text'>How to configure the IIS SMTP Service to send emails from ASP.NET code?</title><content type='html'>&lt;p&gt;I have probably configured the IIS SMTP service a dozen times over the past five years but I still struggle with authentication and relay, so I have decided to write this note once and for all.&lt;/p&gt;&lt;p&gt;First, the source for your System.Net.Mail issues is definitely &lt;a href="http://www.systemnetmail.com/"&gt;http://www.systemnetmail.com/&lt;/a&gt;, including some sample code.&lt;/p&gt;&lt;p&gt;Because we are all urged to deliver rapidly, I have provided a test application which you can download from &lt;a href="http://www.velodoc.com/downloads/061124.blog.zip"&gt;http://www.velodoc.com/downloads/061124.blog.zip&lt;/a&gt;. Contrary to most samples that you will find on the Internet, this one uses a configuration file including system.net\mailSettings, which is probably the way you want to send emails from your ASP.NET code.&lt;/p&gt;&lt;p&gt;Obviously you need to install the SMTP Service, which is well explained at &lt;a href="http://msdn2.microsoft.com/en-us/library/8b83ac7t.aspx"&gt;http://msdn2.microsoft.com/en-us/library/8b83ac7t.aspx&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Let’s say you need to send your emails from &lt;a href="mailto:website@yourdomain.tld"&gt;website@yourdomain.tld&lt;/a&gt;. In this case, it is recommended (but not required) that you rename the default domain into yourdomain.tld.&lt;/p&gt;&lt;p&gt;Display the default SMTP Virtual Server properties and on the Access tab:&lt;/p&gt;&lt;ol type="1"&gt;&lt;li&gt;Configure authentication by removing Anonymous access and allowing Basic authentication and/or integrated Windows authentication;&lt;/li&gt;&lt;li&gt;Grant relay to 127.0.0.1 and allow all computers which successfully authenticate to relay.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br /&gt;&lt;/p&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/x/blogger2/8066/2278/320/387886/061124a.png" border="0" /&gt;You can certainly be more restrictive depending on your requirements, once you got teh above configuration to work properly.&lt;br /&gt;&lt;br /&gt;Finally, you can create a dedicated account and properly configure your settings:&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;system.net&amp;gt;&amp;lt;mailSettings&amp;gt;&lt;br /&gt;&amp;lt;smtp deliveryMethod="Network" from="website@yourdomain.tld"&amp;gt;&lt;br /&gt;&amp;lt;network host="127.0.0.1" port="25" userName="DOMAIN\account" password="password"/&amp;gt;&lt;br /&gt;&amp;lt;/smtp&amp;gt;&lt;br /&gt;&amp;lt;/mailSettings&amp;gt;&lt;br /&gt;&amp;lt;/system.net&amp;gt;&lt;/span&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-3024452581296618602?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/3024452581296618602/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=3024452581296618602' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/3024452581296618602'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/3024452581296618602'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/11/how-to-configure-iis-smtp-service-to.html' title='How to configure the IIS SMTP Service to send emails from ASP.NET code?'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-430431067851406012</id><published>2006-11-24T08:32:00.000Z</published><updated>2006-11-24T09:49:42.113Z</updated><title type='text'>What’s next after designing and hosting your web site?</title><content type='html'>&lt;p&gt;You have now designed a nice web site which you have uploaded on a hosted server and you think you are ready to go. Not quite right. There are a few more steps required which will guarantee a better visibility of your web site.&lt;/p&gt;&lt;p&gt;I am not a search engine optimization (SEO) professional and qualified people are writing books about SEO which can be a very complex subject. But I have been confronted to the issue, I have searched for answers on the Internet and I publish here my findings. If you apply the 80-20 Pareto rule, you can get decent results in three steps that you may want to re-iterate periodically:&lt;/p&gt;&lt;ol type="1"&gt;&lt;li&gt;Make your web site is right for search engine crawling robots;&lt;/li&gt;&lt;li&gt;Submit your web site to search engines;&lt;/li&gt;&lt;li&gt;Get referral links.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;p&gt;I may have done something right since I have managed to get our web site on the first page on MSN and Yahoo. I know from experience that the only way to get a high ranking on Google is to obtain referral links.&lt;/p&gt;&lt;h4&gt;1) Make your web site right&lt;/h4&gt;&lt;p&gt;First, you need to make sure that search engine robots can read your web site. You also need to assist search engine robots by telling them which pages to index and how to categorize your web site.&lt;/p&gt;&lt;h5&gt;Make sure your HTML is compliant&lt;/h5&gt;&lt;p&gt;A web design environment like Dreamweaver will warn you of any non-compliance issue. You can also use a text browser like Lynx to check that your web site displays properly to search engines. Note that search engine robots read sites in a similar way. You can also check your pages at &lt;a href="http://www.smart-it-consulting.com/internet/google/googlebot-spoofer/index.htm"&gt;http://www.smart-it-consulting.com/internet/google/googlebot-spoofer/index.htm&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Important also is to set the page encoding and content language. I personally recommend using utf-8 encoding even on English pages. Contrary to what people often think, utf-8 is not double byte and the size of an English page is the same in utf-8 and iso-8859-1.&lt;/p&gt;&lt;h5&gt;Describe your web site properly&lt;/h5&gt;&lt;p&gt;Title, meta description, meta keywords and images alternate text contribute to help search engines categorize your web site properly.&lt;/p&gt;&lt;p&gt;Getting your keywords right is a difficult exercise:&lt;/p&gt;&lt;ol type="1"&gt;&lt;li&gt;you should limit yourself to 10 to 20 keywords;&lt;/li&gt;&lt;li&gt;the more targeted your keywords the more efficient they are to help find you, but you do not want to be too narrow;&lt;/li&gt;&lt;li&gt;As far as Google, Yahoo and MSN are concerned, you do not need both the singular and plural of a keyword and the order of words in a keyword seems to make no difference.&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;p&gt;The following tools will help your build your keywords meta tag:&lt;/p&gt;&lt;ol type="1" start="3"&gt;&lt;ul type="disc"&gt;&lt;li&gt;&lt;a href="http://www.wordtracker.com/"&gt;http://www.wordtracker.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://adwords.google.com/select/KeywordToolExternal"&gt;https://adwords.google.com/select/KeywordToolExternal&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://inventory.overture.com/"&gt;http://inventory.overture.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://tools.seobook.com/general/keyword/"&gt;http://tools.seobook.com/general/keyword/&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/ol&gt;&lt;h5&gt;Add an address and a privacy policy&lt;/h5&gt;&lt;p&gt;An address and a privacy policy will not give you a high ranking, but they may prevent you from getting one because you won’t look like a serious company. To add a privacy policy for your site, follow the steps at &lt;a href="http://www.the-dma.org/privacy/creating.shtml#form"&gt;http://www.the-dma.org/privacy/creating.shtml#form&lt;/a&gt;.&lt;/p&gt;&lt;h5&gt;Add content rating&lt;/h5&gt;&lt;p&gt;To add content rating for your site, follow the steps at &lt;a href="http://www.icra.org/label/"&gt;http://www.icra.org/label/&lt;/a&gt;&lt;/p&gt;&lt;h5&gt;Create sitemaps&lt;/h5&gt;&lt;p&gt;Sitemaps will tell search engines which pages to look for. To create sitemaps, follow the steps at &lt;a href="http://www.xml-sitemaps.com/"&gt;http://www.xml-sitemaps.com/&lt;/a&gt;. You can get more information at &lt;a href="http://www.sitemaps.org/"&gt;http://www.sitemaps.org/&lt;/a&gt;. &lt;/p&gt;&lt;p&gt;You are encouraged to submit your sitemaps to search engines, in particular:&lt;/p&gt;&lt;ul type="disc"&gt;&lt;li&gt;&lt;a href="http://www.google.com/webmasters/"&gt;http://www.google.com/webmasters/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="https://siteexplorer.search.yahoo.com/mysites"&gt;https://siteexplorer.search.yahoo.com/mysites&lt;/a&gt;/&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;h5&gt;Create a robot.txt file&lt;/h5&gt;&lt;p&gt;You create a robots.txt file essentially to tell which parts of your site not to index. More information about robots.txt files is available at &lt;a href="http://www.robotstxt.org/wc/robots.html"&gt;http://www.robotstxt.org/wc/robots.html&lt;/a&gt;.&lt;/p&gt;&lt;h5&gt;Add web site monitoring and statistics&lt;/h5&gt;&lt;p&gt;If your web site is too often inaccessible, you will be downgraded by search engines. Accordingly, you need to monitor your web site and keep your ISP honest. The following monitoring services range from free to high-end:&lt;/p&gt;&lt;ul type="disc"&gt;&lt;li&gt;&lt;a href="http://site24x7.com/"&gt;http://site24x7.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.hyperspin.com/"&gt;http://www.hyperspin.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.alertra.com/"&gt;http://www.alertra.com/&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.alertsite.com/"&gt;http://www.alertsite.com/&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;p&gt;Most hosting packages come with AWStats and Webalizer which give poor statistics. There is obviously &lt;a href="http://www.webtrends.com/"&gt;http://www.webtrends.com/&lt;/a&gt; but I can only recommend the free &lt;a href="http://www.google.com/analytics/"&gt;http://www.google.com/analytics/&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;2) Submit your web site to search engines&lt;/h4&gt;&lt;p&gt;Most ISPs offer search engine submission standard with hosting packages. Unless you are very lazy, do not pay for a submission service and do not buy submission software. Submitting your URLs to Google, MSN and Yahoo only takes 10 minutes and covers for more than 80% of the search engine traffic.&lt;/p&gt;&lt;p&gt;This is especially true if you already own a web site that is referenced. In this case, you just need a hyperlink from the referenced web site to the new web site and the search engine crawlers will automatically index your new site. &lt;/p&gt;&lt;h4&gt;3) Get referral links&lt;/h4&gt;&lt;p&gt;Getting referral links is the only thing that guarantees high rankings. Basically, the more a page is referenced on the web, the best the value of this page to the Internet community, so the highest ranking it gets in searches. Additionally, a reference on the &lt;a href="http://www.bbc.co.uk/"&gt;http://www.bbc.co.uk/&lt;/a&gt; web site is worth more than a reference on &lt;a href="http://www.acme.tf/"&gt;http://www.acme.tf/&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;So you need to work on getting other web sites to reference your own web site. This is an everyday job that only your organization can successfully perform. You should get a decent ranking on Google (top 3 pages) with about 100 references but obviously some topics are more crowded than others. The earlier you start the better. Good luck!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-430431067851406012?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/430431067851406012/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=430431067851406012' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/430431067851406012'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/430431067851406012'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/11/whats-next-after-designing-and-hosting.html' title='What’s next after designing and hosting your web site?'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-4076665249910811697</id><published>2006-11-23T13:55:00.000Z</published><updated>2006-12-14T15:51:22.272Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='SMTP'/><title type='text'>Troubleshooting SMTP using Telnet</title><content type='html'>Today, I have been confronted to configuring Virtuozzo + Plesk on our new VPS web site server to send emails from ASP.NET code.&lt;br /&gt;&lt;br /&gt;On our old Plesk 7 server, we used to send emails from an email account which had no mailbox but the same configuration did not seem to work in the more recent Plesk 7.6. I am not a Plesk aficionado, so I went the old way to find out what was going wrong.&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Open a command windows by typing cmd in the Start -&gt; Run… dialog box and click OK.&lt;/li&gt;&lt;li&gt;At the prompt, type telnet mail.yourdomain.tld 25 + Enter&lt;/li&gt;&lt;li&gt;The mail server should display version information.&lt;/li&gt;&lt;li&gt;Type HELO + Enter.&lt;/li&gt;&lt;li&gt;Type AUTH LOGIN + Enter.&lt;/li&gt;&lt;li&gt;Type your mailbox username or username@ yourdomain.tld encoded in base64 + Enter. ESMTP requires a login in the form username@ yourdomain.tld. A helpful site to get a base64 encoded value is &lt;a href="http://www.motobit.com/util/base64-decoder-encoder.asp"&gt;http://www.motobit.com/util/base64-decoder-encoder.asp&lt;/a&gt;.&lt;/li&gt;&lt;li&gt;Type your mailbox password encoded in base64 + Enter.&lt;/li&gt;&lt;li&gt;If you have successfully authenticated, the server will reply "235 authenticated".&lt;/li&gt;&lt;li&gt;Type MAIL FROM: username@ yourdomain.tld + Enter.&lt;/li&gt;&lt;li&gt;Type RCPT TO: anothermailbox@ yourdomain.tld + Enter.&lt;/li&gt;&lt;li&gt;Type DATA + Enter.&lt;/li&gt;&lt;li&gt;Type Subject: Test + Enter + Enter (Send a blank line to separate the headers from the message body).&lt;/li&gt;&lt;li&gt;Type SMTP test + Enter.&lt;/li&gt;&lt;li&gt;Type . + Enter (a dot, then Enter).&lt;/li&gt;&lt;li&gt;The server should reply "250 Message queued"&lt;/li&gt;&lt;li&gt;Type QUIT + Enter.&lt;/li&gt;&lt;li&gt;Close the command window and check your mailbox.&lt;/li&gt;&lt;/ol&gt;In my case, the message that I was getting in .NET was “no email account can send to anothermailbox@ yourdomain.tld”, which is not very helpful but the procedure above was showing that step 8 was actually going wrong. After a few changes in the Plesk configuration I have discovered that the email account required a mailbox to send emails.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-4076665249910811697?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/4076665249910811697/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=4076665249910811697' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/4076665249910811697'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/4076665249910811697'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/11/troubleshooting-smtp-using-telnet.html' title='Troubleshooting SMTP using Telnet'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-1026025808510520951</id><published>2006-11-23T13:16:00.000Z</published><updated>2006-11-24T09:40:24.119Z</updated><title type='text'>Translating a web site into Chinese and Japanese</title><content type='html'>We are a small company selling software as a service. Most  of our leads come from advertising on Google, MSN and Yahoo and although we are  European, 70% of our customer base is located in the US. This is not surprising because  our web site is only available in English and French and our advertising too.  Considering that most of our competitors are located in the US too, we can assume that the cost of a lead in  the US  is much higher. So we have decided to tap into the great reservoir of non  English-speaking countries and have our web site translated in 8 languages,  among which Chinese and Japanese.&lt;h4&gt;Word documents&lt;/h4&gt;We have put our web content into Word 2003 to get it  translated by professional translators. Obviously the Chinese and Japanese  documents that we have received were not properly displayed in Word. We have  found on the web that we had to install the Proofing Tools for Microsoft Office  to display the content, which we have done and it works. We have realized later  on a computer that had downloaded the Asian language packs for Internet  Explorer that this is another way to get the Japanese and Chinese content  properly displayed in Office, and contrary to the Proofing Tools, it is free.  In fact Word 2003 is Unicode and you just need the proper fonts.&lt;h4&gt;Html pages&lt;/h4&gt;The next step is to get the Word document into HTML.  Apparently copying and pasting from Word to Dreamweaver works quite well but I  have had so many issues in the past with the way Word handles HTML that I have  preferred another way. You need to choose whether you will have an UTF-8  encoded page or whether you will use a code page (GB 2312 for simplified  Chinese). A code page will produce a more compact file but this is the old way.  We have decided to use UTF-8 for our entire site. In Word, save your word  document as “filtered html” and in the Save As dialog select “Web options”.  Select the UTF-8 encoding and a simplified Chinese font. Do the same for  Japanese. Then you can open your new html document in Dreamweaver and copy  paste reliably within Dreamweaver.&lt;p&gt;You will need to add the following meta tags in your  translated html pages:&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;meta  http-equiv="Content-Type" content="text/html;  charset=UTF-8" /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;meta http-equiv="Content-Language"  content="zh" /&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;Images&lt;/h4&gt;We use Adobe ImageReady and Macromedia Fireworks for our  images. Fireworks is less powerful but the use of the PNG file format makes it  much easier to maintain large quantities of image files because Windows  Explorer displays the thumbnails. When you copy Chinese characters from Word or  Html into ImageReady, only half of them display properly and the others are  replaced by question marks. In fact ImageReady selects the MS Gothic font by  default when it should paste SimHei or SimSon. These fonts are not even  displayed in the font drop-down list but you can key in the font name and this  works.&lt;br /&gt;&lt;br /&gt;Finally, no matter how well you prepare your work with the translators,  you will realize that some strings will be too long to fit your buttons or some  last minute changes will not have been taken into account or else and you will find  much easier to get an approximate automated translation from &lt;a href="http://www.systransoft.com/index.html"&gt;http://www.systransoft.com/index.html&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;&lt;h2&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/x/blogger2/8066/2278/1600/218083/061123a.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/x/blogger2/8066/2278/320/587931/061123a.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;/h2&gt; You can check the result at &lt;a href="http://www.velodoc.com/"&gt;http://www.velodoc.com/zh/&lt;/a&gt; and &lt;a href="http://www.velodoc.com/ja/"&gt;http://www.velodoc.com/ja/&lt;/a&gt;.    To download the Asian Pack, simply select View -&amp;gt; Encoding -&amp;gt; More -&amp;gt;  Chinese Simplified in Internet Explorer.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-1026025808510520951?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/1026025808510520951/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=1026025808510520951' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/1026025808510520951'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/1026025808510520951'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/11/translating-web-site-into-chinese-and.html' title='Translating a web site into Chinese and Japanese'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-996071601320420361</id><published>2006-11-22T11:05:00.000Z</published><updated>2006-11-22T11:46:02.741Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><title type='text'>Resumable file downloads in ASP.NET</title><content type='html'>The &lt;a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html"&gt;http protocol&lt;/a&gt; implements the ACCEPT-RANGES and ETAG response headers to signify the ability to download resources in chunks. There is an interesting &lt;a href="http://msdn.microsoft.com/msdnmag/issues/06/09/WebDownloads/default.aspx"&gt;article published in MSDN magazine&lt;/a&gt; which has some sample code implemented in VB.NET. For the records, similar implementations can be found at:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;&lt;a href="http://www.thescripts.com/forum/thread334139.html"&gt;http://www.thescripts.com/forum/thread334139.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.devx.com/dotnet/Article/22533/0/page/1"&gt;http://www.devx.com/dotnet/Article/22533/0/page/1&lt;/a&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;I have made a C# implementation of this code which you can download from &lt;a href="http://www.velodoc.com/downloads/061122.blog.zip"&gt;http://www.velodoc.com/downloads/061122.blog.zip&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;To use this code, you need to:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Create a C# class library named “Memba.FileDownload” or whatever name you deem more appropriate and add the two class files from the archive.&lt;/li&gt;&lt;li&gt;Create a web site and add the following to the system.web/httpHandlers section of the web.config:&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;add type="Memba.FileDownload.DownloadHandler, Memba.FileDownload" validate="false" path="*.zip" verb="*"/&amp;gt;&lt;/span&gt;&lt;/li&gt;&lt;li&gt;You also need to make sure the zip extension is &lt;a href="http://www.microsoft.com/technet/prodtechnol/WindowsServer2003/Library/IIS/4c840252-fab7-427e-a197-7facb6649106.mspx"&gt;mapped to the aspnet_isapi.dll&lt;/a&gt; in the IIS management snap-in otherwise your handler will not be called.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;To test this code, download a zip file hosted on the web site you have just created. You should be able to stop and resume the download in Internet Explorer or any download manager which supports resumable downloads.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-996071601320420361?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/996071601320420361/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=996071601320420361' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/996071601320420361'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/996071601320420361'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/11/resumable-file-downloads-in-aspnet.html' title='Resumable file downloads in ASP.NET'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-3144683305036500010</id><published>2006-11-22T10:12:00.000Z</published><updated>2006-11-22T10:47:57.742Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><title type='text'>Where do you get your icons from?</title><content type='html'>I have never been able to find a decent royalty-free library of icons but you only have what you pay for, haven’t you?&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.iconexperience.com/"&gt;IconExperience&lt;/a&gt; is the best library I have found and I can only recommend it. It is comprehensive and affordable. Incors have just released version 2.0 which has more than 2000 icons and now includes the 128*128 format.&lt;br /&gt;&lt;br /&gt;If you know any other valuable source of icons, please comment.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-3144683305036500010?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/3144683305036500010/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=3144683305036500010' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/3144683305036500010'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/3144683305036500010'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/11/where-do-you-get-your-icons-from.html' title='Where do you get your icons from?'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-116176174285762076</id><published>2006-10-25T08:35:00.000+01:00</published><updated>2007-08-15T17:41:43.534+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Velodoc'/><category scheme='http://www.blogger.com/atom/ns#' term='Vista'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><title type='text'>Designing gadgets and widgets for uploading files to Memba Velodoc</title><content type='html'>&lt;strong&gt;&lt;em&gt;&lt;span style="font-family:Arial;font-size:130%;"&gt;Requirements&lt;/span&gt;&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;A sender, a Receiver, a Subject, a Message, a File to upload and a checkbox to accept terms (see &lt;a href="http://www.velodoc.net/login.aspx"&gt;www.velodoc.net/login.aspx&lt;/a&gt;);&lt;/li&gt;&lt;li&gt;A progress bar to monitor upload progress;&lt;/li&gt;&lt;li&gt;A professional look &amp; feel;&lt;/li&gt;&lt;li&gt;To be developed in 3 to 5 days max.&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;&lt;em&gt;&lt;span style="font-family:Arial;font-size:130%;"&gt;Reference documentation&lt;/span&gt;&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://windowssdk.msdn.microsoft.com/en-us/library/ms722795.aspx"&gt;http://windowssdk.msdn.microsoft.com&lt;br /&gt;/en-us/library/ms722795.aspx&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/sidebar/sidebar/overviews/gdo.asp"&gt;http://msdn.microsoft.com/library/default.asp?&lt;br /&gt;url=/library/en-us/sidebar/sidebar/overviews/gdo.asp&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://microsoftgadgets.com/Sidebar/DevelopmentOverview.aspx"&gt;http://microsoftgadgets.com/Sidebar/&lt;br /&gt;DevelopmentOverview.aspx&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.microsoft.com/technet/scriptcenter/topics/vista/gadgets-pt1.mspx"&gt;http://www.microsoft.com/technet/scriptcenter/&lt;br /&gt;topics/vista/gadgets-pt1.mspx&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;&lt;em&gt;&lt;span style="font-family:Arial;font-size:130%;"&gt;Findings and impact on technologies&lt;/span&gt;&lt;/em&gt;&lt;/strong&gt;&lt;br /&gt;A windows sidebar gadget is a piece of DHTML hosted in the sidebar. Generally what you can do with DHTML can be done in a gadget.&lt;br /&gt;&lt;br /&gt;There are limitations though, most of which are related to the browser security sandbox. Effectively a gadget is hosted locally, which has impacts on how it can communicate with remote web sites.&lt;br /&gt;&lt;br /&gt;In particular, developing a file upload gadget with a progress bar in DHTML requires a cross-domain iFrame and scripting the iFrame in this case is forbidden. I have tried two nested iFrames which gives you scripting but the deepest iFrame opens in a new browser window instead of within the gadget. The only workaround I have found in half a day is to display the progress bar in a new browser window, but this does not look good and I was not prepared to lose more time.&lt;br /&gt;&lt;br /&gt;So, I have considered XBAP WPF browser applications and although there is no File Upload control, I seem to have found the foundations for a file upload gadget here:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://blogs.msdn.com/mszcool/archive/2006/04/25/583317.aspx"&gt;http://blogs.msdn.com/mszcool/archive/2006/04/25/&lt;br /&gt;583317.aspx&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://blogs.msdn.com/karstenj/archive/2006/10/04/WPF-Vista-Gadgets-_2D00_-Part-1_3A00_-Using-XBAP-and-IFRAME.aspx"&gt;http://blogs.msdn.com/karstenj/archive/2006/10/04/&lt;br /&gt;WPF-Vista-Gadgets-_2D00_-Part-1_3A00_-Using-XBAP-and-IFRAME.aspx&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://laurenlavoie.com/avalon/154"&gt;http://laurenlavoie.com/avalon/154&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/csharp/uploadfileex.asp"&gt;http://www.codeproject.com/csharp/uploadfileex.asp&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;But WPF development is really early stage, development environment is primitive, documentation is lacking and I got worried about some warnings related to the sandbox that are mentioned in the literature quoted above.&lt;br /&gt;&lt;br /&gt;In these circumstances, the only alternative was Macromedia Flash. I have even found a couple of examples running on the web. I have hosted them within an iFrame of a bespoke gadget and there I was: at the end of day one, I had my design and a fully functional (but ugly) prototype. Further documentation is available at:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://livedocs.macromedia.com/labs/as3preview/docs/00000142.html"&gt;http://livedocs.macromedia.com/labs/as3preview/&lt;br /&gt;docs/00000142.html&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.codeproject.com/aspnet/FlashUpload.asp"&gt;http://www.codeproject.com/aspnet/FlashUpload.asp&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://markshu.ca/imm/flash/tutorial/fileReference.html"&gt;http://markshu.ca/imm/flash/tutorial/fileReference.html&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-116176174285762076?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/116176174285762076/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=116176174285762076' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/116176174285762076'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/116176174285762076'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/10/designing-windows-sidebar-gadget-for.html' title='Designing gadgets and widgets for uploading files to Memba Velodoc'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-116152313863305127</id><published>2006-10-22T14:18:00.001+01:00</published><updated>2006-11-22T10:51:10.895Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><title type='text'>Choosing a GUI library for ASP.NET</title><content type='html'>You can get an exhaustive list of .NET components at &lt;a href="http://www.componentsource.com/"&gt;http://www.componentsource.com/&lt;/a&gt; but if you want a GUI library for ASP.NET, your choice is really between:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Infragistics (&lt;a href="http://www.infragistics.com/"&gt;http://www.infragistics.com/&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;Telerik (&lt;a href="http://www.telerik.com/"&gt;http://www.telerik.com/&lt;/a&gt;)&lt;/li&gt;&lt;li&gt;ComponentArt (&lt;a href="http://www.componentart.com/"&gt;http://www.componentart.com/&lt;/a&gt;)&lt;/li&gt;&lt;/ul&gt;I would not recommend the other vendors for any of the following reasons:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Framework is not sufficiently exhaustive to cover 99% of the requirements;&lt;/li&gt;&lt;li&gt;Vendor has not been around for a sufficiently long time;&lt;/li&gt;&lt;li&gt;Updates are not sufficiently frequent to follow the pace of new developments like Ajax;&lt;/li&gt;&lt;li&gt;Developer license is not royalty-free and/or price is unaffordable;&lt;/li&gt;&lt;/ul&gt;Infragistics, Telerik and ComponentArt have very similar features, pricing and support when you do not dig into the details of each framework. See the &lt;a href="http://www.infoworld.com/Infragistics_NetAdvantage_for_ASP.NET/product_81775.html?view=1&amp;amp;curNodeId=7"&gt;Infoworld comparative article&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I generally find Infragistics to be a richer framework than Telerik and ComponentArt, with two drawbacks: (1) more complex to use and (2) fatter Javascript library to load on the client.&lt;br /&gt;&lt;br /&gt;On the mid-term, ComponentArt may have taken a competitive edge by rewriting its components on top of the Microsoft Ajax framework (code-named Atlas).&lt;br /&gt;&lt;br /&gt;On the long-term, it is difficult to predict the impact of WPF on web interfaces. On one hand, there is a need for richer interfaces that are easier to develop and Microsoft is committed to deliver the technology (WPF/E) and tools to achieve just that. On the other hand, WPF is really nothing more than Flash the Microsoft way, and very few web sites are developed with Flash yet although the Flash plug-in is available on 90% of internet PCs.&lt;br /&gt;&lt;br /&gt;I have personally used Sheridan and now Infragistics controls for years, so I stick with them but if I had to make a new choice now, I would definitely opt for the rewritten ComponentArt controls.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-116152313863305127?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/116152313863305127/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=116152313863305127' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/116152313863305127'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/116152313863305127'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/10/choosing-gui-library-for-aspnet_22.html' title='Choosing a GUI library for ASP.NET'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-116151826881574847</id><published>2006-10-22T12:57:00.000+01:00</published><updated>2006-11-22T10:56:50.844Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Paypal'/><title type='text'>Paypal IPN with UTF8</title><content type='html'>Today, I got stuck a couple of hours on implementing Paypal IPN with UTF-8 encoding. You get loads of examples on the Web and in the documentation with windows-1252 default charset but none with UTF-8 encoding.&lt;br /&gt;&lt;br /&gt;Documentation led me to the wrong track, trying to set the &lt;strong&gt;charset&lt;/strong&gt; and &lt;strong&gt;form-charset&lt;/strong&gt; post fields to UTF-8, but this does not work. You always get a windows-1252 encoded notification.&lt;br /&gt;&lt;br /&gt;When you search for the solution on Google, you mostly get complaints from developers who struggle with it and pretend there are bugs.&lt;br /&gt;&lt;br /&gt;Finally, the solution is obvious (as always). Log to the Paypal web site and go to your profile.&lt;br /&gt;Click the Language Encoding link.&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/blogger/803/1833/320/061020a.0.png" border="0" /&gt;Click the More Options button.&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/blogger/803/1833/320/061020b.png" border="0" /&gt;&lt;br /&gt;Select UTF-8 in the Encoding drop down list. That’s all! &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-116151826881574847?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/116151826881574847/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=116151826881574847' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/116151826881574847'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/116151826881574847'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/10/paypal-ipn-with-utf8.html' title='Paypal IPN with UTF8'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-116073231621865510</id><published>2006-10-13T10:38:00.000+01:00</published><updated>2006-11-22T10:51:44.089Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Visual Studio'/><title type='text'>SourceSafe 2005 issue fixed</title><content type='html'>More than 6 months ago, I have experienced an awkward problem with SourceSafe.&lt;br /&gt;&lt;br /&gt;I periodically run the following script to launch the Analyze tool on SourceSafe databases:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;Dim shell&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;Set shell = CreateObject("WScript.Shell")&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;Dim sVssAnalyzeCmd&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;Dim sVssAnalyzeExe&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;sVssAnalyzeExe = chr(34) &amp; "C:\Program Files\Microsoft Visual SourceSafe\analyze.exe" &amp;amp; chr(34) &amp; " -F -V3 -D "&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;'----------&amp;gt; First Project&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;sVssAnalyzeCmd = sVssAnalyzeExe &amp; chr(34) &amp;amp; "d:\vss2005\project1\data" &amp;amp; chr(34)&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;shell.Run sVssAnalyzeCmd, 7, true&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:+0;"&gt;One day, Analyze was reporting the following error:&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color:#ff6600;"&gt;The file 0\DATA\\ is not a valid SourceSafe physical database file. It must be renamed to a file with an extension or moved to another directory outside the database.&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;I found a curious fix on the web: to work around this problem, rename the physical file for the database root. Use all uppercase letters in the new name.&lt;br /&gt;&lt;br /&gt;I renamed d:\vss2005\project1\data\a\aaaaaaaa into d:\vss2005\project1\data\a\AAAAAAAA and it worked.&lt;br /&gt;&lt;br /&gt;I am glad to realize that a fix has recently been made available by Microsoft at:&lt;br /&gt;&lt;a href="http://support.microsoft.com/kb/923842/en-us"&gt;http://support.microsoft.com/kb/923842/en-us&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-116073231621865510?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/116073231621865510/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=116073231621865510' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/116073231621865510'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/116073231621865510'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/10/sourcesafe-2005-issue-fixed.html' title='SourceSafe 2005 issue fixed'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-116067318134215734</id><published>2006-10-12T18:13:00.000+01:00</published><updated>2006-11-22T10:52:14.249Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>Useful networking tools</title><content type='html'>Today, I was working on integrating a web application with Paypal. My IPN handler in my development environment could not be reached by Paypal, although my test web server was published to the Internet.&lt;br /&gt;&lt;br /&gt;Having searched for simple ways to test a Url from the Internet, I have found the following which I recommend: &lt;a href="http://www.changedetect.com/cd-test-url.asp"&gt;http://www.changedetect.com/cd-test-url.asp&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff9900;"&gt;[Updated on 22 Oct 2006]&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Endeavouring to compare web hosting packages, I have used:&lt;br /&gt;&lt;a href="http://www.vertain.com/?sst"&gt;http://www.vertain.com/?sst&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff9900;"&gt;[Updated on 25 Oct 2006]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;An excellent and still free web site monitoring service is available at:&lt;br /&gt;&lt;a href="http://site24x7.com/"&gt;http://site24x7.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:#ff9900;"&gt;[Updated on 6 Nov 2006]]&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;A comprehensive DNS toolset can be found at:&lt;br /&gt;&lt;a href="http://www.dnsstuff.com/"&gt;http://www.dnsstuff.com/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-116067318134215734?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/116067318134215734/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=116067318134215734' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/116067318134215734'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/116067318134215734'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/10/useful-networking-tools.html' title='Useful networking tools'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-116067052061537404</id><published>2006-10-12T17:28:00.000+01:00</published><updated>2006-11-22T10:57:09.141Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><title type='text'>Preventing page caching and displaying “Page has expired” in ASP.NET 2.0</title><content type='html'>I have found two answers to this question:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;Response.Buffer = True&lt;br /&gt;Response.ExpiresAbsolute = Now().Subtract(New TimeSpan(1, 0, 0, 0))&lt;br /&gt;Response.Expires = 0&lt;br /&gt;Response.CacheControl = "no-cache"&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Source: &lt;a href="http://www.extremeexperts.com/Net/FAQ/DisablingBackButton.aspx"&gt;http://www.extremeexperts.com/Net/FAQ/DisablingBackButton.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Note that Response.Expires is deprecated in ASP.NET and Response.Cache.SetExpires should be used instead.&lt;/em&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;font-size:85%;"&gt;&amp;lt;%@ OutputCache location="none" %&amp;gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;Source: &lt;a href="http://www.syncfusion.com/FAQ/aspnet/WEB_c25c.aspx"&gt;http://www.syncfusion.com/FAQ/aspnet/WEB_c25c.aspx&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;More details at &lt;a href="http://www.c-sharpcorner.com/asp/Articles/CachingInASPDPL.asp"&gt;http://www.c-sharpcorner.com/asp/Articles/CachingInASPDPL.asp&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-116067052061537404?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/116067052061537404/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=116067052061537404' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/116067052061537404'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/116067052061537404'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/10/preventing-page-caching-and-displaying.html' title='Preventing page caching and displaying “Page has expired” in ASP.NET 2.0'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-115790355908092379</id><published>2006-09-10T16:52:00.000+01:00</published><updated>2006-11-22T10:56:07.013Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><title type='text'>Atlas script manager control on login page raises a Javascript error in IE, not in Firefox</title><content type='html'>The error reported by IE is the following:&lt;br /&gt;&lt;br /&gt;&lt;p align="left"&gt;&lt;img style="DISPLAY: block; MARGIN: 0px auto 10px; CURSOR: hand; TEXT-ALIGN: center" alt="" src="http://photos1.blogger.com/blogger/803/1833/320/060910a.png" border="0" /&gt;&lt;/p&gt;If you execute the code carefully in the debugger or use a request analyzer like Fiddler, you will realize that the script manager control requires &lt;a href="http://localhost:3261/WebApp/atlasglob.axd"&gt;http://localhost:3261/WebApp/atlasglob.axd&lt;/a&gt; which it cannot access until user is logged in.&lt;br /&gt;&lt;br /&gt;The solution is to add the following in web.config so that atlasglob.axd can be retrieved when the user is not logged in.&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&amp;lt;location path="atlasglob.axd"&amp;gt;&lt;br /&gt;&amp;lt;system.web&amp;gt;&lt;br /&gt;&amp;lt;authorization&amp;gt;&lt;br /&gt;&amp;lt;allow users="*"/&amp;gt;&lt;br /&gt;&amp;lt;/authorization&amp;gt;&lt;br /&gt;&amp;lt;/system.web&amp;gt;&lt;br /&gt;&amp;lt;/location&amp;gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-115790355908092379?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/115790355908092379/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=115790355908092379' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/115790355908092379'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/115790355908092379'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/09/atlas-script-manager-control-on-login.html' title='Atlas script manager control on login page raises a Javascript error in IE, not in Firefox'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-115244226111846875</id><published>2006-07-09T11:51:00.000+01:00</published><updated>2006-11-22T10:53:06.435Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tools'/><title type='text'>Choosing a wiki and a blog</title><content type='html'>I recently had to choose both a wiki and a blog. I also expected to find both functionalities within the same product or hosted service as they are not that different.&lt;br /&gt;&lt;br /&gt;My requirements for the wiki were the following:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Topic articles with versioning, attachments and discussions;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Authoring of articles by invitation only, discussions opened to everyone;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Hierarchical organisation of topics, ideally presented like online help: table of contents, index, search;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Customisable UI (branding);&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Full-text search;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Authoring using Word;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Preferably a hosted service with a friendly URL,&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Ad-free.&lt;/li&gt;&lt;/ul&gt;My requirements for a blog were very similar, except:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Authoring of articles by the owner of the blog only;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Organisation by category and by date.&lt;/li&gt;&lt;/ul&gt;My first observation is that you apparently cannot have both within the same solution.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.wikimatrix.org/"&gt;http://www.wikimatrix.org/&lt;/a&gt; is an invaluable resource to compare wiki software and two hosted solutions rise above average: jotspot and stikipad, although neither of them fulfils 100% of my requirements. Both products are basic but they do the job although authoring in Word, my top requirement, is not possible with these wikis.&lt;br /&gt;&lt;br /&gt;I have not been able to find a comprehensive resource that compares blog software properly although there is some information at &lt;a href="http://www.cmsmatrix.org/"&gt;http://www.cmsmatrix.org/&lt;/a&gt;. The well-known products I have come across are Community Server (formerly .Text), Moveable Type and WordPress. The top services are Blogger, MySpace and MSN Spaces. There is now also a Yahoo offering based on Moveable Type. My preference is Blogger because there is a Word plug-in which works reasonably well and it is free. The main objection is that Blogger lacks proper categories.&lt;br /&gt;&lt;br /&gt;My conclusion is that there is still a lot to improve on wikis and blogs especially to streamline the authoring process and to make navigation more fluid.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-115244226111846875?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/115244226111846875/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=115244226111846875' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/115244226111846875'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/115244226111846875'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/07/choosing-wiki-and-blog.html' title='Choosing a wiki and a blog'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-115219124681169572</id><published>2006-07-06T14:07:00.000+01:00</published><updated>2006-11-22T10:57:34.389Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Data access'/><title type='text'>Why I rarely use ADO.NET Datasets</title><content type='html'>Have you ever seen these great presentations which teach you how to build a master-details web page in a few minutes without writing a single line of code using a combination of DataSets, TableAdapters, ObjectDataSources, GridViews and FormViews? There is a great one at &lt;a href="http://download.microsoft.com/download/8/3/6/836dd5f8-fa92-499f-8219-0d326f13bf18/hilo_data_final.wmv"&gt;http://download.microsoft.com/download/8/3/6/836dd5f8-fa92-499f-8219-0d326f13bf18/hilo_data_final.wmv&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;There are sound technical reasons not to use DataSets in ASP.NET applications due to their stateful nature. These reasons are explained by Frans Bouma in his blog at &lt;a href="http://weblogs.asp.net/fbouma/archive/2003/05/13/6966.aspx"&gt;http://weblogs.asp.net/fbouma/archive/2003/05/13/6966.aspx&lt;/a&gt;. I have experienced other reasons not to use DataSets as a business layer.&lt;br /&gt;&lt;br /&gt;The entity-relationship model (the way data is organised in database) rarely corresponds so perfectly (see the video mentioned above) to the way you are going to present it. You will need to go through various transformations, for example:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;You may have an invoice which is constituted of items and you need to present the invoice total which is actually the total of all item amounts. This total may also need to be presented in several currencies.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You may have an N-N relationship between messages and contacts in your database, but you need to display a message with a To, Cc and Bcc fields which are separated lists of email addresses.&lt;/li&gt;&lt;/ul&gt;Data is rarely presented in the way it is stored in database and a business layer gives you the objects that you need between data and presentation, for example:&lt;br /&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;You need to store UTC dates which will have to be converted using the time zone defined in your user’s profile;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You need to store country codes which will have to be mapped to localized country names;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You need to store a document status as a byte like 0, 1 and 2, which will have to be mapped to an enumerated value like “draft”, “approved” and “rejected”.&lt;/li&gt;&lt;/ul&gt;You also need to validate data before storing it in database. You can use validation controls in your presentation layer, but their features are limited and it is good practice to implement business rules in a business layer.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;So what should we do?&lt;br /&gt;&lt;br /&gt;&lt;/strong&gt;&lt;strong&gt;&lt;/strong&gt;&lt;ol&gt;&lt;li&gt;Implement your data access layer (DAL) as stored procedures handling create, read, update and delete (CRUD) operations;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Implement a business logic layer (BLL) in C# or VB.NET calling stored procedures using data readers and commands, which will achieve much better performances.&lt;/li&gt;&lt;/ol&gt;&lt;strong&gt;Then when do you use datasets?&lt;/strong&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;You only use datasets in rapid application development (RAD) scenarios, or when&lt;/li&gt;&lt;br /&gt;&lt;li&gt;You have no other choice, for example when a component that you need (otherwise you would spend hours reinventing the wheel) requires datasets.&lt;/li&gt;&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-115219124681169572?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/115219124681169572/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=115219124681169572' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/115219124681169572'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/115219124681169572'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/07/why-i-rarely-use-adonet-datasets.html' title='Why I rarely use ADO.NET Datasets'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-115156978364237574</id><published>2006-06-29T09:29:00.000+01:00</published><updated>2006-11-22T10:57:52.461Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Data access'/><title type='text'>Using Guids or Integers as database identifiers</title><content type='html'>Globally unique identifiers (Guids) are those strings that you find in COM clsid’s or in the windows registry and that look like: {ED256ABD-5BE7-4E46-BCDA-1E26B0364EBB}. You need 128 bits to store a Guid.&lt;br /&gt;&lt;br /&gt;Integers are simply numbers that identify database rows in a table in an ascending order. They generally start at a seed of 1 and are automatically incremented by the database itself with an incremental step of 1, so you get 1, 2, 3, … Note that the database lets you specify the seed and the increment as required. You need 32 bits to store an integer.&lt;br /&gt;&lt;br /&gt;The detractors of Guids claim that Guids require a lot more storage space, so they dramatically affect performances. If you want to store contact details with name, address, telephone and fax number in a table, you will easily get a dozen fields which will at least require 1000 bytes to store with a double-byte character set (required for working in any country). In this example, the difference on storage between using a Guid and an Integer as an identity is below 1%.&lt;br /&gt;&lt;br /&gt;There are several advantages to using Guids:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Guids are well-typed in Java and in the .Net framework and I personally like to have a specific type for identifiers in the business layer;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;They can be generated in the application, so you do not have to query the database after an insert to know which identifier has been generated for you;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;They are guaranteed to be globally unique by using a combination of the network card MAC address and time at instant of generation, which is a reasonable guarantee. This is required in replication scenarios and SQL Server replication relies on Guids anyway, so using Guids is more future proof.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-115156978364237574?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/115156978364237574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=115156978364237574' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/115156978364237574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/115156978364237574'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/06/using-guids-or-integers-as-database.html' title='Using Guids or Integers as database identifiers'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-115148110624461885</id><published>2006-06-28T08:51:00.000+01:00</published><updated>2006-11-22T10:55:11.499Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Data access'/><title type='text'>Stored procedures or inline SQL</title><content type='html'>Using stored procedure versus using inline SQL has been a debate for long in the software development community. There are good articles on the subject, including:&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;a href="http://weblogs.asp.net/rhoward/archive/2003/11/17/38095.aspx"&gt;http://weblogs.asp.net/rhoward/archive/2003/11/17/38095.aspx&lt;/a&gt;&lt;br /&gt;&lt;a href="http://weblogs.asp.net/fbouma/archive/2003/11/18/38178.aspx"&gt;http://weblogs.asp.net/fbouma/archive/2003/11/18/38178.aspx&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.simple-talk.com/sql/t-sql-programming/to-sp-or-not-to-sp-in-sql-server/"&gt;http://www.simple-talk.com/sql/t-sql-programming/to-sp-or-not-to-sp-in-sql-server/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://www.simple-talk.com/sql/t-sql-programming/to-sp-or-not-to-sp-in-sql-server-an-argument-for-stored-procedures/"&gt;http://www.simple-talk.com/sql/t-sql-programming/to-sp-or-not-to-sp-in-sql-server-an-argument-for-stored-procedures/&lt;/a&gt; &lt;/p&gt;&lt;p&gt;Generally the debate is about best practice, security, performance and maintainability with two camps:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Rapid Application Developers prefer to rely on tools (RAD, ORM) that generate code, which all use inline SQL statements. This camp will claim that their tools enforce best practices, prevent SQL injection attacks and ensure maintainability while SQL execution plan caching makes performance equivalent to stored procedures.&lt;/li&gt;&lt;li&gt;Developers who write their own business layer and data access layer code without support from such tools should opt for Stored Procedures which will make their application generally more secure, maintainable and performing better. I am on this side. Also note that having all your SQL code in stored procedures makes it easier to have it audited and reviewed by a database expert.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-115148110624461885?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/115148110624461885/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=115148110624461885' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/115148110624461885'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/115148110624461885'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/06/stored-procedures-or-inline-sql.html' title='Stored procedures or inline SQL'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-115139666097528679</id><published>2006-06-27T09:24:00.000+01:00</published><updated>2006-11-27T15:13:54.284Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='.NET'/><category scheme='http://www.blogger.com/atom/ns#' term='Business logic'/><title type='text'>Enterprise Library</title><content type='html'>One of the most exciting Microsoft initiatives and sections of their web site is the patterns and practices section at &lt;a href="http://msdn.microsoft.com/practices/"&gt;http://msdn.microsoft.com/practices/&lt;/a&gt;. As part of this section, there is Enterprise Library for .NET Framework (EntLib).&lt;br /&gt;&lt;br /&gt;EntLib is not really a framework. Microsoft calls it a collection of reusable and extensible application blocks for enterprise development. I would define it a set of helper classes which greatly simplify development in the following areas:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;Datatabase access;&lt;/li&gt;&lt;li&gt;Caching;&lt;/li&gt;&lt;li&gt;Logging;&lt;/li&gt;&lt;li&gt;Exception Handling;&lt;/li&gt;&lt;li&gt;Security and Cryptography;&lt;/li&gt;&lt;/ol&gt;Generally these blocks are extremely easy to use and I definitely recommend any .NET architect of serious business application to consider building on top of EntLib with two main benefits:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Rock-solid foundations (helper classes);&lt;/li&gt;&lt;li&gt;Instrumentation.&lt;/li&gt;&lt;/ul&gt;&lt;strong&gt;Database access&lt;/strong&gt;&lt;br /&gt;The Data Access Application Block (DAAB) is in my opinion the weakest block and the fans of O/R mapping frameworks like DataObjects, Genome or NHybernate generally laugh at it. Microsoft has made an attempt to complement the DAAB with the Data Mapping Application Block but it does not seem to be continued. I am not a big fan of O/R mapping tools. They make custom development very productive, but you have to tweak the code to get what you really need and optimize performances which makes maintenance more complex on the long term, especially when upgrading to new releases of the frameworks. So I write my own data access layer and I get the productivity gains and best practices from a template-based code generator like CodeSmith. In this scenario, DAAB is very neat and my only objection is that it is only database access. In my applications, I also have data in files. I would love an instrumented FAAB for file IO including XML/CSV/Text files and binary files. And with the new packaging APIs in WinFX for Office Open XML Formats, we could even imagine OAAB. Then we would have a complete data access application block.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Caching:&lt;/strong&gt;&lt;br /&gt;Considering the HttpContext.Cache in ASP.NET 2.0 the Caching Application Block is only an incremental improvement in this context but it delivers its full value in the context of WinForms applications.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Logging:&lt;/strong&gt;&lt;br /&gt;The logging application block is an alternative to Log4Net. You will need to find or build replacements for the default formatters and trace listeners. The default format of log entries does not make it easy to read large files when you can now associate XML with XSL stylesheets that let you drilldown into data effectively. And you will want to replace the default flat file trace listener with a rolling file trace listener that generates a new file every day or when the size reaches a threshold.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Exception Handling:&lt;/strong&gt;&lt;br /&gt;Exception handling is the block I personally prefer. I find writing good error handling code and reporting extremely difficult and the exception handling block provides much more than a few helper classes. You get best practices in an extensive framework with the full benefits of configurable policies. This is definitely the block that justifies adopting EntLib.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;Security and Cryptography:&lt;/strong&gt;&lt;br /&gt;The security application block handles caching of security-related credentials and authorizations. Caching security-related credentials works well with Windows Forms applications but it does not fit the Membership provider model implemented in ASP.NET 2.0. For the same reason the authorization part of the block which makes a neat use of rules, does not integrate well in ASP.NET and especially with the navigation server controls. In my opinion, the block lacks proper server controls including menus and command buttons to constitute an application block and not simply a collection of helper classes.&lt;br /&gt;&lt;br /&gt;&lt;strong&gt;What’s next?&lt;/strong&gt;&lt;br /&gt;The great new feature of .NET framework 3.0 (formerly WinFX) is workflow and we will need best practices and frameworks to get the full potential of this exciting technology. Microsoft makes an extensive use of RSS in the next releases of Vista, Internet Explorer and Office and the same requirement applies here. Finally we will also want to rip the benefits of the full-text indexing and search functionalities of Vista which are worth a new block.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-115139666097528679?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/115139666097528679/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=115139666097528679' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/115139666097528679'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/115139666097528679'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/06/enterprise-library.html' title='Enterprise Library'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-115131103387820958</id><published>2006-06-26T09:37:00.000+01:00</published><updated>2006-11-22T10:55:37.746Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='GUI'/><title type='text'>Ajax at last</title><content type='html'>I have always felt that HTML and more recently XML/XSL were a step back from object oriented programming and rich user interfaces.&lt;br /&gt;&lt;br /&gt;In the mid-90’s, we had very neat C++ user interface (UI) frameworks implementing a model-view-controller (MVC) like Microsoft Foundation Classes (MFC). With these frameworks we could build 100% object oriented applications that were:&lt;br /&gt;&lt;ul&gt;&lt;li&gt;Easy to architect, design, develop, test and maintain especially because the tools were very mature;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Providing rich UI features like complex controls, dynamic data exchange, object linking and embedding, drag and drop or notifications that update the interface when the underlying data changes.&lt;/li&gt;&lt;/ul&gt;&lt;br /&gt;It all went away with the advent of HTML, a rudimentary technology to present and link documentation pages, which has been diverted from its original purpose to develop business applications, just because IT departments were missing the days of mainframes when an application had to be deployed only once on a server to be available everywhere.&lt;br /&gt;&lt;br /&gt;Suddenly our applications became very slow. Everything had to be done with a bunch of simplistic UI controls. Data had to be round-tripped to the server to be validated or for the user interface to be updated accordingly. We had to page through long lists to find our items with limited sorting capabilities. Merging data into Word was near to impossible except using the old copy-paste trick. Without proper tools, architecting, designing, developing, testing and maintaining these applications was significantly more difficult.&lt;br /&gt;&lt;br /&gt;Then came Java with Swing and the promise of an MVC framework including rich UI controls. I really thought that Java would become the Holy Grail of web interfaces. Java applets were offering the best of both worlds with the promise of “develop once, run everywhere”. But again, we have been deceived; the promise was not kept and information technology (IT) departments did not want to deploy the plug-in with some help from Microsoft, who ditched Java after embracing it.&lt;br /&gt;&lt;br /&gt;Not long ago after releasing .NET framework, Microsoft has praised the benefits of ‘smart clients’ which would offer the best of web architectures and rich user interfaces but nobody really bought into it.&lt;br /&gt;&lt;br /&gt;Now the market reiterates its promise of a rich UI for the web with Asynchronous JavaScript and Xml (Ajax). People will tell you that Ajax has been around for quite some time and that Outlook Web Access 2000 was the first application implementing Ajax in the late 90’s. Ajax is based on the XMLHttpRequest object which is available since Internet Explorer version 4. XMLHttpRequest allows code to pass a request to the server without reposting the entire page but Ajax is much more than that otherwise we would have heard about it before.&lt;br /&gt;&lt;br /&gt;To get a rich UI, you need much more that the XMLHttpRequest object; you need:&lt;br /&gt;&lt;ol&gt;&lt;li&gt;support from the industry which includes browser manufacturers and the support for XMLHttpRequest in Mozilla and other browsers is very recent;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;A choice of UI component frameworks that use XMLHttpRequest in the background to provide rich UI features because like me, you do not want to reinvent the wheel and develop a library of UI components. Infragistics, Telerik, ComponetArt, ComponentOne and the others have only recently released their Ajax UI frameworks.&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;To be honest, Ajax is a jumble of technologies clumsily put together: some Javascript code within an HTML page scripts a binary client object to post data using HTTP to a web server where some Java or .NET code is interpreted by a virtual machine in view to retrieve or save data into a SQL database. I know Ajax is not the whole chain, but what a mess! This mess has good chances to win the rich UI also known as Web 2.0 battle because it does not compromise the ease of deployment of applications. After 10 years of web architecture hegemony, it is going to be good to retrieve the user experience of rich user interfaces.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-115131103387820958?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/115131103387820958/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=115131103387820958' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/115131103387820958'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/115131103387820958'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/06/ajax-at-last.html' title='Ajax at last'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-115123634384618320</id><published>2006-06-25T12:52:00.000+01:00</published><updated>2006-11-22T10:54:58.569Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Data access'/><title type='text'>Attaching databases to SQL Server 2005</title><content type='html'>Often, sample projects contain a database file (MDF) but no log file (LDF).&lt;br /&gt;&lt;br /&gt;In this case you need to attach the database running the following query against master in SQL Server Management Studio:&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;EXEC sp_attach_db @dbname = N'DBName', &lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:Courier New;font-size:85%;"&gt;@filename1 = N'D:\Working Folders\Project\App_Data\DBName.mdf'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This will not only attach the database but also create a log file.&lt;br /&gt;&lt;br /&gt;&lt;em&gt;Note: replace DBName and path as required.&lt;/em&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-115123634384618320?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/115123634384618320/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=115123634384618320' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/115123634384618320'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/115123634384618320'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/06/attaching-databases-to-sql-server-2005.html' title='Attaching databases to SQL Server 2005'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-18669442.post-114873196462671536</id><published>2006-05-27T13:12:00.000+01:00</published><updated>2006-11-13T08:38:40.416Z</updated><title type='text'>Grand opening</title><content type='html'>You blog, he/she blogs, they blog but I still don't blog.&lt;br /&gt;&lt;br /&gt;It is now done: I have opened my blog on blogger.&lt;br /&gt;&lt;br /&gt;I need to keep the pace so please add your comments to motivate me.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/18669442-114873196462671536?l=jlchereau.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://jlchereau.blogspot.com/feeds/114873196462671536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=18669442&amp;postID=114873196462671536' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/114873196462671536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/18669442/posts/default/114873196462671536'/><link rel='alternate' type='text/html' href='http://jlchereau.blogspot.com/2006/05/grand-opening.html' title='Grand opening'/><author><name>Jacques L. Chereau</name><uri>http://www.blogger.com/profile/03733988177982708738</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://photos1.blogger.com/blogger/803/1833/1600/Jacques.Chereau.Small.jpg'/></author><thr:total>3</thr:total></entry></feed>
