<?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; Guides</title>
	<atom:link href="http://www.geekscrapbook.com/category/guides/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>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>
		<item>
		<title>How To: Build A Sign On Service Like Windows Live Using ASP.Net</title>
		<link>http://www.geekscrapbook.com/2009/07/05/how-to-build-a-single-sign-on-service-like-windows-live/</link>
		<comments>http://www.geekscrapbook.com/2009/07/05/how-to-build-a-single-sign-on-service-like-windows-live/#comments</comments>
		<pubDate>Sun, 05 Jul 2009 13:17:33 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[Guides]]></category>
		<category><![CDATA[Sign On Series]]></category>
		<category><![CDATA[How-To]]></category>

		<guid isPermaLink="false">http://www.geekscrapbook.com/?p=25</guid>
		<description><![CDATA[If you run a business that serves a variety of web-enabled products to your clients, the task of implementing sign-on logic for each one can become redundant and hard to maintain. Having a single sign on service can help modularize the sign on process for all of your products as well as add fluidity as [...]]]></description>
			<content:encoded><![CDATA[<p align="left">If you run a business that serves a variety of web-enabled products to your clients, the task of implementing sign-on logic for each one can become redundant and hard to maintain. Having a single sign on service can help modularize the sign on process for all of your products as well as add fluidity as your users move between your services.</p>
<p>First, I would suggest looking into one of the single sign on services already out there such as Windows Live or OpenID. There’s no real point in building your own service if it’s possible to use one of these readily available services. However, if for some reason these services just don’t fit your needs, this article will cover a simple solution.</p>
<p>I’ll be covering, in order, the following pieces:</p>
<ol>
<li>Database </li>
<li>A Simple Sign-in Page </li>
<li>Web Service </li>
<li>Integrating an Application </li>
</ol>
<p>All the code is available for download at the end of this article. You may want to download it in advance and follow along.</p>
<p><strong>Database      <br /></strong>I’ll be working in a database I’ve named SingleSignOn. The following script will create your tables:</p>
<p><a title="SQL File to Create Your Single Sign On Tables" href="http://www.geekscrapbook.com/wp-content/uploads/2009/07/SingleSignOn.txt" target="_blank">Download SQL</a></p>
<p>For this guide we will keep things simple, starting with the database design. We only need 3 tables to do the job:</p>
<ul>
<li>Users </li>
<li>UserSessions </li>
<li>Applications </li>
</ul>
<p>The code in this article is going to assume you’ve already filled up your users table so you may want to fill it with some sample data (remember to <a href="http://md5-hash-online.waraxe.us/" target="_blank">hash the passwords using MD5</a>); a registration screen won’t be difficult to add on later. A test user is included in the downloadable SQL file at the end of the article.</p>
<p>We will explore the tables more fully as we build our service.</p>
<p><strong>A Simple Sign-in Page      <br /></strong>Instead of having users for each of your products log in using yet another log in page, we will create a central page that will handle all login requests and then perform the appropriate redirect.</p>
<p>The sign-in page will do a few things:</p>
<ol>
<li>Identify the requesting application </li>
<li>Authenticate the user </li>
<li>Create a session for the user </li>
<li>Redirect the user </li>
</ol>
<p>Our page will check the query string for the application ID. This will allow us to display to the users what application they are logging into, but more importantly it tells our sign-in page where to send them once we’ve authenticated them.</p>
<p>Before we can start our sign-in page, we need to create an access layer for our database. For the sake of simplicity, I will use LINQ to SQL.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.geekscrapbook.com/wp-content/uploads/2009/07/image5.png" width="400" height="394" /></p>
<p>Now, let’s create a page with a few labels, a couple text-boxes, and a sign-in button.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="image" border="0" alt="image" src="http://www.geekscrapbook.com/wp-content/uploads/2009/07/image15.png" width="334" height="178" /></p>
<p>On page load, we will check for an application ID in the query string. We don’t really need to do anything with it yet other than set our labels.</p>
<pre class="csharpcode c-sharp"><span class="kwrd">protected</span> <span class="kwrd">void</span> Page_Load(<span class="kwrd">object</span> sender, EventArgs e)
{
    <span class="kwrd">int</span> appID;
    <span class="kwrd">string</span> sAppID = Request.QueryString[<span class="str">&quot;appid&quot;</span>];

    <span class="kwrd">if</span> (!String.IsNullOrEmpty(sAppID) &amp;&amp; <span class="kwrd">int</span>.TryParse(sAppID, <span class="kwrd">out</span> appID))
    {
        SingleSignOn.Database.Context dbCon = <span class="kwrd">new</span> Context(DBSettings.SignOnConnectionString);
        SingleSignOn.Database.Application app = dbCon.Applications.Where(
            a =&gt; a.ApplicationID == appID
            ).FirstOrDefault();

        <span class="kwrd">if</span> (app != <span class="kwrd">null</span>)
        {
            lblApplicationName.Text = app.Name;
            lblPublisher.Text = app.Publisher;
        }
    }
}</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>Now, let’s stub out some helper methods. We will need methods to authenticate a user based on an email address and a password, as well as methods to create a session and redirect the user to the correct place.</p>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">int</span> AuthenticateUser(<span class="kwrd">string</span> username, <span class="kwrd">string</span> passwordhash)
{
    <span class="kwrd">return</span> -1;
}

<span class="kwrd">protected</span> <span class="kwrd">string</span> CreateUserSession(<span class="kwrd">int</span> userID)
{
    <span class="kwrd">return</span> <span class="kwrd">null</span>;
}

<span class="kwrd">protected</span> <span class="kwrd">void</span> RedirectUser(<span class="kwrd">string</span> sessionID)
{

}</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>Let’s add an event to our sign-in button and write the code that will direct the flow.</p>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">void</span> btnSignIn_Click(<span class="kwrd">object</span> sender, EventArgs e)
{
    <span class="kwrd">int</span> userID = AuthenticateUser(txtEmail.Text, txtPassword.Text);
    <span class="kwrd">if</span> (userID == -1)
    {
        lblError.Text = <span class="str">&quot;Sign in failed. Please try again&quot;</span>;
        <span class="kwrd">return</span>;
    }

    <span class="kwrd">string</span> sessionID = CreateUserSession(userID);

    <span class="kwrd">if</span> (String.IsNullOrEmpty(sessionID))
    {
        lblError.Text = <span class="str">&quot;Error during sign in. Please try again.&quot;</span>;
        <span class="kwrd">return</span>;
    }

    RedirectUser(sessionID);
}</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>Now, we just need to implement our methods.</p>
<p>AuthenticateUser will need to find the user trying to log in, test the hash of the entered password against the one stored in our database, and, on a successful match, return the user’s ID. On failure, we’re going to return –1.</p>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">int</span> AuthenticateUser(<span class="kwrd">string</span> email, <span class="kwrd">string</span> password)
{
    <span class="kwrd">string</span> passwordHash = GetMd5Sum(password);
    SingleSignOn.Database.Context dbCon = <span class="kwrd">new</span> Context(DBSettings.SignOnConnectionString);
    SingleSignOn.Database.User user = dbCon.Users.Where(
        u =&gt; u.Email.ToLower() == email.ToLower() &amp;&amp; u.Password == passwordHash
        ).FirstOrDefault();

    <span class="kwrd">if</span> (user != <span class="kwrd">null</span>)
    {
        <span class="kwrd">return</span> user.UserID;
    }

    <span class="kwrd">return</span> -1;
}</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>CreateUserSession takes the user ID we retrieved and initializes a session. It then returns the session ID.</p>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">string</span> CreateUserSession(<span class="kwrd">int</span> userID)
{
    <span class="kwrd">try</span>
    {
        SingleSignOn.Database.Context dbCon = <span class="kwrd">new</span> Context(DBSettings.SignOnConnectionString);
        SingleSignOn.Database.UserSession newSession = <span class="kwrd">new</span> UserSession();
        newSession.Created = DateTime.Now;
        newSession.SessionID = Guid.NewGuid();
        newSession.UserID = userID;
        newSession.Expires = DateTime.Now.AddMinutes(1.0);
        dbCon.UserSessions.InsertOnSubmit(newSession);
        dbCon.SubmitChanges();
        <span class="kwrd">return</span> newSession.SessionID.ToString();
    }
    <span class="kwrd">catch</span>
    {
        <span class="kwrd">return</span> <span class="kwrd">null</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>We’ve set the session to expire after a minute, which is more than enough time to redirect the user back to the application they are logging into. We’re using the “Expires” column to determine how long the user has to complete the sign-in handshake before this session is declared “dead”.</p>
<p>RedirectUser will determine where to send the user based on the application ID found in the query string. You may wish to handle the case where there is no application ID by dictating a default application ID. We’ll place the session ID in the query string so the application can handle the handshake with our web service.</p>
<pre class="csharpcode"><span class="kwrd">protected</span> <span class="kwrd">void</span> RedirectUser(<span class="kwrd">string</span> sessionID)
{
    <span class="kwrd">int</span> appID;
    <span class="kwrd">string</span> sAppID = Request.QueryString[<span class="str">&quot;appid&quot;</span>];

    <span class="kwrd">if</span> (!String.IsNullOrEmpty(sAppID) &amp;&amp; <span class="kwrd">int</span>.TryParse(sAppID, <span class="kwrd">out</span> appID))
    {
        SingleSignOn.Database.Context dbCon = <span class="kwrd">new</span> Context(DBSettings.SignOnConnectionString);
        SingleSignOn.Database.Application app = dbCon.Applications.Where(
            a =&gt; a.ApplicationID == appID
            ).FirstOrDefault();

        <span class="kwrd">if</span> (app != <span class="kwrd">null</span>)
        {
            Response.Redirect(app.RedirectUrl + <span class="str">&quot;?sid=&quot;</span> + sessionID);
        }
    }
}</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>Our sign-in page is now functional enough to perform its duties. Let’s move on to our web service.</p>
<p><strong>Web Service</strong></p>
<p>The web service really only needs a single method: GetUserSessionInfo. This web method will examine our session ID, make sure it is valid, and return a class (that we will also create) containing the user’s ID, email, and display name.</p>
<pre class="csharpcode">[WebMethod]
<span class="kwrd">public</span> UserInfo GetUserSessionInfo(<span class="kwrd">string</span> sessionId)
{
    SingleSignOn.Database.Context dbCon = <span class="kwrd">new</span> Context(DBSettings.SignOnConnectionString);

    UserSession theSession = dbCon.UserSessions.Where(
        us =&gt; us.SessionID == <span class="kwrd">new</span> Guid(sessionId)
        ).FirstOrDefault();

    <span class="kwrd">if</span> (theSession != <span class="kwrd">null</span> &amp;&amp; theSession.Expires &gt; DateTime.Now &amp;&amp; theSession.Serviced == <span class="kwrd">null</span>)
    {
        theSession.Serviced = DateTime.Now;
        dbCon.SubmitChanges();
        <span class="kwrd">return</span> <span class="kwrd">new</span> UserInfo(
            theSession.User.UserID,
            theSession.User.Email,
            theSession.User.DisplayName);
    }

    <span class="kwrd">return</span> <span class="kwrd">null</span>;
}

[Serializable()]
<span class="kwrd">public</span> <span class="kwrd">class</span> UserInfo
{
    <span class="kwrd">public</span> <span class="kwrd">int</span> UserID { get; set; }
    <span class="kwrd">public</span> <span class="kwrd">string</span> Email { get; set; }
    <span class="kwrd">public</span> <span class="kwrd">string</span> DisplayName { get; set; }

    <span class="kwrd">public</span> UserInfo()
    {
    }

    <span class="kwrd">public</span> UserInfo(<span class="kwrd">int</span> userID, <span class="kwrd">string</span> email, <span class="kwrd">string</span> displayName)
    {
        <span class="kwrd">this</span>.UserID = userID;
        <span class="kwrd">this</span>.Email = email;
        <span class="kwrd">this</span>.DisplayName = displayName;
    }
}</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>Notice that once the Serviced time is set, the session is considered “used” and won’t be valid again. This is a security measure that prevents the user’s session from being re-used. Now, let’s see how everything pieces together by integrating an application into our new architecture.</p>
<p><strong>Integrating an Application</strong></p>
<p>For our first application, we will build a simple profile viewer site. First, let’s add the information for the application into our applications table (we are going to assume everything is running on a local IIS server):</p>
<pre class="csharpcode">INSERT <span class="kwrd">INTO</span> Applications (Name, Publisher, IntegrationDate, RedirectUrl)
<span class="kwrd">VALUES</span> (<span class="str">'My Profile'</span>, <span class="str">'www.geekscrapbook.com'</span>, GetDate(), <span class="str">'http://localhost/myprofile'</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>Let’s add a class to our project called IntegratedPage. This will handle all the sign-on logic. On each request, we will make sure the Asp.Net session variable “UserInfo” is set. If it isn’t, we will check to see if there is a session ID in the query string. If there is one, we will call the web service method and set the session information. Otherwise, we will redirect the user to the single sign on site.</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">class</span> IntegratedPage : System.Web.UI.Page
{
    <span class="kwrd">protected</span> <span class="kwrd">override</span> <span class="kwrd">void</span> OnPreInit(EventArgs e)
    {
        <span class="kwrd">if</span> (UserInfo == <span class="kwrd">null</span>)
        {

            <span class="kwrd">string</span> s = Request.QueryString[<span class="str">&quot;sid&quot;</span>];

            <span class="kwrd">if</span> (!String.IsNullOrEmpty(s))
            {

                localhost.SignOnService webService = <span class="kwrd">new</span> localhost.SignOnService();
                UserInfo = webService.GetUserSessionInfo(s);
            }
        }

        <span class="kwrd">if</span> (UserInfo == <span class="kwrd">null</span>)
        {
            Response.Redirect(<span class="str">&quot;http://localhost/signonsite/default.aspx?appid=1&quot;</span>);
        }

        <span class="kwrd">base</span>.OnPreInit(e);
    }

    <span class="kwrd">public</span> localhost.UserInfo UserInfo
    {
        get
        {
            <span class="kwrd">return</span> (localhost.UserInfo)Session[<span class="str">&quot;UserInfo&quot;</span>];
        }
        set
        {
            Session[<span class="str">&quot;UserInfo&quot;</span>] = <span class="kwrd">value</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>Now all we have to do to require sign-in for a page is derive it from our new IntegratedPage:</p>
<pre class="csharpcode"><span class="kwrd">public</span> <span class="kwrd">partial</span> <span class="kwrd">class</span> _Default : IntegratedPage
{
    <span class="kwrd">protected</span> <span class="kwrd">void</span> Page_Load(<span class="kwrd">object</span> sender, EventArgs e)
    {
        lblEmail.Text = UserInfo.Email;
        lblDisplayName.Text = UserInfo.DisplayName;
    }
}</pre>
<p>So, let’s put it all together. I simply added each of the three web projects as applications to my machine’s IIS server, allowing me to test locally:</p>
<p align="center"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="image" border="0" alt="image" src="http://www.geekscrapbook.com/wp-content/uploads/2009/07/image4.png" width="300" height="331" />&#160;&#160;&#160;&#160;&#160; <img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="image" border="0" alt="image" src="http://www.geekscrapbook.com/wp-content/uploads/2009/07/image6.png" width="300" height="332" />&#160;</p>
<p>And there you have it: sign on handled independently from a central location.</p>
<p><strong>Download the Solution </p>
<p></strong>You can download a zip file of the solution by clicking the link below.</p>
<p><a href="http://www.geekscrapbook.com/wp-content/uploads/2009/07/SingleSignOn.zip">SingleSignOn.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekscrapbook.com/2009/07/05/how-to-build-a-single-sign-on-service-like-windows-live/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multiple WordPress Sites on GoDaddy&#8217;s Windows Hosting</title>
		<link>http://www.geekscrapbook.com/2009/07/03/how-to-install-multiple-wordpress-blogs-using-godaddys-windows-hosting/</link>
		<comments>http://www.geekscrapbook.com/2009/07/03/how-to-install-multiple-wordpress-blogs-using-godaddys-windows-hosting/#comments</comments>
		<pubDate>Fri, 03 Jul 2009 19:00:47 +0000</pubDate>
		<dc:creator>Dave</dc:creator>
				<category><![CDATA[Guides]]></category>
		<category><![CDATA[How-To]]></category>

		<guid isPermaLink="false">http://www.geekscrapbook.com/?p=5</guid>
		<description><![CDATA[UPDATE: This post is now obsolete since GoDaddy now allows multiple installations of wordpress. I’ll call that a bug fixed! This is a fitting first post, since this site exists thanks to the solution. As referenced in some other spots, GoDaddy&#8217;s Windows hosting isn&#8217;t really WordPress-friendly. Being a .Net developer, I can&#8217;t live without the [...]]]></description>
			<content:encoded><![CDATA[<p><strong>UPDATE: </strong>This post is now obsolete since GoDaddy now allows multiple installations of wordpress. I’ll call that a bug fixed!</p>
<p>This is a fitting first post, since this site exists thanks to the solution. As referenced in some other spots, GoDaddy&#8217;s Windows hosting isn&#8217;t really WordPress-friendly. Being a .Net developer, I can&#8217;t live without the Windows hosting, but let&#8217;s face it: WordPress is pretty neat. Copying up my locally WORKING test blog just wasn&#8217;t enough, unfortunately. I found the only way to install WordPress was to go through GoDaddy&#8217;s &#8220;Hosting Connection&#8221; and have them set it up for me. The Hostinng Connection is just a big library of web applications you can one-click-install, and GoDaddy will do all the work for you in setting them up. So, I went through the install for my wife&#8217;s blog, no problem. Ten minutes later the blog was up and running (<a href="http://www.mommybug.com">http://www.mommybug.com</a>). I thought, &#8220;Hey, that was easy! Let&#8217;s add another.&#8221;</p>
<p>Wait. Now when I check the Hosting Connection, I only have the option to UNINSTALL WordPress? Come on! You let me install it in a subfolder, but you&#8217;re not going to let me install more than one copy? Eventually after talking with support and getting nowhere, I was frustrated enough to try uninstalling the first blog, so I clicked the &#8220;Uninstall&#8221; link. To my surprise it asked me if I wanted to delete the files and drop the database.</p>
<p>I said, &#8220;&#8230;. NO! I&#8217;ll keep them!&#8221;</p>
<p>After &#8220;uninstalling,&#8221; The very next thing I did was visit my wife&#8217;s blog. It was still there. I went back to the Hosting Connection and hit &#8220;Install&#8221; to install WordPress again, but pointed it at the &#8220;geekscrapbook&#8221; subfolder. 10 minutes later, I&#8217;ve got two&#8211;COUNT &#8216;EM, TWO&#8211;WordPress blogs on the same GoDaddy hosting account.</p>
<p>All this after 3-4 days of talking to support. Sometimes it&#8217;s just best to do things yourself.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.geekscrapbook.com/2009/07/03/how-to-install-multiple-wordpress-blogs-using-godaddys-windows-hosting/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
