<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Geek Scrapbook &#187; ASP.NET</title>
	<atom:link href="http://www.geekscrapbook.com/category/asp-net/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.geekscrapbook.com</link>
	<description>The .Net developer&#039;s everyday how-to guide.</description>
	<lastBuildDate>Fri, 03 Sep 2010 19:58:18 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>CashTrackerOnline.com Weekly Development Summary</title>
		<link>http://www.geekscrapbook.com/2010/08/26/cashtrackeronline-com-weekly-development-summary/</link>
		<comments>http://www.geekscrapbook.com/2010/08/26/cashtrackeronline-com-weekly-development-summary/#comments</comments>
		<pubDate>Thu, 26 Aug 2010 17:36:23 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Cash Tracker Online]]></category>

		<guid isPermaLink="false">http://www.geekscrapbook.com/2010/08/26/cashtrackeronline-com-weekly-development-summary/</guid>
		<description><![CDATA[This will be the first of a series of weekly updates about the Cash Tracker Online project. I’m happy with the progress I have made so far. I have a lot of the groundwork laid, but it will still be a few weeks before the initial version is ready to be published. Here’s the summary… [...]]]></description>
			<content:encoded><![CDATA[<p>This will be the first of a series of weekly updates about the Cash Tracker Online project.</p>
<p>I’m happy with the progress I have made so far. I have a lot of the groundwork laid, but it will still be a few weeks before the initial version is ready to be published. Here’s the summary…</p>
<p><strong>Finished Work</strong></p>
<ol>
<li>Domain purchased </li>
<li>Database Schema tentatively complete </li>
<li>Website project created </li>
<li>Simple Logo produced </li>
<li>Default / login screen working </li>
<li>Error handling in place, notifications of problems being routed correctly </li>
<li>Maintenance mode working </li>
<li>Dashboard “shell” built </li>
<li>Accounts summary pane on dashboard finished </li>
</ol>
<p><strong>Needed Before Release</strong></p>
<ol>
<li>A place to host the website and database (being worked out, should have this soon) </li>
<li>Make a decision on whether to use some third party controls and which ones </li>
<li>CRUD (Create, Read, Update, &amp; Delete) for:
<ul>
<li>Accounts </li>
<li>Recurrences </li>
<li>Manual Entry </li>
<li>Recurrence adjustments </li>
</ul>
</li>
<li>Balance calculations </li>
<li>Account projections </li>
<li>Graphical visuals </li>
<li>Data export </li>
</ol>
<p> <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="LogoSmall" border="0" alt="LogoSmall" src="http://www.geekscrapbook.com/wp-content/uploads/2010/08/LogoSmall_thumb.png" width="240" height="64" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekscrapbook.com/2010/08/26/cashtrackeronline-com-weekly-development-summary/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>CashTrackerOnline.com Domain Purchased</title>
		<link>http://www.geekscrapbook.com/2010/08/23/cashtrackeronline-com-domain-purchased/</link>
		<comments>http://www.geekscrapbook.com/2010/08/23/cashtrackeronline-com-domain-purchased/#comments</comments>
		<pubDate>Tue, 24 Aug 2010 01:14:48 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Cash Tracker Online]]></category>

		<guid isPermaLink="false">http://www.geekscrapbook.com/2010/08/23/cashtrackeronline-com-domain-purchased/</guid>
		<description><![CDATA[I’ve decided to go ahead with the online version of Cash Tracker. I purchased and parked the domain on my personal hosting account today. You can view the “coming soon” splash page here. I’ve also decided to convert Cash Tracker to a web project before implementing any of the new features. I think the development [...]]]></description>
			<content:encoded><![CDATA[<p> I’ve decided to go ahead with the online version of <a href="http://www.geekscrapbook.com/cash-tracker" target="_blank">Cash Tracker</a>. I purchased and parked the domain on my personal hosting account today. You can view the “coming soon” splash page <a href="http://www.cashtrackeronline.com" target="_blank">here</a>. I’ve also decided to convert Cash Tracker to a web project before implementing any of the new features. I think the development will be much faster-paced because programming for the web is my strong suit. Also, the tool will be much more accessible on the web, and version control will be much easier to implement (no more converting .tfx files to a new version because of a schema change). </p>
<p>I already have the database all laid out on paper, and I will make database diagrams and code samples available as I finish them. At some point I may be forced to stop posting source code for the sake of security, but until I start collecting sensitive data (right now the data I track can’t be tied to anyone or any actual accounts), I will continue to post code here.</p>
<p>  <img title="CTComingSoon" border="0" alt="CTComingSoon" src="http://www.geekscrapbook.com/wp-content/uploads/2010/08/CTComingSoon_thumb.jpg" width="1000" height="465" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekscrapbook.com/2010/08/23/cashtrackeronline-com-domain-purchased/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Connection Timeout Using LINQ DataContext</title>
		<link>http://www.geekscrapbook.com/2010/08/13/connection-timeout-using-linq-datacontext/</link>
		<comments>http://www.geekscrapbook.com/2010/08/13/connection-timeout-using-linq-datacontext/#comments</comments>
		<pubDate>Fri, 13 Aug 2010 16:23:48 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Code Samples]]></category>
		<category><![CDATA[LINQ]]></category>

		<guid isPermaLink="false">http://www.geekscrapbook.com/2010/08/13/connection-timeout-using-linq-datacontext/</guid>
		<description><![CDATA[For a while now, I’ve had a website that was sporadically encountering the following error: Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached. My Research On the website in question, I use [...]]]></description>
			<content:encoded><![CDATA[<p>For a while now, I’ve had a website that was sporadically encountering the following error:</p>
<blockquote><p>Timeout expired. The timeout period elapsed prior to obtaining a connection from the pool. This may have occurred because all pooled connections were in use and max pool size was reached.</p>
</blockquote>
<p><strong>My Research      <br /></strong>On the website in question, I use LINQ-to-SQL heavily to perform data operations. Naturally, I suspected that I wasn’t disposing of my DataContext objects correctly, causing me to exceed the number of connections available in the pool. After doing a little research on the subject, I read in several articles (some by folks who are much more knowledgeable than myself) that I shouldn’t have to dispose of them. They all said the following code is just fine:</p>
<blockquote><pre class="code"><span style="color: #2b91af">CORDataContext </span>mcon = <span style="color: blue">new </span><span style="color: #2b91af">CORDataContext</span>();
<span style="color: #2b91af">COR_Employee </span>emp = mcon.COR_Employees.FirstOrDefault();</pre>
</blockquote>
<p>In fact, I should be able to put that into an infinite loop and never get the exception I was encountering. According to the experts, LINQ is not only smart enough to automatically open and close the connection for me, but also smart enough to dispose of the object when I’m done. No need for a “using” around my code or even a Connection.Close().</p>
<p><strong>An Exception to the Rule</strong></p>
<p>I noticed, though, that my code was slightly different. In my specific setup, I have a central database and a LOT of other databases I might want to connect to. So, to take advantage of connection pooling more, I always connect to the central database first and change to whatever catalog I need to access. In doing so, it is necessary to manually open the connection, like the following:</p>
<blockquote>
<pre class="code"><span style="color: #2b91af">CORDataContext </span>mcon = <span style="color: blue">new </span><span style="color: #2b91af">CORDataContext</span>();mcon.Connection.Open(); mcon.Connection.ChangeDatabase(<span style="color: #a31515">&quot;OtherDB&quot;</span>);
<span style="color: #2b91af">COR_Employee </span>emp = mcon.COR_Employees.FirstOrDefault();</pre>
</blockquote>
<p><strong>My Testing</p>
<p></strong>I began to theorize that manually opening the connection in this way <strong>keeps the connection alive</strong> after I’ve run my query. I confirmed the belief by trying to run the following code:</p>
<blockquote>
<pre class="code"><span style="color: blue">for </span>(<span style="color: blue">int </span>i = 0; i &lt; 1000; i++) {

    <span style="color: #2b91af">CORDataContext </span>mcon = <span style="color: blue">new </span><span style="color: #2b91af">CORDataContext</span>();
    <span style="color: #2b91af">COR_Employee </span>emp = mcon.COR_Employees.FirstOrDefault();
    mcon.Connection.Open();
    mcon.Connection.ChangeDatabase(<span style="color: #a31515">&quot;OtherDB&quot;</span>);

    <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">&quot;&quot; </span>+ (i + 1) + <span style="color: #a31515">&quot; / 1000&quot;</span>);
}</pre>
</blockquote>
<p>I got the exception after 230 or so connections. By default there are 100 connections available in the pool, but the garbage collector kicked in and helped give me a buffer before I ran out. So, from that I can conclude that manually opened DataContext connections will stay open until the connection is closed or the DataContext is disposed.</p>
<p><strong>The Solution</strong></p>
<p>Once I fully understood the problem, the fix was common sense:</p>
<blockquote>
<pre class="code"><span style="color: blue">for </span>(<span style="color: blue">int </span>i = 0; i &lt; 1000; i++) {

    <span style="color: blue">using </span>(<span style="color: #2b91af">CORDataContext </span>mcon = <span style="color: blue">new </span><span style="color: #2b91af">CORDataContext</span>()) {
        <span style="color: #2b91af">COR_Employee </span>emp = mcon.COR_Employees.FirstOrDefault();
        mcon.Connection.Open();
        mcon.Connection.ChangeDatabase(<span style="color: #a31515">&quot;OtherDB&quot;</span>);

        <span style="color: #2b91af">Console</span>.WriteLine(<span style="color: #a31515">&quot;&quot; </span>+ (i + 1) + <span style="color: #a31515">&quot; / 1000&quot;</span>);
    }
}</pre>
</blockquote>
<p>Adding a “using” to automatically dispose of my DataContext did the trick, and this loop now finishes in about 3 seconds (even with the overhead of writing to the console). I hope this helps someone else, because it’s been plaguing me for weeks!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekscrapbook.com/2010/08/13/connection-timeout-using-linq-datacontext/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>IHttpHandler and IRequiresSessionState</title>
		<link>http://www.geekscrapbook.com/2010/03/04/ihttphandler-and-irequiressessionstate/</link>
		<comments>http://www.geekscrapbook.com/2010/03/04/ihttphandler-and-irequiressessionstate/#comments</comments>
		<pubDate>Fri, 05 Mar 2010 01:25:35 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[ASP.NET]]></category>

		<guid isPermaLink="false">http://www.geekscrapbook.com/2010/03/04/ihttphandler-and-irequiressessionstate/</guid>
		<description><![CDATA[If your web application relies on session to persist the user’s state and you’ve ever tried writing your own HTTP handler, you’ve probably run into an error: “Session state is not available in this context”. Thankfully, there is a simple remedy. In your class definition you need to implement the interface System.Web.SessionState.IRequiresSessionState. Once you’ve done [...]]]></description>
			<content:encoded><![CDATA[<p>If your web application relies on session to persist the user’s state and you’ve ever tried writing your own HTTP handler, you’ve probably run into an error: “Session state is not available in this context”. Thankfully, there is a simple remedy. </p>
<p>In your class definition you need to implement the interface <a href="http://msdn.microsoft.com/en-us/library/system.web.sessionstate.irequiressessionstate.aspx" target="_blank">System.Web.SessionState.IRequiresSessionState</a>. Once you’ve done that you’ll find yourself magically able to use session once more.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekscrapbook.com/2010/03/04/ihttphandler-and-irequiressessionstate/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ASP.NET Maintenance Scheduling Made Easy</title>
		<link>http://www.geekscrapbook.com/2009/08/04/asp-net-maintenance-scheduling-made-easy/</link>
		<comments>http://www.geekscrapbook.com/2009/08/04/asp-net-maintenance-scheduling-made-easy/#comments</comments>
		<pubDate>Wed, 05 Aug 2009 00:54:24 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[ASP.NET]]></category>
		<category><![CDATA[Guides]]></category>

		<guid isPermaLink="false">http://www.geekscrapbook.com/2009/08/04/asp-net-maintenance-scheduling-made-easy/</guid>
		<description><![CDATA[Any time I have code I need to release for an ASP.NET website that I know is going to cause a recompile (like anything in app_code, any new binaries, master pages, user controls, etc.) I try to avoid doing it when I know there are a lot of users on the site. The best way [...]]]></description>
			<content:encoded><![CDATA[<p align="left">Any time I have code I need to release for an ASP.NET website that I know is going to cause a recompile (like anything in app_code, any new binaries, master pages, user controls, etc.) I try to avoid doing it when I know there are a lot of users on the site. The best way to ensure that nobody will be using your website is to add scheduled maintenance support to your site. It’s very easy to do and it can save you and your users a lot of headache while you make updates.</p>
<p><strong>Deriving from System.Web.UI.Page&#160; <br /></strong>A quick and dirty way to get a maintenance window up for your site is to write a base page (derived from System.Web.UI.Page) that all of your pages derive from. That way you can specify things to happen on multiple pages from one central location. So let’s say I have BasePage.cs in my App_Code folder. I can override the OnPreInit() method to check to see whether I’m supposed to be in maintenance mode or not. If the site is supposed to be “down” I will redirect the user to a page that will say the site is down for maintenance. For now I will just be checking a flag I’ve set in app settings.</p>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> OnPreInit(EventArgs e) {
    <span class="kwrd">base</span>.OnPreInit(e);
    <span class="kwrd">if</span> (ConfigurationManager.AppSettings[<span class="str">&quot;MaintenanceMode&quot;</span>].ToUpper() == <span class="str">&quot;TRUE&quot;</span>) {
        <span class="kwrd">if</span> (Request.Url.AbsolutePath.ToLower() != <span class="str">&quot;/maintenance.aspx&quot;</span>) {
            Response.Redirect(<span class="str">&quot;Maintenance.aspx&quot;</span>);
        }
    }
}</pre>
<p>
  </p>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p><strong>Using an HttpModule </p>
<p></strong>An alternate way to add code that checks for maintenance (and is less work if you have medium-to-large sized site OR multiple sites that need to use the same maintenance code) is to place it in an HttpModule and add the module to web.config. I personally think the HttpModule is perfectly suited to solving this problem. Checking for maintenance is typically something that is separate from most other things, so it makes sense to modularize it as much as possible. It’s just good form! Here’s my module code:</p>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<pre class="csharpcode">

<span class="kwrd">public</span> <span class="kwrd">class</span> MaintenanceModule : IHttpModule
{
    <span class="preproc">#region</span> IHttpModule Members

    <span class="kwrd">public</span> <span class="kwrd">void</span> Dispose() {

    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> Init(HttpApplication context) {
        context.BeginRequest +=<span class="kwrd">new</span> EventHandler(context_BeginRequest);
    }

    <span class="kwrd">public</span> <span class="kwrd">void</span> context_BeginRequest(<span class="kwrd">object</span> sender, EventArgs e) {&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span class="kwrd">if</span> (ConfigurationManager.AppSettings[<span class="str">&quot;MaintenanceMode&quot;</span>] == <span class="str">&quot;TRUE&quot;</span>) { &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <span class="kwrd">if</span> (Request.Url.AbsolutePath.ToLower() != <span class="str">&quot;/maintenance.aspx&quot;</span>) { &#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Response.Redirect(<span class="str">&quot;Maintenance.aspx&quot;</span>);             }         }
    }
    <span class="preproc">#endregion</span>
}
</pre>
<p>And here is my web.config entry (added to the httpModules section in system.web for local use; put it in the modules section of system.webserver for IIS to pick it up):</p>
<pre class="csharpcode"><span class="kwrd">&lt;</span><span class="html">add</span> <span class="attr">name</span><span class="kwrd">=&quot;MaintenanceModule&quot;</span> <span class="attr">type</span><span class="kwrd">=&quot;MaintenanceModule&quot;</span> <span class="kwrd">/&gt;</span></pre>
<p>
  </p>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p><strong>Scheduling Maintenance Ahead of Time </p>
<p></strong>I like to give my users several days’ notice before I bring a site down for maintenance, so I do two things to accomplish that. First, I keep a table called MaintenanceSchedule that I can put a start time, end time, public message, and private message into. Then, on pages where I want to notify users of the upcoming maintenance, I check the table for maintenance periods that haven’t yet begun.</p>
<pre class="csharpcode"><span class="kwrd">string</span> connectionString =
    ConfigurationManager.ConnectionStrings[<span class="str">&quot;DefaultConnection&quot;</span>].ConnectionString;

<span class="kwrd">using</span> (SqlConnection con = <span class="kwrd">new</span> SqlConnection(connectionString)) {
    con.Open();
    <span class="kwrd">using</span> (SqlCommand com = con.CreateCommand()) {
        com.CommandText = <span class="str">&quot;GetNextMaintenancePeriod&quot;</span>;
        com.CommandType = CommandType.StoredProcedure;

        <span class="kwrd">using</span> (SqlDataReader sdr = com.ExecuteReader()) {
            <span class="kwrd">if</span> (sdr.Read()) {
                DateTime start = sdr.GetDateTime(1);
                DateTime end = sdr.GetDateTime(2);

                litUpcomingMaintenance.Text =
                    <span class="str">&quot;&lt;strong&gt;Alert!&lt;/strong&gt; &quot;</span>
                    + <span class="str">&quot;This site will be going down for maintenance from &quot;</span>
                    + start.ToString() + <span class="str">&quot; until &quot;</span> + end.ToString() + <span class="str">&quot;.&quot;</span>;
            }
            <span class="kwrd">else</span> {
                <span class="rem">// throw an exception to show the default message.</span>
                <span class="kwrd">throw</span> <span class="kwrd">new</span> Exception(<span class="str">&quot;No maintenance period found...&quot;</span>);
            }
        }
    }
}</pre>
<p>
  </p>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p>This method also allows me to put a more specific message out when the site is actually being worked on as well as a way to keep a record of when past maintenance periods occurred.</p>
<pre class="csharpcode"><span class="kwrd">string</span> connectionString =
    ConfigurationManager.ConnectionStrings[<span class="str">&quot;DefaultConnection&quot;</span>].ConnectionString;

<span class="kwrd">try</span> {
    <span class="kwrd">using</span> (SqlConnection con = <span class="kwrd">new</span> SqlConnection(connectionString)) {
        con.Open();
        <span class="kwrd">using</span> (SqlCommand com = con.CreateCommand()) {
            com.CommandText = <span class="str">&quot;GetCurrentMaintenancePeriod&quot;</span>;
            com.CommandType = CommandType.StoredProcedure;

            <span class="kwrd">using</span> (SqlDataReader sdr = com.ExecuteReader()) {
                <span class="kwrd">if</span> (sdr.Read()) {
                    DateTime start = sdr.GetDateTime(1);
                    DateTime end = sdr.GetDateTime(2);
                    <span class="kwrd">string</span> message = sdr.GetString(3);

                    litMaintenance.Text =
                        <span class="str">&quot;This site is currently undergoing maintenance. &quot;</span>
                        + <span class="str">&quot;Maintenance is expected to start at &quot;</span>
                        + start.ToString() + <span class="str">&quot; and end at &quot;</span> + end.ToString()
                        + <span class="str">&quot;.&lt;br/&gt;&lt;br/&gt;&quot;</span> + message;
                }
                <span class="kwrd">else</span> {
                    <span class="rem">// throw an exception to show the default message.</span>
                    <span class="kwrd">throw</span> <span class="kwrd">new</span> Exception(<span class="str">&quot;No maintenance period found...&quot;</span>);
                }
            }
        }
    }
}
<span class="kwrd">catch</span> (Exception ex) {
    <span class="rem">// This is in case my database goes down during the maintenance period.</span>
    litMaintenance.Text = <span class="str">&quot;This site is currently undergoing maintenance.&quot;</span>
        + <span class="str">&quot; Please try again later.&quot;</span>;
}</pre>
<p>I’ll also alter my base page to automatically take the site down when maintenance is scheduled to begin.</p>
<pre class="csharpcode"><span class="kwrd">string</span> connectionString =
    ConfigurationManager.ConnectionStrings[<span class="str">&quot;DefaultConnection&quot;</span>].ConnectionString;

<span class="kwrd">if</span> (Request.Url.AbsolutePath.ToLower() != <span class="str">&quot;/maintenance.aspx&quot;</span>) {
    <span class="kwrd">using</span> (SqlConnection con = <span class="kwrd">new</span> SqlConnection(connectionString)) {
        con.Open();
        <span class="kwrd">using</span> (SqlCommand com = con.CreateCommand()) {
            com.CommandText = <span class="str">&quot;GetCurrentMaintenancePeriod&quot;</span>;
            com.CommandType = CommandType.StoredProcedure;

            <span class="kwrd">using</span> (SqlDataReader sdr = com.ExecuteReader()) {
                <span class="kwrd">if</span> (sdr.Read()) {
                    Response.Redirect(<span class="str">&quot;Maintenance.aspx&quot;</span>);
                }
            }
        }
    }
}</pre>
<p>
  </p>
<style type="text/css">
<p>.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }</style>
<p><strong>Code Sample</strong></p>
<p>I’ve included a sample website with a SQL script to show how all the pieces fit together. Just download the files, run the SQL against your database, open the website (I used Microsoft Visual Web Developer 2008 Express Edition), and put your connection string into the web.config. Then, add some rows into the MaintenanceSchedule table and run the site to see how it all works.</p>
<p><a href="http://www.geekscrapbook.com/wp-content/uploads/2009/08/MaintenanceTest.zip" target="_blank">Download Sample Code (.zip)</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekscrapbook.com/2009/08/04/asp-net-maintenance-scheduling-made-easy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
