<?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>Nathan Bridgewater</title>
	<atom:link href="http://www.integratedwebsystems.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.integratedwebsystems.com</link>
	<description>Works on my machine!</description>
	<lastBuildDate>Wed, 03 Mar 2010 17:12:03 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Walkthrough: Porting Asp.Net MVC Website to Mono 2.6.1 and MySql on Linux Apache &#8211; Porting to Mono Part 3 of 3</title>
		<link>http://www.integratedwebsystems.com/2010/02/walkthrough-porting-asp-net-mvc-website-to-mono-2-6-1-and-mysql-on-linux-apache-porting-to-mono-part-3-of-3/</link>
		<comments>http://www.integratedwebsystems.com/2010/02/walkthrough-porting-asp-net-mvc-website-to-mono-2-6-1-and-mysql-on-linux-apache-porting-to-mono-part-3-of-3/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 04:21:00 +0000</pubDate>
		<dc:creator>Nathan Bridgewater</dc:creator>
				<category><![CDATA[Mono]]></category>
		<category><![CDATA[ASP.Net]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[MySql]]></category>

		<guid isPermaLink="false">http://www.integratedwebsystems.com/?p=447</guid>
		<description><![CDATA[So for the third and final part of this series, I want to walk through how I ported a very small project I posted on CodePlex awhile back called SiteManager. It is an extremely simplified CMS application that I wrote using Linq to Sql and MVC in order to provide a very basic and easy [...]]]></description>
			<content:encoded><![CDATA[<p sizcache="0" sizset="0">So for the third and final part of this series, I want to walk through how I ported a very small project I posted on CodePlex awhile back called <a href="http://sitemanager.codeplex.com" target="_blank">SiteManager</a>. It is an extremely simplified CMS application that I wrote using Linq to Sql and MVC in order to provide a very basic and easy website tool. It uses membership provider for authentication and Linq to Sql Classes with its database in MS Sql Server. For this walkthrough, I’ll be converting the database to MySql and adapting Linq to Sql to Dblinq so it can completely run on Mono and Linux.</p>
</p>
<p> <span id="more-447"></span>
<link rel="stylesheet" type="text/css" href="/css/jquery.lightbox-0.5.css" />
<h3>Index</h3>
<ul sizcache="0" sizset="1">
<li sizcache="0" sizset="1"><a href="#start">Getting Started</a> </li>
<li sizcache="0" sizset="2"><a href="#database">Database Migration</a> </li>
<li sizcache="0" sizset="3"><a href="#l2s">Linq to Sql to Dblinq</a> </li>
<li sizcache="0" sizset="4"><a href="#membership">Membership</a> </li>
<li sizcache="0" sizset="5"><a href="#authorization">Authorization</a> </li>
<li sizcache="0" sizset="6"><a href="#deployment">Deployment</a> </li>
<li sizcache="0" sizset="7"><a href="#vim">VIM (Editing code files on the server)</a> </li>
<li sizcache="0" sizset="8"><a href="#wrapup">Wrap Up</a> </li>
<li sizcache="0" sizset="9"><a href="#source">Get the Source</a> </li>
</ul>
<h3 sizcache="0" sizset="10"><a name="start">Getting Started</a></h3>
<p sizcache="0" sizset="11">Since I’ve already ported this application, it is very easy to identify any of the problem points. But for any new project, I would identify the basic items related to common issues with changing platforms like: data access, authentication, and any operating system specific code. Using the <a href="http://mono-project.com/MoMA" target="_blank">MoMA tool</a> is hugely beneficial to see how your code base might fare in the Mono framework. It will point out any specific code you’re using that could cause problems.&#160;&#160; You should also <a href="http://mono-project.com/Start" target="_blank">browse the Mono site</a> and learn some basics about the framework since they have quite a few useful extended frameworks that are not part of the Windows .Net runtime.&#160; They also have another nice guide out there for <a href="http://www.mono-project.com/Guide:_Porting_ASP.NET_Applications">porting Asp.Net applications</a> where they use PostgreSql and Blog Starter Kit.</p>
<p>&#160;</p>
<h3 sizcache="0" sizset="14"><a name="database">Database Migration</a></h3>
<p>You should know that Microsoft Sql Server works fine with Mono and works well when you are in a Windows environment and want to run Mono applications against existing Sql Servers. Since we’re running this application completely on a Linux server, as you might do in a hosted Linux environment, leaving our database in Sql Server isn’t an option.&#160; I chose to migrate to MySql purely for personal preference since I have a little more experience with this one rather than others like PostgreSql or Sqlite. However with Dblinq, you will have quite a few options.</p>
<h4>Create an Empty MySql Database and an Application User</h4>
<p sizcache="0" sizset="15">If you recall from my first post in this series, we <a href="http://www.integratedwebsystems.com/2010/01/installing-opensuse-11-2-with-mono-2-6-1-and-apache-using-text-mode-configuration-porting-to-mono-part-1-of-3/#InstallMonoAndApache">installed and configured MySql server</a>.&#160;&#160; We also discussed creating new users. You will want to create a new database with a new user who has access to it from the local machine. (Note that this can also be performed with the <a href="http://dev.mysql.com/downloads/workbench/5.2.html" target="_blank">MySql Workbench GUI Tools</a>).</p>
<p>So to begin, using Putty, SSH into your server.&#160; Then run:</p>
<pre class="brush: sql; gutter: false;">root@server: mysql -u admin_username -p
Enter password: ********
create database sitemanager_mono;
grant all privileges on sitemanager_mono.* to 'aspnet'@'localhost' identified by 'pass';
quit</pre>
<p>You may want to replace the username and password I used here with something more secure, but for this demo I kept it simple. You can do that by replacing ‘aspnet’ with a username of your choice and ‘pass’ with a password of your choice.</p>
<p>You now have a new empty database with its own power user account that can only access it from the local machine. This will be our application user so keep the credentials handy for later when we edit the config file.</p>
<h4>Migrating Sql Server Schema to MySql</h4>
<p sizcache="0" sizset="17">I used the <a href="http://dev.mysql.com/downloads/workbench/5.2.html" target="_blank">MySql Migration Toolkit</a> (part of the GUI Workbench) to perform my migration. It actually worked out pretty well with the exception of a few data type conversions. I like to use varchar(max) fields in Sql server. I also use bit fields for booleans since they parse right over to C# booleans.&#160; The migration tool didnt’ like varchar(max) and converted them to varchar(-1). It also converted my bit fields to tinyint(4). So during the migration, I was able to make edits to a few of my tables that contained those fields. For varchar(max), you have a choice. You can: use a smaller field like varchar(5000), use a Text field, or you can choose to store your text data in a binary blob and encode/decode it to UTF8.&#160; For this, application, I went the route of selecting a smaller varchar field for simplicity; but if my content pages were large, I would probably go the route of text. I found some <a href="http://www.pythian.com/news/7129/text-vs-varchar/" target="_blank">interesting discussion in this post on the topic.</a></p>
<p>So in order, here are the steps I took using the migration tool:</p>
<table border="0" cellspacing="0" cellpadding="2" width="561" sizcache="0" sizset="19">
<tbody sizcache="0" sizset="19">
<tr sizcache="0" sizset="19">
<td valign="top" width="263" sizcache="0" sizset="19"><a class="lightbox" title="Step 1" href="/resources/p447/1.jpg" jquery1267071925472="12" jquery1267072108070="12"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Step 1" border="0" alt="Step 1" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/02/1.jpg" width="244" height="178" /></a> </td>
<td valign="top" width="296">&#160;</td>
</tr>
<tr sizcache="0" sizset="20">
<td valign="top" width="263" sizcache="0" sizset="20"><a class="lightbox" title="Step 2" href="/resources/p447/2.jpg" jquery1267071925472="14" jquery1267072108070="14"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Step 2" border="0" alt="Step 2" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/02/2.jpg" width="244" height="178" /></a> </td>
<td valign="top" width="296">
<p>Choose your source database.</p>
</td>
</tr>
<tr sizcache="0" sizset="21">
<td valign="top" width="263" sizcache="0" sizset="21"><a class="lightbox" title="Step 3" href="/resources/p447/3.jpg" jquery1267071925472="16" jquery1267072108070="16"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Step 3" border="0" alt="Step 3" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/02/3.jpg" width="244" height="178" /></a> </td>
<td valign="top" width="296">
<p>Choose your target database.</p>
</td>
</tr>
<tr sizcache="0" sizset="22">
<td valign="top" width="263" sizcache="0" sizset="22"><a class="lightbox" title="Step 4" href="/resources/p447/4.jpg" jquery1267071925472="18" jquery1267072108070="18"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Step 4" border="0" alt="Step 4" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/02/4.jpg" width="244" height="178" /></a> </td>
<td valign="top" width="296">Select the source schema. </td>
</tr>
<tr sizcache="0" sizset="23">
<td valign="top" width="263" sizcache="0" sizset="23"><a class="lightbox" title="Step 5" href="/resources/p447/5.jpg" jquery1267071925472="20" jquery1267072108070="20"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="" border="0" alt="" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/02/5.jpg" width="244" height="178" /></a> </td>
<td valign="top" width="296">Add exclusions. I chose to exclude my membership tables since I configured those to use a different catalog. </td>
</tr>
<tr sizcache="0" sizset="24">
<td valign="top" width="263" sizcache="0" sizset="24"><a class="lightbox" title="Step 6" href="/resources/p447/6.jpg" jquery1267071925472="22" jquery1267072108070="22"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Step 6" border="0" alt="Step 6" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/02/6.jpg" width="244" height="178" /></a> </td>
<td valign="top" width="296">Utf-8 was fine for my solution</td>
</tr>
<tr sizcache="0" sizset="25">
<td valign="top" width="263" sizcache="0" sizset="25"><a class="lightbox" title="Step 7" href="/resources/p447/7.jpg" jquery1267071925472="24" jquery1267072108070="24"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Step 7" border="0" alt="Step 7" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/02/7.jpg" width="244" height="178" /></a> </td>
<td valign="top" width="296">Mapping error review</td>
</tr>
<tr sizcache="0" sizset="26">
<td valign="top" width="263" sizcache="0" sizset="26"><a class="lightbox" title="Step 8" href="/resources/p447/8.jpg" jquery1267071925472="26" jquery1267072108070="26"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Step 8" border="0" alt="Step 8" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/02/8.jpg" width="244" height="178" /></a> </td>
<td valign="top" width="296">Execution step</td>
</tr>
<tr sizcache="0" sizset="27">
<td valign="top" width="263" sizcache="0" sizset="27"><a class="lightbox" title="Step 9" href="/resources/p447/9.jpg" jquery1267071925472="28" jquery1267072108070="28"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Step 9" border="0" alt="Step 9" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/02/9.jpg" width="244" height="178" /></a> </td>
<td valign="top" width="296">Execution results</td>
</tr>
<tr sizcache="0" sizset="28">
<td valign="top" width="263" sizcache="0" sizset="28"><a class="lightbox" title="Step 10" href="/resources/p447/10.jpg" jquery1267071925472="30" jquery1267072108070="30"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Step 10" border="0" alt="Step 10" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/02/10.jpg" width="244" height="178" /></a> </td>
<td valign="top" width="296">
<p>Script errors will appear on the last screen.&#160; Make the necessary changes, click Apply Changes, and Recreate Objects for each error.&#160; When finished, click next to finish.</p>
<p>This is where you’ll see varchar(-1) for conversion from varchar(max) fields.&#160; Change this to text or varchar(n).</p>
<p>Note that sql bit fields convert to smallint(4) if you wish to change that back to bit.</p>
</td>
</tr>
</tbody>
</table>
<p>&#160;</p>
<h3 sizcache="0" sizset="29"><a name="l2s">Linq to Sql Classes to Dblinq</a></h3>
<p>After fixing errors and executing the script, you should now have your full schema migrated to MySql. Now you need to convert your Linq to Sql to Dblinq. Mono uses Dblinq as its Linq to Sql replacement internally. I chose to manually use DBlinq because I wasn’t sure how much of the Dblinq code was available in Mono.&#160; I downloaded the current version of the Dblinq project from their public Subversion repository.</p>
<p>So the basic idea here is that we’re going to swap out L2S with Dblinq in a nearly transparent way.&#160; We’ll drop the existing DBML file from our project, use DBMetal.exe to regenerate new classes, and then update our DBFactory utility function to create a new data context from the DBlinq side.&#160;&#160; Essentially, this will allow us to re-use the same operational syntax in the Repository class with minimal changes.</p>
<p>For generating new classes, I used the DBMetal utility that comes with Dblinq. Here&#8217;s the batch file I setup to generate my code: </p>
<pre class="brush: bash; gutter: false;">REM: note that the '-sprocs' option is turned on

&quot;DbMetal.exe&quot; --provider=MySql -database:sitemanager_mono -server:carbuncle -user:user -password:pass &quot;-namespace:IWS.SiteManager.Core.Model&quot; -code:Generated.cs -sprocs --pluralize</pre>
<p>After generating the classes, I replaced the DBFactory GetProvider function with this: </p>
<pre class="brush: csharp; gutter: false;">public static Model.SiteManager GetProvider()
{
    var con_string = GetDefaultConnectionString();
    return new Model.SiteManager(new MySql.Data.MySqlClient.MySqlConnection(con_string));
}</pre>
<p>I used a repository class as a helper to access my data model. Each repository class contains its own instance of the data context (in this case, Data.SiteManager). During construction of the repository class, it creates a new instance of the data context so any of the factory functions are able to use it without maintaining their own context. So I replaced all the member variable types for existing data contexts with the new one generated from Dblinq. I also noticed Dblinq had different casing than the original column names.&#160; So where I had columns like, “ModifiedUTC” before, it was “ModifiedUtc” now. This was a pretty painless fix with find/replace.</p>
<p>You’ll notice here that the Linq syntax itself didn’t change at all.</p>
<pre class="brush: csharp; gutter: false;">public class ContentRepository
{
    SiteManager _DB;

    public ContentRepository()
    {
        _DB = DBFactory.GetProvider();
    }

    /// &lt;summary&gt;
    /// gets a page by its id
    /// &lt;/summary&gt;
    /// &lt;param name=&quot;id&quot;&gt;&lt;/param&gt;
    /// &lt;returns&gt;&lt;/returns&gt;
    public Content GetContent(int id)
    {
        return _DB.Contents.Where(o =&gt; o.ID == id).SingleOrDefault();
    }
    /// &lt;summary&gt;
    /// Load a page by its permalink.
    /// &lt;/summary&gt;
    /// &lt;param name=&quot;permalink&quot;&gt;&lt;/param&gt;
    /// &lt;returns&gt;&lt;/returns&gt;
    public Content GetPage(string section, string permalink)
    {
        return _DB.Contents.Where(o =&gt; o.SectionID == section &amp;&amp; o.Permalink == permalink.Trim().ToLower()).SingleOrDefault();
    }
    /// &lt;summary&gt;
    /// gets the configured default page.
    /// &lt;/summary&gt;
    /// &lt;returns&gt;&lt;/returns&gt;
    public Content GetIndexPage(string section)
    {
        var data = _DB.Sections.Where(o =&gt; o.ID == section).SingleOrDefault();

        Content page = null;

        if (data != null &amp;&amp; data.DefaultContentID.HasValue)
            page = _DB.Contents.Where(o =&gt; o.ID == data.DefaultContentID.Value).SingleOrDefault;

        return page;
    }
    public string GetSectionIDForPage(int id)
    {
        var section = _DB.Contents.Where(o =&gt; o.ID == id).Select(o =&gt; o.SectionID).SingleOrDefault();
        return section;
    }
    public void SaveContent(Content content)
    {
        Section section = null;

        if (_DB.Sections.Where(o =&gt; o.ID == content.SectionID).Count() == 0)
        {
            section = new Section();
            section.ID = content.SectionID;
            section.Description = &quot;Auto-generated section for new page.&quot;;
            _DB.Sections.InsertOnSubmit(section);
            _DB.SubmitChanges();
        }

        //take current version, push it to content history, overwrite current with new.
        Content old = this.GetContent(content.ID);
        if (old != null)
        {
            //archive old version.
            ContentHistory row = new ContentHistory();
            row.ContentID = content.ID;
            row.Body = old.Body;
            row.CreatedUtc = DateTime.UtcNow;
            _DB.ContentHistories.InsertOnSubmit(row);
            _DB.SubmitChanges();

            old.LoadFromExisting(content); //load current values
        }
        else
        {
            old = content;
            _DB.Contents.InsertOnSubmit(old);
        }

        _DB.SubmitChanges();

        if (section != null) //was a new one. set the default content id.
        {
            section.DefaultContentID = content.ID;
            _DB.SubmitChanges();
        }
    }
    public void DeleteContent(int id)
    {
        var data = _DB.Contents.Where(o =&gt; o.ID == id).SingleOrDefault();
        if (data != null)
        {
            //remove conflicts first.
            var section = this.GetSectionByID(data.SectionID);
            if (section != null)
            {
                section.DefaultContentID = null;
                _DB.SubmitChanges();
            }

            _DB.Contents.DeleteOnSubmit(data);
            _DB.SubmitChanges();
        }
    }
}</pre>
<p>At this point, the project should be compilable. You may need to make a few tweaks to get the loose ends tied up.</p>
<p>&#160;</p>
<h3 sizcache="0" sizset="30"><a name="membership">Membership Provider</a></h3>
<p sizcache="0" sizset="31">After following the <a href="http://www.integratedwebsystems.com/2010/02/how-to-setup-and-configure-mysql-membership-provider-6-2-2-porting-to-mono-part-2-of-3/" target="_blank">instructions from the last post</a>, you should get your membership provider setup and configured. For Mono, I think the biggest hang up for me was not being able to use hashed passwords. Alternatively, you can investigate using encrypted passwords. For simplicity, I used clear text passwords here.</p>
<p>&#160;</p>
<h3 sizcache="0" sizset="32"><a name="authorization">Membership Authorization</a></h3>
<p>You should now have a runable MVC application. Almost everything should work with exception to how security applies rules from the web.config.&#160; I noticed Mono doesn’t apply the same security authorization rules to paths for MVC like it does for web forms. I removed &lt;location path=””&gt; tags from my config file and placed the authorization restrictions to my controller actions instead. </p>
<p>So for example this config section would be used to restrict access to all actions in the Manage controller on Windows.</p>
<pre class="brush: xml; gutter: false;">&lt;location path=&quot;Manage&quot;&gt;
    &lt;system.web&gt;
        &lt;authorization&gt;
            &lt;allow roles=&quot;Admins,Editors&quot;/&gt;
            &lt;deny users=&quot;*&quot;/&gt;
        &lt;/authorization&gt;
    &lt;/system.web&gt;
&lt;/location&gt;</pre>
<p>So on Mono, we remove it from web.config and move to the manage controller as an attribute on ALL actions you want to restrict. This can become a maintenance hassle, but they may eventually fix this for MVC in Mono.</p>
<pre class="brush: csharp; gutter: false;">[Authorize(Roles=&quot;Admins,Editors&quot;)]
public ActionResult Index()
{
    return View();
}</pre>
<h3>&#160;</h3>
<h3 sizcache="0" sizset="33"><a name="deployment">Deployment</a></h3>
<p>Don’t forget to make changes to your web.config file. Include the credentials you setup for your database earlier.&#160; Then using Build-&gt;Publish, publish the site to a local folder. Don’t include the App_Data folder and have it delete all files before publishing. Then using FileZilla over SFTP, connect to your server and upload the published website to the web folder you configured. With the latest Mono, the website should automatically reload the new assemblies. If you have any doubt about this, you can always SSH into the server and restart apache.</p>
<p>To restart apache, gain root access using <strong>su</strong> and then: </p>
<pre class="brush: bash; gutter: false;">service apache2 restart</pre>
<p>Optionally, if restarting apache doesn’t seem to work, you can also search and kill off the mono processes:</p>
<pre class="brush: bash; gutter: false;">diabolos:/home/nathan # ps -A | grep mono
 2162 ?        00:00:03 mono
 2164 ?        00:00:08 mono
diabolos:/home/nathan # kill 2162
diabolos:/home/nathan # kill 2164</pre>
<p>The next request to the server will restart these processes as needed. </p>
<p>&#160;</p>
<h3 sizcache="0" sizset="34"><a name="vim">Quick Guide to VIM</a></h3>
<p>Every once in awhile, you may need to edit files that live on the server without going through the whole process of publishing, deploying, etc. To do this, I like to use a tool called VIM. So what is VIM?&#160; For those of you haven’t used it, it’s a simple text editor in Linux that comes with most distributions. You can think of VIM like “edit” for DOS on steroids. The OpenSuse version even has code completion and color-coded syntax, which is very neat.</p>
<p>To open a file with VIM, SSH into your server and run this command:</p>
<p>vi <em>filename</em></p>
<p>When you open the file, there isn’t a menu, but you’ll see ~ on the left and the text of your file.&#160; VIM has modes (much more than I’ll discuss here), but you need to know of at least two:&#160; insert mode and append mode.&#160; This will allow you to insert or append text starting at the cursor position. So move your cursor to any location and press <em><strong>i</strong></em> for insert mode. You will be able to freely type almost anything. To exit insert mode, hit <em><strong>Esc</strong></em>. Append mode uses the same behavior by pressing <em><strong>a</strong></em>. You will append text starting at the cursor position. Entering <strong><em>:d</em></strong> will delete the current line. Be sure not to use arrow keys while in an editing mode.</p>
<p>To save a file, press <strong><em>Esc </em></strong>to exit editing mode, and then press<strong><em> :w</em></strong> to write the file. You can then enter <strong><em>:q</em></strong> to quit.&#160;&#160; And to save and quit, use <strong><em>:wq.</em></strong>&#160; You can get more info by entering <strong><em>man vi</em></strong> at the command prompt.</p>
<p>&#160;</p>
<h3 sizcache="0" sizset="35"><a name="wrapup">Wrap Up</a></h3>
<p>So that’s it. This is a tiny project, but you may be able to apply these ideas to your own projects.&#160; For me, this gets my imagination fired up about what kinds of solutions I can take advantage of using Mono. I think there’s a lot of potential here.&#160; I’ve recently begun using interfaces and dependency injection with my projects for data frameworks to avoid the mess we covered in the Linq to Sql to Dblinq section. This means I can write a decoupled application that can optionally use Linq to Sql or Dblinq as a pluggable assembly that is injected using settings in my config file. This will make the transition between Windows and Mono much less painful.</p>
<p>&#160;</p>
<h3 sizcache="0" sizset="36"><a name="source">Get the Source</a></h3>
<p sizcache="0" sizset="37">To obtain the source, head over to <a href="http://sitemanager.codeplex.com/SourceControl/list/changesets" target="_blank">sitemanager.codeplex.com</a> and download the latest source.&#160; You’ll find the mono ported code under the /branches/mono-mysql-fork branch. </p>
<p>&#160;</p>
<h3>Useful Links</h3>
<ul sizcache="0" sizset="38">
<li sizcache="0" sizset="38"><a href="http://www.mono-project.com" target="_blank">Mono project</a> </li>
<li sizcache="0" sizset="39"><a href="http://mono-project.com/Start" target="_blank">Getting Started with Mono</a> </li>
<li sizcache="0" sizset="40"><a href="http://mono-project.com/Guide:_Porting_ASP.NET_Applications" target="_blank">Porting Asp.Net Applications</a> </li>
<li sizcache="0" sizset="41"><a href="http://dev.mysql.com/downloads/connector/net/" target="_blank">MySql .NET Connector</a> (I downloaded mono build &amp; source) </li>
<li sizcache="0" sizset="42"><a href="https://sitemanager.svn.codeplex.com/svn/branches/mono-mysql-fork" target="_blank">SiteManager CodePlex Mono Branch in Subversion</a> </li>
<li sizcache="0" sizset="43"><a href="http://linq.to/db" target="_blank">Dblinq website</a> </li>
<li sizcache="0" sizset="44"><a href="http://dblinq2007.googlecode.com/svn/trunk/" target="_blank">Dblinq Subversion</a> </li>
</ul>
<p><script type="text/javascript" src="http://www.google.com/jsapi"></script><script type="text/javascript">
		google.load("jquery", "1.4.1");
	</script><script type="text/javascript" src="/js/jquery.lightbox-0.5.pack.js"></script><script type="text/javascript" src="/tools/js/lightbox.js"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.integratedwebsystems.com/2010/02/walkthrough-porting-asp-net-mvc-website-to-mono-2-6-1-and-mysql-on-linux-apache-porting-to-mono-part-3-of-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>How to Setup and Configure MySql Membership Provider 6.2.2 &#8211; Porting to Mono Part 2 of 3</title>
		<link>http://www.integratedwebsystems.com/2010/02/how-to-setup-and-configure-mysql-membership-provider-6-2-2-porting-to-mono-part-2-of-3/</link>
		<comments>http://www.integratedwebsystems.com/2010/02/how-to-setup-and-configure-mysql-membership-provider-6-2-2-porting-to-mono-part-2-of-3/#comments</comments>
		<pubDate>Mon, 01 Feb 2010 06:00:00 +0000</pubDate>
		<dc:creator>Nathan Bridgewater</dc:creator>
				<category><![CDATA[ASP.Net]]></category>
		<category><![CDATA[Configuration Tool]]></category>
		<category><![CDATA[Membership]]></category>
		<category><![CDATA[Mono]]></category>
		<category><![CDATA[MySql]]></category>
		<category><![CDATA[MySql.Web]]></category>

		<guid isPermaLink="false">http://www.integratedwebsystems.com/?p=448</guid>
		<description><![CDATA[As the second part of this series, I’ll look at building a website that can use the MySql Membership Provider. This is one of the main hang-ups I’ve run into while porting one of my ASP.NET applications to Mono. With the latest MySql Connector, this turns out to be a very easy thing to do. [...]]]></description>
			<content:encoded><![CDATA[<p>As the second part of this series, I’ll look at building a website that can use the MySql Membership Provider. This is one of the main hang-ups I’ve run into while porting one of my ASP.NET applications to Mono. With the latest MySql Connector, this turns out to be a very easy thing to do. It’s nearly as simple as setting up your web.config with the correct parameters and getting the right connector version.</p>
<p> <span id="more-448"></span><br />
<h3>Download the MySql Connector</h3>
<p>Fortunately now, the MySql.Web assembly comes with the prebuilt versions of the <a href="http://dev.mysql.com/downloads/connector/net/" target="_blank">MySql Connector/Net</a>. If you don’t have it, <a href="http://dev.mysql.com/downloads/connector/net/" target="_blank">go get it</a>.&#160; I recommend the Mono build, even for the Windows folks, because it’s a simple zip file with the assemblies. If you would like to see additional samples, download the Source version of their connector. When you have it downloaded, <strong>add a reference to MySql.Web</strong> in your web project.</p>
<h3>&#160;</h3>
<h3>Database</h3>
<p>As with the Microsoft Sql Server membership provider, you have a choice to place your database tables in an existing application database or in its own database. I prefer to use its own just to keep it separated in case I want to share the Membership component among several applications. If you build upon my <a href="http://www.integratedwebsystems.com/2010/01/installing-opensuse-11-2-with-mono-2-6-1-and-apache-using-text-mode-configuration-porting-to-mono-part-1-of-3/" target="_blank">last post</a>, you can simply create an empty database for your membership data.&#160; Don’t create any tables yet. Just create an empty shell and create a user account for the application to connect your database and has access to create and alter tables. If you’re new to MySql, the <a href="http://dev.mysql.com/downloads/workbench/5.2.html" target="_blank">MySql Administration Tools</a> are extremely handy for this.</p>
<p>&#160;</p>
<h3>Configuration</h3>
<p>The configuration options are mostly the same as the ones you’ve seen in the Microsoft Sql Server membership provider. This one has one added feature, which is an autogenerateschema flag.&#160; This flag instructs the membership provider to actually push schema updates based on the version you’re running. To enable it, simply set it to true.&#160; As with other membership configuration, once you have it enabled and configured to connect to your database, it should work immediately.</p>
<p>There are a few caveats that I ran into while configuring this. For example, hashed passwords only works on Windows .Net; not Mono. Encrypted passwords takes a little more configuration and also (through practice here) only seemed to work on Windows .Net.&#160; There may be some bugs in my version of Mono 2.6.1 or maybe another configuration oddity I couldn’t identify.</p>
<p>Nonetheless, the MySql providers work 100% on Windows. If you’re running on Mono, your main option is to use Clear Text passwords; or if you want to get a little creative, download the source code to the MySql Connector and rewire how it runs its encryption through the framework and roll your own instead.</p>
<p>&#160;</p>
<h3>Configuration Tool</h3>
<p>So moving forward, I built a tiny little configuration tool that you can use to generate the web.config sections you need for this. It takes into account some of my experiences with the things I mentioned like Hashed and Encrypted passwords. It will also auto-generate your MachineKey section if you choose to use encrypted passwords on the Windows side.</p>
<p><a class="launch_tool" href="#" jquery1265988263049="49" jquery1265988344594="2">Launch Configuration Tool</a></p>
<p>Here is the default, Windows based configuration that is generated. You may use this and tweak it or generate your own. </p>
<pre class="brush: xml; gutter: false;">
&lt;?xml version=&quot;1.0&quot;?&gt;
&lt;configuration&gt;
    &lt;connectionStrings&gt;
        &lt;add name=&quot;MySqlMembershipConnection&quot;
            connectionString=&quot;Data Source=server_name;user id=username;password=password;database=database_name;&quot;
            providerName=&quot;MySql.Data.MySqlClient&quot;/&gt;
    &lt;/connectionStrings&gt;

    &lt;system.web&gt;

        &lt;authentication mode=&quot;Forms&quot;&gt;
            &lt;forms
              loginUrl=&quot;~/Account/Logon&quot;

              timeout=&quot;30&quot;
              name=&quot;.ASPXFORM$&quot;
              path=&quot;/&quot;
              requireSSL=&quot;false&quot;
              slidingExpiration=&quot;true&quot;
              defaultUrl=&quot;Default.aspx&quot;

              enableCrossAppRedirects=&quot;false&quot;/&gt;
        &lt;/authentication&gt;

        &lt;membership defaultProvider=&quot;MySqlMembershipProvider&quot;&gt;
            &lt;providers&gt;
                &lt;clear/&gt;
                &lt;add name=&quot;MySqlMembershipProvider&quot;
                      type=&quot;MySql.Web.Security.MySQLMembershipProvider, mysql.web&quot;
                        connectionStringName=&quot;MySqlMembershipConnection&quot;
                        enablePasswordRetrieval=&quot;false&quot;
                        enablePasswordReset=&quot;true&quot;
                        requiresQuestionAndAnswer=&quot;false&quot;
                        requiresUniqueEmail=&quot;true&quot;
                        passwordFormat=&quot;Hashed&quot;
                        maxInvalidPasswordAttempts=&quot;5&quot;
                        minRequiredPasswordLength=&quot;6&quot;
                        minRequiredNonalphanumericCharacters=&quot;0&quot;
                        passwordAttemptWindow=&quot;10&quot;

                        applicationName=&quot;/&quot;
                        autogenerateschema=&quot;true&quot;/&gt;
            &lt;/providers&gt;
        &lt;/membership&gt;

        &lt;roleManager enabled=&quot;true&quot; defaultProvider=&quot;MySqlRoleProvider&quot;&gt;
            &lt;providers&gt;
                &lt;clear /&gt;
                &lt;add connectionStringName=&quot;MySqlMembershipConnection&quot;
                    applicationName=&quot;/&quot;
                    name=&quot;MySqlRoleProvider&quot;
                    type=&quot;MySql.Web.Security.MySQLRoleProvider, mysql.web&quot;
                    autogenerateschema=&quot;true&quot;/&gt;
            &lt;/providers&gt;
        &lt;/roleManager&gt;

        &lt;profile&gt;
            &lt;providers&gt;
                &lt;clear/&gt;
                &lt;add type=&quot;MySql.Web.Security.MySqlProfileProvider, mysql.web&quot;
                      name=&quot;MySqlProfileProvider&quot;
                      applicationName=&quot;/&quot;
                      connectionStringName=&quot;MySqlMembershipConnection&quot;
                      autogenerateschema=&quot;true&quot;/&gt;
            &lt;/providers&gt;
        &lt;/profile&gt;
    &lt;/system.web&gt;
&lt;/configuration&gt;
</pre>
<h3>Testing Membership</h3>
<p>So once you have your membership configured, you’ll need to test it out. First, don&#8217;t forget to update your connection string credentials. Then the easiest way to test your membership configuration (if you are using Visual Studio) is to use the ASP.NET Configuration Tool (appears when selecting your web project). <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="Solution Toolbar" border="0" alt="Solution Toolbar" align="right" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/Toolbar.jpg" width="368" height="86" />When membership configuration is working properly the landing page will show you how many users are configured in the system. If there are none, it will still show you zero. You will also have access to add, remove, and update users from this screen.&#160; If it doesn’t show you anything, then there’s likely something wrong in your configuration.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="aspnetConfig" border="0" alt="aspnetConfig" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/aspnetConfig.jpg" width="512" height="180" /></p>
<p>&#160;</p>
<p>After the first time testing your membership, you’ll notice all the schema in the database will have been generated and is now filled with data. This was caused by the<em> autogeneratechema</em> flag being set to “true”.&#160; As new versions of MySql.Web assembly are released from MySql, any schema changes new to each version will automatically be applied with this flag enabled. It should also alleviate that “Schema is missing or incorrect” error.</p>
<p><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="database" border="0" alt="database" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/database.jpg" width="602" height="266" /></p>
<p>&#160;</p>
<h3>Wrap Up</h3>
<p>So with that, you should have your ASP.NET application configured to run membership to a MySql database. If you’re using Mono, this configuration should work with the default ASP.NET MVC web application (after you reference the MySql assemblies and setup the configuration of course).&#160; Look forward to my next post, which will be the final part of this series about porting an ASP.NET MVC application to Mono. We’ll be taking a very simple MVC application called <a href="http://sitemanager.codeplex.com" target="_blank">SiteManager on CodePlex</a> and convert it to run on Mono and MySql.</p>
<p>&#160;</p>
<h3>Useful Links</h3>
<ul>
<li><a href="http://dev.mysql.com/downloads/mysql/" target="_blank">MySql Community Server</a>&#160; &#8211; Installing on OpenSuse Linux? <a href="http://www.integratedwebsystems.com/2010/01/installing-opensuse-11-2-with-mono-2-6-1-and-apache-using-text-mode-configuration-porting-to-mono-part-1-of-3/#InstallMonoAndApache">Refer to my last post</a>. </li>
<li><a href="http://dev.mysql.com/downloads/workbench/5.2.html" target="_blank">MySql GUI Tools</a> </li>
<li><a href="http://dev.mysql.com/downloads/connector/net/" target="_blank">MySql Connector/NET</a> </li>
<li><a class="launch_tool" href="#">My Cool Configuration Tool</a> </li>
</ul>
<p><div id="dialogContent"></div>
<link href="/tools/css/smoothness/jquery-ui-1.7.2.custom.css" rel="stylesheet" type="text/css" />
<link href="/tools/css/p448.css" rel="stylesheet" type="text/css" />
	<script type="text/javascript" src="http://www.google.com/jsapi"></script><br />
	<script type="text/javascript">
		google.load("jquery", "1.4.1");
		google.load("jqueryui", "1.7.2");
	</script><br />
	<script language="javascript" type="text/javascript" src="/tools/js/p448.js"></script><br />
	<script src="/tools/js/MicrosoftAjax.js" type="text/javascript"></script><br />
	<script src="/tools/js/MicrosoftMvcAjax.js" type="text/javascript"></script></p>
]]></content:encoded>
			<wfw:commentRss>http://www.integratedwebsystems.com/2010/02/how-to-setup-and-configure-mysql-membership-provider-6-2-2-porting-to-mono-part-2-of-3/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Cold Weather Lunar Ring (Lunar-bow)</title>
		<link>http://www.integratedwebsystems.com/2010/01/cold-weather-lunar-ring-lunar-bow/</link>
		<comments>http://www.integratedwebsystems.com/2010/01/cold-weather-lunar-ring-lunar-bow/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 18:59:13 +0000</pubDate>
		<dc:creator>Nathan Bridgewater</dc:creator>
				<category><![CDATA[Off-Topic]]></category>
		<category><![CDATA[cold]]></category>
		<category><![CDATA[halo]]></category>
		<category><![CDATA[moon]]></category>
		<category><![CDATA[night]]></category>
		<category><![CDATA[ring]]></category>
		<category><![CDATA[space]]></category>

		<guid isPermaLink="false">http://www.integratedwebsystems.com/?p=620</guid>
		<description><![CDATA[I thought I’d share a couple photos I took recently for fun.

 
The first one is a refraction of moonlight through ice crystals in the atmosphere. It was very cool to see. This image was taken with a 30 second exposure with our Nikon D60.&#160; I found more info describing this phenomenon here.
&#160;
 I also [...]]]></description>
			<content:encoded><![CDATA[<p>I thought I’d share a couple photos I took recently for fun.</p>
</p>
<p> <span id="more-620"></span>
<p sizcache="0" sizset="0"><a class="lightbox" title="Lunar-bow - Moonlight refraction off ice crystals in the atmosphere" href="/resources/p620/2.jpg"><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="Lunar-bow" border="0" alt="Lunar-bow" align="right" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/DSC_11851.jpg" width="244" height="165" /></a>The first one is a refraction of moonlight through ice crystals in the atmosphere. It was very cool to see. This image was taken with a 30 second exposure with our <a href="http://www.nikonusa.com/Find-Your-Nikon/ProductDetail.page?pid=25438" target="_blank">Nikon D60</a>.&#160; I found more info <a href="http://home.hiwaay.net/~krcool/Astro/moon/moonring/" target="_blank">describing this phenomenon here</a>.</p>
<p>&#160;</p>
<p sizcache="0" sizset="3"><a class="lightbox" title="Night time crystallized snow" href="/resources/p620/1.jpg"><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="Night snow" border="0" alt="Night snow" align="left" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/night_snow.jpg" width="244" height="165" /></a> I also took another one a couple weeks ago after the snow storm hit us pretty hard. I live in the Midwest, and we typically don’t see this kind of snow. This image was taken a few nights later when the snow had time to melt a little and then re-crystallize on the surface.</p>
<p> <script type="text/javascript" src="http://www.google.com/jsapi"></script> <script type="text/javascript">
google.load("jquery", "1.4.1");
</script> <script type="text/javascript" src="/js/jquery.lightbox-0.5.pack.js"></script>
<link rel="stylesheet" type="text/css" href="/css/jquery.lightbox-0.5.css" media="screen" /> <script type="text/javascript" src="/tools/js/lightbox.js"></script> </p>
<p><a href="http://creativecommons.org/licenses/by-sa/3.0/" rel="license"><img style="border-right-width: 0px; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" alt="Creative Commons License" src="http://i.creativecommons.org/l/by-sa/3.0/88x31.png" /></a>     <br /><span rel="dc:type" property="dc:title" href="http://purl.org/dc/dcmitype/StillImage" xmlns:dc="http://purl.org/dc/elements/1.1/">Lunar-bow</span> by <a href="http://www.integratedwebsystems.com" rel="cc:attributionURL" property="cc:attributionName" xmlns:cc="http://creativecommons.org/ns#">Nathan Bridgewater</a> is licensed under a <a href="http://creativecommons.org/licenses/by-sa/3.0/" rel="license">Creative Commons Attribution-Share Alike 3.0 Unported License</a>.     <br />Permissions beyond the scope of this license may be available at <a href="http://www.integratedwebsystems.com" rel="cc:morePermissions" xmlns:cc="http://creativecommons.org/ns#">http://www.integratedwebsystems.com</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.integratedwebsystems.com/2010/01/cold-weather-lunar-ring-lunar-bow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Installing OpenSuse 11.2 with Mono 2.6.1 and Apache Using Text Mode Configuration &#8211; Porting to Mono Part 1 of 3</title>
		<link>http://www.integratedwebsystems.com/2010/01/installing-opensuse-11-2-with-mono-2-6-1-and-apache-using-text-mode-configuration-porting-to-mono-part-1-of-3/</link>
		<comments>http://www.integratedwebsystems.com/2010/01/installing-opensuse-11-2-with-mono-2-6-1-and-apache-using-text-mode-configuration-porting-to-mono-part-1-of-3/#comments</comments>
		<pubDate>Mon, 25 Jan 2010 13:30:00 +0000</pubDate>
		<dc:creator>Nathan Bridgewater</dc:creator>
				<category><![CDATA[Mono]]></category>
		<category><![CDATA[.NET]]></category>
		<category><![CDATA[apache]]></category>
		<category><![CDATA[installing]]></category>
		<category><![CDATA[linux]]></category>
		<category><![CDATA[mod_mono]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[openSuse]]></category>

		<guid isPermaLink="false">http://www.integratedwebsystems.com/?p=441</guid>
		<description><![CDATA[I’ve always kept an eye on the Mono project, mostly out of curiosity and intrigue. The last time I played around with Mono it was at version 2.0, and at the time I didn’t really spend a lot of time on it because it didn’t support some of the things I was using.&#160; Well recently, [...]]]></description>
			<content:encoded><![CDATA[<p>I’ve always kept an eye on the Mono project, mostly out of curiosity and intrigue. The last time I played around with Mono it was at version 2.0, and at the time I didn’t really spend a lot of time on it because it didn’t support some of the things I was using.&#160; Well recently, I regained interest in Mono when I saw it now supports MVC and some of Dblinq. And since I’ve been buzzing on the whole MVC thing for awhile, I decided to check Mono out for myself and start a fun little porting project. So this is the first part of a three part series describing everything I did to get a server up and running and one of my Asp.Net MVC applications ported to Mono.</p>
<p>This first part will cover installing and configuring an OpenSuse 11.2 server with Apache/Mono and SSH. <a href="http://www.integratedwebsystems.com/2010/02/how-to-setup-and-configure-mysql-membership-provider-6-2-2-porting-to-mono-part-2-of-3/">The second part</a> will talk about how to setup a MySql Membership provider (with mono and Windows), and the third part is a walkthrough showing how to port a simple Asp.Net MVC site to mono and MySql. I’m also targeting those of you who use virtual hosting where you might only have SSH (after install) to configure your server, so I will be using text based tools: SSH, vi, and yast for all my installations and configuration after getting the base system installed.</p>
<p> <span id="more-441"></span>
<p><script type="text/javascript" src="http://www.google.com/jsapi"></script><script type="text/javascript">
		google.load("jquery", "1.4.1");
		google.load("jqueryui", "1.7.2");
	</script><script type="text/javascript" src="/js/jquery.lightbox-0.5.pack.js"></script>
<link rel="stylesheet" type="text/css" href="/css/jquery.lightbox-0.5.css" media="screen" /><script type="text/javascript" src="/tools/js/p441.js"></script></p>
<p sizcache="0" sizset="0">First off, let me just say that I’m a Windows .NET programmer; not a Linux programmer. I know enough about Linux to dig my way around most of the basic stuff, so if anything seems incorrect in this post, feel free to correct me. <img src='http://www.integratedwebsystems.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> &#160; I’m extremely intrigued by Linux and its open source philosophy. I use it for a handful of useful, rock solid services like <a href="http://subversion.tigris.org/" target="_blank">Subversion</a>, <a href="http://www.postfix.org/" target="_blank">Postfix</a>, <a href="http://www.samba.org/" target="_blank">Samba</a> file servers and <a href="http://www.mysql.com/" target="_blank">MySql</a>. I also share an interest with many small web shops in finding more affordable hosting solutions for smaller Asp.Net apps. And in light of Mono being able to run MVC apps, it’s very exciting to think of what we can do with it.</p>
<h3>Index</h3>
<ul sizcache="0" sizset="4">
<li sizcache="0" sizset="4"><a href="#BeforeYouBegin">Before You Begin</a>&#160; </li>
<li sizcache="0" sizset="5"><a href="#InstallingLinuxPart1">Installing Linux Graphical (part 1)</a> </li>
<li sizcache="0" sizset="6"><a href="#InstallingLinuxPart2">Configuring Linux During Install (part 2)</a> </li>
<li sizcache="0" sizset="7"><a href="#ConfiguringLinuxAfterInstall">Configuring Linux After Install</a> </li>
<li sizcache="0" sizset="8"><a href="#UpdatingSoftware">Updating Software</a> </li>
<li sizcache="0" sizset="9"><a href="#InstallMonoAndApache">Install Mono, Apache, and MySql</a> </li>
<li sizcache="0" sizset="10"><a href="#ConfigureApache">Configure a Virtual Host &amp; Web Directory</a> </li>
<li sizcache="0" sizset="11"><a href="#RunningMVC">Running the Default Visual Studio MVC Website</a> </li>
<li sizcache="0" sizset="12"><a href="#UsefulLinks">Useful Links</a> </li>
</ul>
<p sizcache="0" sizset="11">&#160;</p>
<h3 sizcache="0" sizset="13"><a name="BeforeYouBegin">Before you Begin</a></h3>
<p sizcache="0" sizset="14">There are a few things you need to download before you get started.&#160; First of all, you’ll need an SSH client for file transfer and console access. I’m using <a href="http://filezilla-project.org/download.php" target="_blank">FileZilla</a> and <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html" target="_blank">Putty</a> as my SSH clients. If you’ve never used it before, think of SSH like telnet and FTP wrapped into one.</p>
<p>Here’s a few tips on navigating the text mode installer screens. Use the Tab Key to cycle through fields or change focus between sections on the screen. Use the Spacebar or Enter to select an option. Esc can back out of a dropdown option. You can use the arrow keys to cycle options in a section.</p>
<p sizcache="0" sizset="16">Download one of the <a href="http://software.opensuse.org/112/en" target="_blank">installers on OpenSuse’s website.</a> Burn or mount the ISO and boot your machine from it to begin.</p>
<p><em>Note: while I was doing this on a test virtual machine, I could only get the Network install to work with Virtual PC 2007 on my hardware. All the versions worked fine when installing it to a physical machine. If you choose the network install, you may need to configure your DHCP settings before the GUI installer starts. (with Virtual PC, make sure the correct external network card is exposed to the virtual machine). </em></p>
<h3 sizcache="0" sizset="17"><a name="InstallingLinuxPart1">Installing Linux Graphical (part 1)</a></h3>
<p>In sequence, here are (most) of the screens you’ll see during the first part of installing OpenSuse 11.2.</p>
<div class="gallery" sizcache="0" sizset="18">
<table border="0" cellpadding="5" sizcache="0" sizset="18">
<tbody sizcache="0" sizset="18">
<tr sizcache="0" sizset="18">
<td width="269" sizcache="0" sizset="18"><a title="OpenSuse 11.2 boot screen" href="/resources/p441/install/1.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="OpenSuse Boot Screen" border="0" alt="OpenSuse Boot Screen" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/1.jpg" width="244" height="184" /></a></td>
<td width="375">&#160;</td>
</tr>
<tr sizcache="0" sizset="19">
<td width="269" sizcache="0" sizset="19"><a title="Language selection" href="/resources/p441/install/2.jpg"><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="Language selection" border="0" alt="Language selection" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/22.jpg" width="244" height="199" /></a></td>
<td width="375">
<p>Language selection</p>
</td>
</tr>
<tr sizcache="0" sizset="20">
<td width="269" sizcache="0" sizset="20"><a title="New install. Disable Auto-configuration" href="/resources/p441/install/3.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="New install. Disable auto-configuration." border="0" alt="New install. Disable auto-configuration." src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/3.jpg" width="244" height="199" /></a></td>
<td width="375">
<p>Uncheck<strong> </strong><em>Use Automatic Configuration</em></p>
</td>
</tr>
<tr sizcache="0" sizset="21">
<td width="269" sizcache="0" sizset="21"><a title="Choose your time zone" href="/resources/p441/install/4.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Choose your time zone" border="0" alt="Choose your time zone" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/41.jpg" width="244" height="199" /></a></td>
<td width="375">
<p>Choose your time zone.</p>
</td>
</tr>
<tr sizcache="0" sizset="22">
<td width="269" sizcache="0" sizset="22"><a title="Desktop selection. See options." href="/resources/p441/install/5.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Desktop selection" border="0" alt="Desktop selection" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/51.jpg" width="244" height="199" /></a></td>
<td width="375">
<p>I chose minimal server.</p>
<p><strong>Optional:</strong> You may choose a desktop if you wish to use remote VNC to remotely admin your server with a GUI.&#160; VNC is kind of like using Remote Desktop. To do that, choose your desktop here, and we’ll configure it to still boot to text mode later at the summary screen.</p>
</td>
</tr>
<tr sizcache="0" sizset="23">
<td width="269" sizcache="0" sizset="23"><a title="Partition selection. I used defaults." href="/resources/p441/install/6.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Partition selection" border="0" alt="Partition selection" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/61.jpg" width="244" height="199" /></a></td>
<td width="375">Partition selection. I used defaults.</td>
</tr>
<tr sizcache="0" sizset="24">
<td width="269" sizcache="0" sizset="24"><a title="Setting up the first user. Uncheck Automatic Login." href="/resources/p441/install/7.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Setting up the first user" border="0" alt="Setting up the first user" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/71.jpg" width="244" height="199" /></a></td>
<td width="375">
<p>Enter your username. Uncheck automatic login.</p>
<p><strong>Optional:</strong> You may choose a different password for the root user.&#160; This is good if you have a public server sitting in the cloud in case someone gets the password to your normal user account.</p>
</td>
</tr>
<tr sizcache="0" sizset="25">
<td width="269" sizcache="0" sizset="25"><a title="Summary. Enable SSH." href="/resources/p441/install/8.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Summary" border="0" alt="Summary" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/81.jpg" width="244" height="199" /></a></td>
<td width="375">
<p>Summary screen. Scroll to the bottom.<strong> Click “enable and open” for Firewall and SSH</strong>. We’ll use SSH to remotely admin the server.</p>
<p><strong>Optional: </strong>If you chose a desktop earlier, change the <em>Default Runlevel </em>to 3 (Full multiuser with network). This will cause the server to boot to normal text mode by default.</p>
</td>
</tr>
<tr sizcache="0" sizset="26">
<td width="269" sizcache="0" sizset="26"><a title="Confirm Installation" href="/resources/p441/install/9.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Confirm Installation" border="0" alt="Confirm Installation" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/91.jpg" width="244" height="199" /></a></td>
<td width="375">
<p>Click Install to continue.</p>
</td>
</tr>
<tr sizcache="0" sizset="27">
<td width="269" sizcache="0" sizset="27"><a title="Progress" href="/resources/p441/install/12.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Installation Progress" border="0" alt="Installation Progress" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/121.jpg" width="244" height="199" /></a></td>
<td width="375">&#160;</td>
</tr>
</tbody>
</table></div>
<h3 sizcache="0" sizset="28"><a name="InstallingLinuxPart2">Configuring Linux During Install (part 2)</a></h3>
<p>After the first phase, your computer will reboot and begin the manual configuration phase. As I mentioned earlier, these screens are pretty easy to navigate. Use tab to cycle through the fields or change focus to different sections. Use space or enter to make a selection. Also, the highlighted letters in words are hotkeys you can use in combination with the Alt key.&#160; Each section will continue when you select the NEXT option in the bottom right corner.</p>
<div class="gallery" sizcache="0" sizset="29">
<table border="0" cellpadding="5" sizcache="0" sizset="29">
<tbody sizcache="0" sizset="29">
<tr sizcache="0" sizset="29">
<td valign="top" width="269" sizcache="0" sizset="29"><a title="First configuration screen. Enter your hostname" href="/resources/p441/config/1.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="First configuration screen. Enter your hostname" border="0" alt="First configuration screen. Enter your hostname" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/11.jpg" width="244" height="184" /></a> </td>
<td width="375">
<p>This is the first configuration screen. Enter your new machine hostname (or leave it default).</p>
</td>
</tr>
<tr sizcache="0" sizset="30">
<td valign="top" width="269" sizcache="0" sizset="30"><a title="Progress after choosing hostname." href="/resources/p441/config/2.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Progress screen" border="0" alt="Progress screen" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/21.jpg" width="244" height="184" /></a> </td>
<td width="375">
<p>Showing hostname configuration progress.</p>
</td>
</tr>
<tr sizcache="0" sizset="31">
<td valign="top" width="269" sizcache="0" sizset="31"><a title="Configuration screen. Choose Network Interfaces" href="/resources/p441/config/3.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Main configuration screen. Choose netowrk interface" border="0" alt="Main configuration screen. Choose netowrk interface" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/31.jpg" width="244" height="183" /></a> </td>
<td width="375">
<p>This is the main configuration screen. You will set your network configuration here. Tab until you see the bounding box around the gray area light up. Then down arrow to Network Interfaces. Press enter to select it.</p>
</td>
</tr>
<tr sizcache="0" sizset="32">
<td valign="top" width="269" sizcache="0" sizset="32"><a title="Network Interface screen." href="/resources/p441/config/4.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Network interfaces screen" border="0" alt="Network interfaces screen" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/4.jpg" width="244" height="183" /></a> </td>
<td width="375">
<p><strong>Overview Screen</strong></p>
<p>This is the first Network Interfaces screen. There are three focus areas. The first is the top tab area: Overview, Hostname/DNS, and Routing.</p>
<p>Tab to the interface list and select your interface card for your main Internet connection. Then press Alt-i to view its details</p>
</td>
</tr>
<tr sizcache="0" sizset="33">
<td valign="top" width="269" sizcache="0" sizset="33"><a title="Shows ethernet settings. Leave as DHCP or set to static." href="/resources/p441/config/5.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Ethernet NIC settings" border="0" alt="Ethernet NIC settings" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/5.jpg" width="244" height="184" /></a> </td>
<td width="375">
<p>Shows Ethernet details. If you choose to use static IP, this is where to set that information. Set the IP address, subnet, etc. You may leave this as DHCP if you wish.&#160; When you’re done tab and select Next.</p>
</td>
</tr>
<tr sizcache="0" sizset="34">
<td valign="top" width="269" sizcache="0" sizset="34"><a title="Set hostname/DNS" href="/resources/p441/config/7.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Set hostname and DNS" border="0" alt="Set hostname and DNS" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/7.jpg" width="244" height="184" /></a> </td>
<td width="375">
<p>From the Overview screen (bolded above), move to the Hostname/DNS section. Set your hostname and your DNS servers (if you chose static IP in the previous step).</p>
</td>
</tr>
<tr sizcache="0" sizset="35">
<td valign="top" width="269" sizcache="0" sizset="35"><a title="Routing configuration" href="/resources/p441/config/8.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Routing configuration" border="0" alt="Routing configuration" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/8.jpg" width="244" height="183" /></a> </td>
<td width="375">
<p>If you chose a static IP, tab from the Overview Screen to Routing. Set your default gateway and associate it with the correct device.</p>
</td>
</tr>
<tr sizcache="0" sizset="36">
<td valign="top" width="269" sizcache="0" sizset="36"><a title="Writing network configuration." href="/resources/p441/config/9.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Writing network configuration" border="0" alt="Writing network configuration" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/9.jpg" width="244" height="183" /></a> </td>
<td width="375">After clicking Next from the Overview Screen, the configuration changes will be written to disk. </td>
</tr>
<tr sizcache="0" sizset="37">
<td valign="top" width="269" sizcache="0" sizset="37"><a title="Test Internet Connection" href="/resources/p441/config/10.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Test Internet" border="0" alt="Test Internet" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/10.jpg" width="244" height="185" /></a> </td>
<td width="375">This step will test your Internet connection. If successful, it will check for updates. </td>
</tr>
<tr sizcache="0" sizset="38">
<td valign="top" width="269" sizcache="0" sizset="38"><a title="Successful connection" href="/resources/p441/config/11.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Successful connection" border="0" alt="Successful connection" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/111.jpg" width="244" height="184" /></a> </td>
<td width="375">Successful connection</td>
</tr>
<tr sizcache="0" sizset="39">
<td valign="top" width="269" sizcache="0" sizset="39"><a title="Updating packages" href="/resources/p441/config/12.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Updating packages" border="0" alt="Updating packages" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/12.jpg" width="244" height="184" /></a> </td>
<td width="375">Updating packages</td>
</tr>
<tr sizcache="0" sizset="40">
<td valign="top" width="269" sizcache="0" sizset="40"><a title="Updating packages" href="/resources/p441/config/13.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Updating packages" border="0" alt="Updating packages" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/13.jpg" width="244" height="183" /></a> </td>
<td width="375">&#160;</td>
</tr>
<tr sizcache="0" sizset="41">
<td valign="top" width="269" sizcache="0" sizset="41"><a title="Run updates" href="/resources/p441/config/14.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Run updates" border="0" alt="Run updates" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/14.jpg" width="244" height="184" /></a> </td>
<td width="375">Run updates</td>
</tr>
<tr sizcache="0" sizset="42">
<td valign="top" width="269" sizcache="0" sizset="42"><a title="Package updates" href="/resources/p441/config/15.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Package updates" border="0" alt="Package updates" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/15.jpg" width="244" height="184" /></a> </td>
<td width="375">&#160;</td>
</tr>
<tr sizcache="0" sizset="43">
<td valign="top" width="269" sizcache="0" sizset="43"><a title="Downloading updates" href="/resources/p441/config/16.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Downloading updates" border="0" alt="Downloading updates" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/16.jpg" width="244" height="183" /></a> </td>
<td width="375">&#160;</td>
</tr>
<tr sizcache="0" sizset="44">
<td valign="top" width="269" sizcache="0" sizset="44"><a title="Installing updates" href="/resources/p441/config/17.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Installing updates" border="0" alt="Installing updates" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/17.jpg" width="244" height="184" /></a> </td>
<td width="375">Will reboot after this step. You may need to click Next after it finishes.</td>
</tr>
<tr sizcache="0" sizset="45">
<td valign="top" width="269" sizcache="0" sizset="45"><a title="After reboot, next config screen." href="/resources/p441/config/18.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="After reboot, next config screen." border="0" alt="After reboot, next config screen." src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/18.jpg" width="244" height="183" /></a> </td>
<td width="375">&#160;</td>
</tr>
<tr sizcache="0" sizset="46">
<td valign="top" width="269" sizcache="0" sizset="46"><a href="/resources/p441/config/19.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="" border="0" alt="" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/19.jpg" width="244" height="184" /></a> </td>
<td width="375">&#160;</td>
</tr>
<tr sizcache="0" sizset="47">
<td valign="top" width="269" sizcache="0" sizset="47"><a title="Printer setup" href="/resources/p441/config/20.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Printer setup" border="0" alt="Printer setup" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/20.jpg" width="244" height="183" /></a> </td>
<td width="375">I used defaults here. </td>
</tr>
<tr sizcache="0" sizset="48">
<td valign="top" width="269" sizcache="0" sizset="48"><a title="Finally!" href="/resources/p441/config/21.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Finally!" border="0" alt="Finally!" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/211.jpg" width="244" height="184" /></a> </td>
<td width="375">Finally done! </td>
</tr>
<tr sizcache="0" sizset="49">
<td valign="top" width="269" sizcache="0" sizset="49"><a title="Console after installation" href="/resources/p441/config/22.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Console after installation" border="0" alt="Console after installation" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/221.jpg" width="244" height="183" /></a> </td>
<td width="375">The installation drops you to a console.&#160; </td>
</tr>
</tbody>
</table></div>
<p>&#160;</p>
<h3 sizcache="0" sizset="50"><a name="ConfiguringLinuxAfterInstall">Configuring Linux After Install</a></h3>
<div class="gallery" sizcache="0" sizset="51">
<p sizcache="0" sizset="51"><a title="Putty, open a connection to your new server." href="/resources/p441/post_install/1.jpg"><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="Putty, open connection" border="0" alt="Putty, open connection" align="right" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/113.jpg" width="244" height="234" /></a> At this point, your operating system is installed and accessible online via SSH. (If you purchased a VM, this is where you’ll usually begin). To connect to your new server, open Putty and enter your static IP or hostname for your new server. Select SSH connection type. Then click Open. You will be prompted to trust the certificate. Click YES, and login to your new server using the account you setup during install.</p>
<p sizcache="0" sizset="47"><em>NOTE: (You may optionally save these connection settings by typing a name and clicking Save. </em></p>
</p></div>
<p><strong>Root Access      <br /></strong>You’ll need root access to perform most of the tasks we’re doing, so enter: <strong>su</strong><em>, </em>then type the root password you configured during install. The command prompt will change color to <strong><font color="#ff0000">red</font></strong>.</p>
<h3 sizcache="0" sizset="52"><a name="UpdatingSoftware">Updating Software</a></h3>
<p>One of the really cool things about most Linux distributions is their package management. It’s a one-stop-shop for installing, updating, and removing software on your system. Fedora has <em>yum</em>, Debian has <em>apt-get</em>, OpenSuse has<em> </em><em>zypper</em>. Using these utilities is very straight forward. So if you didn’t update your system during install, you can do it now by entering:</p>
<pre class="brush: bash; gutter: false; toolbar: false;">zypper update</pre>
<p>You can run this command occasionally to update your system. To see more details about how to use it. Enter: man zypper</p>
<p>&#160;</p>
<h3 sizcache="0" sizset="53"><a name="InstallMonoAndApache">Install Mono, Apache, and MySql</a></h3>
<p sizcache="0" sizset="49"><strong>Installing Mono and Apache</strong></p>
<p sizcache="0" sizset="49">With zypper, we can cheat a little to install mono, apache, and all dependencies. First we need to add the mono repositories so zypper knows how to find it.</p>
<p sizcache="0" sizset="49">Enter the following lines separately:</p>
<pre class="brush: bash; gutter: false;">zypper addrepo http://ftp.novell.com/pub/mono/download-stable/openSUSE_11.2 mono-stable
zypper refresh --repo mono-stable
zypper dist-upgrade --repo mono-stable</pre>
<p sizcache="0" sizset="49">Our cheat is going to be installing Mod_Mono, which is the mono plugin for Apache. This will force it to install apache, mono, xsp and everything we need to get started.</p>
<pre class="brush: bash; gutter: false; toolbar: false;">zypper install mod_mono</pre>
<p><strong>Autostart Apache</strong></p>
<p>To make apache start when the system reboots, enter this command:</p>
<pre class="brush: bash; gutter: false; toolbar: false;">chkconfig --add apache2</pre>
<p><strong>Installing MySql Server</strong></p>
<p>To download and install mysql server and client, enter this command:</p>
<pre class="brush: bash; gutter: false; toolbar: false;">zypper install mysql</pre>
<p>Add MySql to your startup and start it:</p>
<pre class="brush: bash; gutter: false; toolbar: false;">chkconfig --add mysql

service mysql start</pre>
<p>Then configure the server with:</p>
<pre class="brush: bash; gutter: false; toolbar: false;">mysql_secure_installation</pre>
<p>Follow the instructions and setup your server. The first question will be to enter your root password; the first time you run this, just press enter with a blank password, then choose <strong>Y</strong> to enter a new root password. You’ll also want to disable remote root access, the anonymous user, and test database.</p>
<p><strong>Optional:</strong></p>
<p>Now setup your user account so you can remotely access the server. This also requires you to expose your MySql server over the Internet if you’re running a hosted server. Users in MySql are username &amp; host based. Both parts make up a unique user.</p>
<p><strong>To add a user:</strong></p>
<p>Connect to your database server using your new root password. Enter: <strong>mysql -p</strong></p>
<p>Here is an example of a user you would typically use for a specific application running on the local machine. This statement grants all privileges on a database called test_database and all its tables to a username ‘my_new_username’ who can only connect from localhost.</p>
<pre class="brush: sql; gutter: false;">grant all privileges on test_database.* to 'my_new_username'@'localhost' identified by 'new_password' with grant option;</pre>
<p>An admin user with access to everything from any location would have a statement similar to this:</p>
<pre class="brush: sql; gutter: false;">grant all privileges on *.* to 'super_user'@'%' identified by 'super_secret_pw' with grant option;</pre>
<p>Enter <strong>quit</strong> to exit the MySql client.</p>
<p><strong>Firewall </strong></p>
<p>This is actually much simpler than it looks. I’m showing all these screens just for reference. Basically, just use yast as the tool configure the firewall. It has a nice little interface similar to the post-install configuration. For what we’re doing, add your network device to the External Zone, then add Secure Shell Server and HTTP Web Server to the allowed services. Then just enable and turn on your firewall (if it isn’t already on)</p>
<div class="gallery" sizcache="0" sizset="54">
<table border="0" cellpadding="5" sizcache="0" sizset="54">
<tbody sizcache="0" sizset="54">
<tr sizcache="0" sizset="54">
<td valign="top" width="269" sizcache="0" sizset="54"><a title="Start yast." href="/resources/p441/post_install/6.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Start Yast" border="0" alt="Start Yast" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/6.jpg" width="244" height="154" /></a> </td>
<td width="375">Enter: <strong>yast</strong></td>
</tr>
<tr sizcache="0" sizset="55">
<td valign="top" width="269" sizcache="0" sizset="55"><a title="Go to interface configuration" href="/resources/p441/post_install/7.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Interface configuration" border="0" alt="Interface configuration" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/72.jpg" width="244" height="154" /></a> </td>
<td width="375">Navigate to Interfaces, set your network device to be in the External Zone. </td>
</tr>
<tr sizcache="0" sizset="56">
<td valign="top" width="269" sizcache="0" sizset="56"><a title="Add allowed sevices" href="/resources/p441/post_install/8.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Allowed Services" border="0" alt="Allowed Services" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/82.jpg" width="244" height="155" /></a> </td>
<td width="375">Navigate to Allowed Services, select External Zone, then select Secure Shell Server. </td>
</tr>
<tr sizcache="0" sizset="57">
<td valign="top" width="269" sizcache="0" sizset="57"><a title="Add each service individually" href="/resources/p441/post_install/9.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Add each service individually" border="0" alt="Add each service individually" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/92.jpg" width="244" height="155" /></a> </td>
<td width="375">
<p>Use the Add link to add the selected service to the list.</p>
<p><strong>Repeat this for HTTP server</strong>.</p>
<p><strong>Optional:</strong> Add MySql server if you want to expose it to the Internet and access it remotely with your tools.</p>
</td>
</tr>
<tr sizcache="0" sizset="58">
<td valign="top" width="269" sizcache="0" sizset="58"><a title="Enable and start the firewall" href="/resources/p441/post_install/10.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Enable and start the firewall" border="0" alt="Enable and start the firewall" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/101.jpg" width="244" height="155" /></a> </td>
<td width="375">Enable and Start your firewall from the Start Up screen. </td>
</tr>
<tr sizcache="0" sizset="59">
<td valign="top" width="269" sizcache="0" sizset="59"><a title="Finish" href="/resources/p441/post_install/11.jpg"><img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Finish" border="0" alt="Finish" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/114.jpg" width="244" height="155" /></a> </td>
<td width="375">Finish</td>
</tr>
</tbody>
</table>
</div>
<p><strong></strong></p>
<p>&#160;</p>
<h3 sizcache="0" sizset="60"><a name="ConfigureApache">Configure a Virtual Host &amp; Web Directory</a></h3>
<p sizcache="0" sizset="61">I used the <a href="http://go-mono.com/config-mod-mono/" target="_blank">Mod_Mono configuration tool</a> on the Mono website, which built the following configuration file. It looks big, but most of it’s comments. The key notes here are that it runs .Net 2.0, it’s root directory and that it handles all requests through Mono (good for MVC). It also does some nice things like compress the output on certain files as well as the Mono output.</p>
<div class="gallery" sizcache="0" sizset="62">
<p sizcache="0" sizset="62"><a title="Using the Mod_Mono configuration tool." href="/resources/p441/post_install/14.jpg"><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="Using the Mod_Mono configuration tool" border="0" alt="Using the Mod_Mono configuration tool" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/141.jpg" width="216" height="244" /></a></p>
</div>
<p sizcache="0" sizset="61">&#160;</p>
<pre class="brush: xml; gutter: false; toolbar: false;">&lt;VirtualHost *:80&gt;
  ServerName odin.integratedwebsystems.int
  ServerAdmin web-admin@odin.integratedwebsystems.int
  DocumentRoot /srv/www/odin.integratedwebsystems.int
  # MonoServerPath can be changed to specify which version of ASP.NET is hosted
  # mod-mono-server1 = ASP.NET 1.1 / mod-mono-server2 = ASP.NET 2.0
  # For SUSE Linux Enterprise Mono Extension, uncomment the line below:
  # MonoServerPath odin.integratedwebsystems.int &quot;/opt/novell/mono/bin/mod-mono-server2&quot;
  # For Mono on openSUSE, uncomment the line below instead:
  MonoServerPath odin.integratedwebsystems.int &quot;/usr/bin/mod-mono-server2&quot;

  # To obtain line numbers in stack traces you need to do two things:
  # 1) Enable Debug code generation in your page by using the Debug=&quot;true&quot;
  #    page directive, or by setting &lt;compilation debug=&quot;true&quot; /&gt; in the
  #    application's Web.config
  # 2) Uncomment the MonoDebug true directive below to enable mod_mono debugging
  MonoDebug odin.integratedwebsystems.int true

  # The MONO_IOMAP environment variable can be configured to provide platform abstraction
  # for file access in Linux.  Valid values for MONO_IOMAP are:
  #    case
  #    drive
  #    all
  # Uncomment the line below to alter file access behavior for the configured application
  MonoSetEnv odin.integratedwebsystems.int MONO_IOMAP=all
  #
  # Additional environtment variables can be set for this server instance using
  # the MonoSetEnv directive.  MonoSetEnv takes a string of 'name=value' pairs
  # separated by semicolons.  For instance, to enable platform abstraction *and*
  # use Mono's old regular expression interpreter (which is slower, but has a
  # shorter setup time), uncomment the line below instead:
  # MonoSetEnv odin.integratedwebsystems.int MONO_IOMAP=all;MONO_OLD_RX=1

  MonoApplications odin.integratedwebsystems.int &quot;/:/srv/www/odin.integratedwebsystems.int&quot;
  &lt;Location &quot;/&quot;&gt;
    Allow from all
    Order allow,deny
    MonoSetServerAlias odin.integratedwebsystems.int
    SetHandler mono
    SetOutputFilter DEFLATE
    SetEnvIfNoCase Request_URI &quot;\.(?:gif|jpe?g|png)$&quot; no-gzip dont-vary
  &lt;/Location&gt;
  &lt;IfModule mod_deflate.c&gt;
    AddOutputFilterByType DEFLATE text/html text/plain text/xml text/javascript
  &lt;/IfModule&gt;
&lt;/VirtualHost&gt;</pre>
<p sizcache="0" sizset="63">Edit the information above (or use the <a href="http://go-mono.com/config-mod-mono/" target="_blank">configuration tool</a>) and replace my hostname with yours. Then save this file with the extension “.conf” and copy it to your /etc/apache2/conf.d directory using <a href="http://filezilla-project.org" target="_blank">FileZilla</a> SFTP connection as the root user.</p>
<p>Create a new directory at the location you specified in the DocumentRoot command. This is the root folder you’ll use to deploy your website.</p>
<pre class="brush: bash; gutter: false; toolbar: false;">cd /srv/www

mkdir my_web_hostname</pre>
<p>After setting all this up, you’ll need to restart your Apache server. To do that, just enter:</p>
<pre class="brush: bash; gutter: false; toolbar: false;">service apache2 restart</pre>
<p>You can restart any of your services this way. You might also reboot your server just to get a fresh run after installing and configuring all our software. Use the shutdown command to restart your system. Again, you can use <em>shutdown &#8211;help</em> or <em>man shutdown</em> to learn more about that command.</p>
<pre class="brush: bash; gutter: false; toolbar: false;">shutdown -r now</pre>
<h3 sizcache="0" sizset="65"><a name="RunningMVC">Running the Default Visual Studio MVC Website</a></h3>
<div class="gallery" sizcache="0" sizset="66">
<p sizcache="0" sizset="66"><a title="Running default MVC website on Apache/Mono 2.6.1" href="/resources/p441/post_install/13.jpg"><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="It works! " border="0" alt="It works! " align="right" src="http://www.integratedwebsystems.com/wp-content/uploads/2010/01/131.jpg" width="244" height="120" /></a> Open Visual Studio 2008 and build a brand new ASP.NET MVC Web Application.&#160; Publish it to a folder and copy all the published contents to your Linux server at <em>/srv/www/my_web_hostname</em> using FileZilla. Using a web browser, browse to your server and it should show that the new web application works right out the box (with the exception of Membership).</p>
</div>
<p sizcache="0" sizset="67">This is cool! It’s a great start knowing that routing, controllers and views all work. Feel free to play with it a bit more. Mono has some great tools like <a href="http://www.mono-project.com/MoMA" target="_blank">MoMa</a> that will tell you if your existing assemblies are compatible with Mono. You can also start toying around with Dblinq and alternative membership providers.</p>
<p>&#160;</p>
<p sizcache="0" sizset="68">There’s more to come. The <a href="http://www.integratedwebsystems.com/2010/02/how-to-setup-and-configure-mysql-membership-provider-6-2-2-porting-to-mono-part-2-of-3/">next post</a> will show you how to use the <a href="http://dev.mysql.com/downloads/connector/net/#downloads" target="_blank">MySql Membership</a> provider with both Windows and Mono.</p>
<p>&#160;</p>
<h3 sizcache="0" sizset="69"><a name="UsefulLinks">Useful Links</a></h3>
<ul sizcache="0" sizset="70">
<li sizcache="0" sizset="70">Mono Website – <a title="http://www.mono-project.com" href="http://www.mono-project.com">http://www.mono-project.com</a>&#160; </li>
<li sizcache="0" sizset="71">Mod_Mono Configuration Tool &#8211; <a href="http://go-mono.com/config-mod-mono/">http://go-mono.com/config-mod-mono/</a> </li>
<li sizcache="0" sizset="72">MoMa&#160; Mono Compatibility Checker &#8211; <a title="http://www.mono-project.com/MoMA" href="http://www.mono-project.com/MoMA">http://www.mono-project.com/MoMA</a> </li>
<li sizcache="0" sizset="73">OpenSuse 11.2 Download Page (scroll down) &#8211; <a href="http://software.opensuse.org/112/en">http://software.opensuse.org/112/en</a> </li>
<li sizcache="0" sizset="74">OpenSuse Documentation (loaded with great how to documents) &#8211; <a href="http://en.opensuse.org/Documentation">http://en.opensuse.org/Documentation</a> </li>
<li sizcache="0" sizset="75">Putty Download Page &#8211; <a href="http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html">http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html</a> </li>
<li sizcache="0" sizset="76">FileZilla Download Page &#8211; <a href="http://filezilla-project.org/download.php">http://filezilla-project.org/download.php</a> </li>
<li sizcache="0" sizset="77">MySql Connector .NET Download &#8211; <a title="http://dev.mysql.com/downloads/connector/net/#downloads" href="http://dev.mysql.com/downloads/connector/net/#downloads">http://dev.mysql.com/downloads/connector/net/#downloads</a> </li>
<li sizcache="0" sizset="78">MySql Workbench (MySql Administration and Development tools) &#8211; <a title="http://dev.mysql.com/downloads/workbench/5.2.html" href="http://dev.mysql.com/downloads/workbench/5.2.html">http://dev.mysql.com/downloads/workbench/5.2.html</a> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.integratedwebsystems.com/2010/01/installing-opensuse-11-2-with-mono-2-6-1-and-apache-using-text-mode-configuration-porting-to-mono-part-1-of-3/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Using jQuery Modal Dialog Confirmation with an ASP.NET Server Control</title>
		<link>http://www.integratedwebsystems.com/2009/12/using-jquery-modal-dialog-confirmation-with-an-asp-net-server-control/</link>
		<comments>http://www.integratedwebsystems.com/2009/12/using-jquery-modal-dialog-confirmation-with-an-asp-net-server-control/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 22:07:07 +0000</pubDate>
		<dc:creator>Nathan Bridgewater</dc:creator>
				<category><![CDATA[ASP.Net]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[dialog]]></category>
		<category><![CDATA[modal]]></category>
		<category><![CDATA[postback]]></category>

		<guid isPermaLink="false">http://www.integratedwebsystems.com/?p=413</guid>
		<description><![CDATA[So the other day, I wanted to build a confirmation dialog using jQuery with an existing Asp.Net web forms Button control.  I wanted this dialog to be modal; and upon confirmation, I wanted it to postback using the Button&#8217;s server-side click event.  After toying with the jQuery dialog, I realized that its dialog doesn’t suspend [...]]]></description>
			<content:encoded><![CDATA[<p>So the other day, I wanted to build a confirmation dialog using jQuery with an existing Asp.Net web forms Button control.  I wanted this dialog to be modal; and upon confirmation, I wanted it to postback using the Button&#8217;s server-side click event.  After toying with the jQuery dialog, I realized that its dialog doesn’t suspend the process while waiting for user input. So it also causes problems with confirmation since clicking the original button will always postback. So with a few tweaks, you can prevent the postback and emulate the click event pretty easily.</p>
<p><span id="more-413"></span></p>
<h3>Setup the Dialog and Postback Script</h3>
<p>In my application, we may click the button multiple times. So you’ll need to initialize it on load and actually open it later. As you can see below, we&#8217;re making our dialog modal and setting its autoOpen to false to prevent it from opening during initialization.  The dialog contains two buttons, and in this initialization, we can define their handler code. The confirmation button “Yes, I Understand and Agree” runs a chunk of code emulates the server control Click event on Button1. Notice I used the inline server-side script to gain access to the Page.ClientScript object, which contains a nice handful of helper functions for javascript.</p>
<pre class="brush: js; gutter: false; toolbar: false;">$().ready(function() {
    $("#ConfirmPanel").dialog(
    { autoOpen: false,
        modal: true,
        bgiframe: true,
        width: 400,
        height: 300,
        buttons: {
            'Youbetcha': function() {
                &lt;%=this.Page.ClientScript.GetPostBackEventReference(new PostBackOptions(this.Button1))%&gt;;
            },
            'No Thanks': function() {
                $(this).dialog('close');
            }
        }
    })
});</pre>
<h3>Open the Dialog with OnClientClick</h3>
<p>Next we’ll open the dialog each time our original server control button is clicked. You use the OnClientClick property to do this.</p>
<pre class="brush: js; gutter: false; toolbar: false;">$("#ConfirmPanel").dialog('open'); return false;</pre>
<p>We always return false here. Since the dialog doesn’t suspend the process, it will always finish and immediately postback. So by returning false, we’re preventing the button from posting back and allowing the jquery dialog to appear.</p>
<p>Here’s the full Asp.Net markup:</p>
<pre class="brush: xml; gutter: false; toolbar: false;">&lt;asp:Label ID="lblClicked" runat="server" /&gt;
&lt;asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Test" OnClientClick="javascript: $('#ConfirmPanel').dialog('open'); return false;"/&gt;
&lt;div id="ConfirmPanel" style="width: 400px; height: 200px;"&gt;
    &lt;h2&gt;Terms and Conditions&lt;/h2&gt;
    &lt;p&gt;By accepting, you agree to the following:
        &lt;ul&gt;
            &lt;li&gt;Are you really, really sure???? &lt;/li&gt;
        &lt;/ul&gt;
    &lt;/p&gt;
&lt;/div&gt;</pre>
<h3>The Result</h3>
<p><a href="http://www.integratedwebsystems.com/wp-content/uploads/2009/12/image.png"><img style="display: inline; border-width: 0px;" title="image" src="http://www.integratedwebsystems.com/wp-content/uploads/2009/12/image_thumb.png" border="0" alt="image" width="534" height="325" /></a></p>
<p>Clicking Youbetcha fires the Click event for our Button1.</p>
<p><a href="http://www.integratedwebsystems.com/wp-content/uploads/2009/12/image1.png"><img style="display: inline; border-width: 0px;" title="image" src="http://www.integratedwebsystems.com/wp-content/uploads/2009/12/image_thumb1.png" border="0" alt="image" width="126" height="36" /></a></p>
<p>Updated: 2/16/2010</p>
<p>To answer Matt’s question, I setup a simple web forms page with a data grid and a button within its rows. All the buttons are wired to one event handler and their command argument property is used to provide identifying data to the event handler.  Having said that, here’s the same solution using dynamic confirmation dialog. If you click OK, it will postback using the original button’s information which is displayed on postback.  Noticed I placed a <em>ClientScript.GetPostBackEventReference(uxGrid, string.Empty)</em> within the PageLoad event. Every time the page loads, postback or not, I want it to do this so it will render the __doPostBack client-side function. Without that, it will only work the first time. Subsequent clicks after the first postback will break.</p>
<p>So essentially the solution is to use __doPostBack(clientside_input_name_attribute, &#8221;).  Using the javascript function below we rebuild the buttons for the dialog each time and rewire it to the appropriate location.  So for this, if you didn&#8217;t want to use a grid, you could still use it the same way via OnClientClick with &#8220;this.name&#8221; and pass that to __doPostBack.</p>
<p>Here’s the markup source.  You can also <a href="/resources/p413/jquery_dynamic_confirmation.zip">download the full source code here</a>.</p>
<p>Thanks Matt.</p>
<pre class="brush: xml; gutter: false;">&lt;%@ Page Language="C#" AutoEventWireup="true"  %&gt;
&lt;%@ Import Namespace="System.Collections.Generic" %&gt;

&lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
&lt;html xmlns="http://www.w3.org/1999/xhtml"&gt;
&lt;head runat="server"&gt;
    &lt;title&gt;&lt;/title&gt;

    &lt;script type="text/C#" runat="server"&gt;
        protected void Page_Load(object sender, EventArgs e)
        {
            ClientScript.GetPostBackEventReference(uxGrid, string.Empty);

            if (!Page.IsPostBack)
            {
                List&lt;int&gt; test = new List&lt;int&gt;();
                test.Add(2);
                test.Add(3);
                test.Add(32);
                test.Add(223);
                test.Add(5);
                test.Add(8);
                uxGrid.DataSource = test;
                uxGrid.DataBind();

            }
        }
        protected void uxRowAction_Click(object sender, EventArgs e)
        {
            Button b = sender as Button;
            if (b != null)
            {
                uxTest.Text = "clicked " + b.CommandArgument;
            }
        }

    &lt;/script&gt;

    &lt;link href="smoothness/jquery-ui-1.7.2.custom.css" rel="stylesheet" type="text/css" /&gt;
    &lt;script src="jquery-1.3.2.min.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script src="jquery-ui-1.7.2.custom.min.js" type="text/javascript"&gt;&lt;/script&gt;
    &lt;script type="text/javascript"&gt;
        $().ready(function() {
            $('#dialogContent').dialog({
                autoOpen: false,
                modal: true,
                bgiframe: true,
                title: "MySql Membership Config Tool",
                width: 800,
                height: 600
            });
        });

        function rowAction(uniqueID) {

            $('#dialogContent').dialog('option', 'buttons',
                {
                    "OK": function() { __doPostBack(uniqueID, ''); $(this).dialog("close"); },
                    "Cancel": function() { $(this).dialog("close"); }
                });

                $('#dialogContent').dialog('open');

            return false;
        }

    &lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
    &lt;form id="form1" runat="server"&gt;
    &lt;div id="dialogContent"&gt;
        &lt;h3&gt;confirm&lt;/h3&gt;
        &lt;p&gt;Click ok to accept&lt;/p&gt;
    &lt;/div&gt;
    &lt;asp:Literal ID="uxTest" runat="server" /&gt;
    &lt;div&gt;
        &lt;asp:DataGrid ID="uxGrid" runat="server" AutoGenerateColumns="false"&gt;
            &lt;Columns&gt;
                &lt;asp:TemplateColumn&gt;
                    &lt;ItemTemplate&gt;
                        &lt;asp:Button ID="uxRowAction" runat="server" CommandArgument='&lt;%#Container.DataItem.ToString() %&gt;' Text="Row Action" OnClick="uxRowAction_Click" OnClientClick="javascript:return rowAction(this.name);" /&gt;
                    &lt;/ItemTemplate&gt;
                &lt;/asp:TemplateColumn&gt;
            &lt;/Columns&gt;
        &lt;/asp:DataGrid&gt;
    &lt;/div&gt;
    &lt;/form&gt;
&lt;/body&gt;
&lt;/html&gt;</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.integratedwebsystems.com/2009/12/using-jquery-modal-dialog-confirmation-with-an-asp-net-server-control/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Playing with SQLite, SubSonic3 and Repository Mode</title>
		<link>http://www.integratedwebsystems.com/2009/11/playing-with-sqlite-subsonic3-and-repository-mode/</link>
		<comments>http://www.integratedwebsystems.com/2009/11/playing-with-sqlite-subsonic3-and-repository-mode/#comments</comments>
		<pubDate>Sun, 22 Nov 2009 03:58:35 +0000</pubDate>
		<dc:creator>Nathan Bridgewater</dc:creator>
				<category><![CDATA[SubSonic]]></category>
		<category><![CDATA[Repository]]></category>
		<category><![CDATA[SQLite]]></category>
		<category><![CDATA[SubSonic3]]></category>

		<guid isPermaLink="false">http://www.integratedwebsystems.com/?p=402</guid>
		<description><![CDATA[Okay, lemme tell ya… I really, really like SubSonic right now.  I’m building a basic data integration application, and I wanted a simple way to store some basic tracking data locally. I didn’t want to build it into a Sql Server or create a super complicated data layer, so I decided to give SubSonic3’s Repository [...]]]></description>
			<content:encoded><![CDATA[<p>Okay, lemme tell ya… I really, really like SubSonic right now.  I’m building a basic data integration application, and I wanted a simple way to store some basic tracking data locally. I didn’t want to build it into a Sql Server or create a super complicated data layer, so I decided to give SubSonic3’s Repository Mode with SQLite a try. SQLite gives me a simple, zero-config, file-based database solution for the app, and SubSonic provides a nice, clean way to push and pull data with it.</p>
<p>First of all, if you haven’t seen Conery’s <a href="http://subsonicproject.com/docs/Simple_Repo_5_Minute_Demo" target="_blank">five minute demo video</a> on repository mode, you should. It’s very cool.  Once you watch it, you’ll get the basics of migration and understand the idea of building the object model first while using the database purely as a storage mechanism. In this case, I built my class, and I’m letting Migration handle all the schema generation for me. It will also create a new database file if one doesn’t already exist. That’s the idea right?</p>
<p><span id="more-402"></span></p>
<h3>Setup Your Configuration File</h3>
<p>For starters, don’t forget to <a href="http://sqlite.phxsoftware.com/" target="_blank">download and install the System.Data.SQLite library first</a>. I ran their Windows installer and it worked just fine. Then add a connection string to your config file. Be sure to set the ProviderName to  <strong>System.Data.SQLite</strong>. SubSonic uses the 2.0 provider model to determine the types required for the data connection.</p>
<pre class="brush: xml; gutter: false; toolbar: false;">&lt;connectionStrings&gt;
    &lt;add name="TrackerConnectionString" connectionString="Data Source=Tracker.db3;" providerName="System.Data.SQLite"/&gt;
&lt;/connectionStrings&gt;</pre>
<h3>Create Your Data Classes</h3>
<p>Create your storage classes. If you’re new to ORM/data layers, remember that each class definition represents a row in the database. In this case, I want a table called DSTFileTrackers with three columns: ID, Filename, and Imported. These are simple classes (other than the subsonic string length attribute). They don’t inherit from any other base class. A nice attribute not used here would be the [SubSonicIgnore] attribute. It will allow you to define other properties that you don’t want to store to the database like for example, read only properties.</p>
<pre class="brush: csharp; gutter: false; toolbar: false;">public class DSTFileTracker
{
    public long ID { get; set; }

    [SubSonic.SqlGeneration.Schema.SubSonicStringLength(100)]
    public string Filename { get; set; }

    public bool Imported { get; set; }
}</pre>
<h3>Write Your Implementation</h3>
<p>Lately, I’ve been playing a lot with ASP.NET MVC, I’ve been creating repository classes for my data objects.  They’re simple subject-matter classes that just handle business/data operations for a set of objects. In this case, I created one called TrackerRepository and implemented most of my SubSonic code there. Later on, I could build an interface for the repository and then set it up for unit testing or make it adaptable to switch to another data layer.</p>
<p>So here’s a sample calling code.</p>
<pre class="brush: csharp; gutter: false; toolbar: false;">var tracker = _Repo.DSTFiles.Where(o =&gt; o.Filename == file.name).FirstOrDefault();
if (tracker == null)
{
    tracker = new DSTFileTracker();
    tracker.Filename = file.name;
    _Repo.SaveDSTFileTracker(tracker);
}</pre>
<p>This save function below lives in my repository class. You can see how nice and clean these statements are. There’s a ton of potential here. Repository mode can do a lot of really cool stuff like deleting many records at once by expression or doing partial inserts and updates.</p>
<pre class="brush: csharp; gutter: false; toolbar: false;">public void SaveDSTFileTracker(DSTFileTracker data)
{
    if (_Repo.Exists&lt;DSTFileTracker&gt;(o =&gt; o.ID == data.ID))
        _Repo.Update&lt;DSTFileTracker&gt;(data);
    else
        _Repo.Add&lt;DSTFileTracker&gt;(data);
}</pre>
<p>So all in all it was pretty easy to do. You’ll notice I ran an existence check. The SimpleRepository doesn’t have this built into a save function like ActiveRecord, but it’s not a big deal to do manually.</p>
<h3>Catching SubSonic Gotchas</h3>
<p>This library is new and like all new libraries, you’ll run into a bug here and there. Hopefully as more and more people use it, the SubSonic community will become more aware of the bugs out there and can fix them.  I ran into a few myself just while doing this. These are mostly specific to the SQLite portion of SubSonic. They were all very easy to fix, and it’s very easy to submit your own patches. Checkout their <a href="http://subsonicproject.com/docs/Submit_Patch" target="_blank">GitHub demo video here</a>.  You can<a href="http://github.com/nathanb/SubSonic-3.0" target="_blank"> access my branch directly for the fixed code</a>. I&#8217;ve applied for a code pull, but it takes a few days and code review before they plug it into the main.</p>
<p>Here’s a few of the issues I ran into:</p>
<ul>
<li>SQLite’s auto-incrementing integer can only be 64bit [integer] rather than 32bit [int]. SubSonic will go and create the 64bit field during migration though; you just won’t see an error until you try to read it back. So if your ID property is an [int], change it to a [long].</li>
<li>The default code for [bool] creates a tinyint field in SQLite.  I had to tweak the Subsonic code by changing it to use a bit.  When reading the values, it breaks because tinyint == Byte and SubSonic sets values to data properties by casting them directly to their actual type in the reader.</li>
<li>When running an Update&lt;T&gt;, I get a NullReferenceException.  This is a bug in SubSonic and already <a href="http://github.com/subsonic/SubSonic-3.0/issues/#issue/123" target="_blank">has an issue posted</a>. I submitted a patch for this.  It’s a simple column name mismatch in the update script generator.</li>
<li>Just like in Linq to Sql when you do custom Lambda expressions with unrelated fields, it could cause problems. I was doing a funky Where(o=&gt;o.Equals(y)) which blew up my stuff because the LINQ predicate expression couldn’t figure out how to parse Equals() and CompareTo() to SQLite syntax.  So keep it simple. <img src='http://www.integratedwebsystems.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.integratedwebsystems.com/2009/11/playing-with-sqlite-subsonic3-and-repository-mode/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Announcing SiteManager &#8211; A Simple Open Source, MVC Based CMS</title>
		<link>http://www.integratedwebsystems.com/2009/10/announcing-sitemanager-a-simple-open-source-cms/</link>
		<comments>http://www.integratedwebsystems.com/2009/10/announcing-sitemanager-a-simple-open-source-cms/#comments</comments>
		<pubDate>Tue, 27 Oct 2009 06:00:36 +0000</pubDate>
		<dc:creator>Nathan Bridgewater</dc:creator>
				<category><![CDATA[ASP.Net]]></category>
		<category><![CDATA[CMS]]></category>
		<category><![CDATA[CodePlex]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[SiteManager]]></category>

		<guid isPermaLink="false">http://www.integratedwebsystems.com/?p=370</guid>
		<description><![CDATA[While playing and learning with MVC, I designed a simple little CMS (content management system). My goals for the project were to keep it simple, use MVC, and make it SEO optimized as possible. Well finally the first version of that application is published on CodePlex. Feel free to go check it out. Don’t forget [...]]]></description>
			<content:encoded><![CDATA[<p>While playing and learning with MVC, I designed a simple little CMS (content management system). My goals for the project were to keep it simple, use MVC, and make it SEO optimized as possible. Well finally the first version of that application is published on <a href="http://sitemanager.codeplex.com" target="_blank">CodePlex</a>. Feel free to go check it out. Don’t forget to peek at the <a href="http://sitemanager.codeplex.com/wikipage?title=setup%20instructions&amp;referringTitle=Documentation" target="_blank">setup documentation</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.integratedwebsystems.com/2009/10/announcing-sitemanager-a-simple-open-source-cms/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Simple Linq to Sql Enhancements with T4 Templating</title>
		<link>http://www.integratedwebsystems.com/2009/10/simple-linq-to-sql-enhancements-with-t4-templating/</link>
		<comments>http://www.integratedwebsystems.com/2009/10/simple-linq-to-sql-enhancements-with-t4-templating/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 16:15:15 +0000</pubDate>
		<dc:creator>Nathan Bridgewater</dc:creator>
				<category><![CDATA[T4]]></category>
		<category><![CDATA[Linq to Sql Classes]]></category>
		<category><![CDATA[Sql Server]]></category>
		<category><![CDATA[visual studio]]></category>

		<guid isPermaLink="false">http://www.integratedwebsystems.com/?p=373</guid>
		<description><![CDATA[I sometimes underestimate the power of the tools that come with visual studio. Usually this is because I&#8217;m ignorant of the fact they even exist until I see them used or read about them somewhere else. T4 text generation is no exception.  This is a very useful tool that&#8217;s built right into Visual Studio 2008 [...]]]></description>
			<content:encoded><![CDATA[<p>I sometimes underestimate the power of the tools that come with visual studio. Usually this is because I&#8217;m ignorant of the fact they even exist until I see them used or read about them somewhere else. <a href="http://www.olegsych.com/2007/12/text-template-transformation-toolkit/" target="_blank">T4 text generation</a> is no exception.  This is a very useful tool that&#8217;s built right into Visual Studio 2008 which I discovered while peeking at the new <a href="http://www.subsonicproject.com" target="_blank">SubSonic 3</a> code when it came out. (Thanks <a href="http://blog.wekeroad.com/" target="_blank">Conery</a>). <img src='http://www.integratedwebsystems.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>After spending a day drilling into T4 and learning how it works, I have to say that it was definitely time not wasted. I&#8217;ve since used it for tons of miscellaneous code generation projects including mostly data layer extensions. And with the help of the data provider specific templates in the SubSonic project, much of the schema extraction code has been provided for us through open source.</p>
<p>I&#8217;m a big fan of SubSonic, and I like to push it in all the shops I work with that aren&#8217;t already anchored down to another data framework. However, sometimes we still have to fall back to vanilla data layers like Linq to Sql (L2S), Entity Framework (EF), or straight up ADO.Net depending on the shop and its personalities. Having experience using SubSonic opens your eyes to some useful ways you can improve L2S and the others.</p>
<p><span id="more-373"></span>Like, for example, updating data&#8230; Have you been in a situation (like a web form postback or a web service call) where you&#8217;re instantiating a new entity instance whose data already exists in your database and you need to simply update it?  In L2S, this isn&#8217;t very straight forward. If you don&#8217;t want to mess with detaching and reattaching data entities, you can simple load an instance from the data context and update its fields with the new data; then commit the change back to the data context.</p>
<p>Well that&#8217;s great and all, but who&#8217;s going to type all the load functions? Not me, I hate typing. <img src='http://www.integratedwebsystems.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' />   So T4 comes to the rescue.  Here you&#8217;ll see a simple script that looks at a database and generates LoadFromExisting() functions for each table into a partial class that extends the original L2S class. Then anytime the schema changes, you simply run the T4 template and it re-executes your generation code.</p>
<h3>Using the Generated Code</h3>
<p>Here’s an example helper save function using Linq to Sql.  It simply checks for an existing record. If it exists, it updates its fields with the ones you passed in making it dirty to the data context, or it instructs the data context to insert it as a new one.</p>
<pre class="brush: csharp; gutter: false; toolbar: false;">public void SaveSection(Section section)
{
    var data = this.GetSectionByID(section.ID);

    if (data == null)
    {
        data = section;
        _DB.Sections.InsertOnSubmit(data);
    }
    else
        data.LoadFromExisting(section);

    _DB.SubmitChanges();
}</pre>
<p>Here is the corresponding LoadFromExisting() definition. You can see it’s very simple. All I really want to do here is update the values and flag the fields on the instance we pulled from the data context as dirty. The main thing to note here is that the class definition is partial.  It matches the namespace and name of the class generated in our DBML data context file.</p>
<pre class="brush: csharp; gutter: false; toolbar: false;">public partial class Section
{

    public Section LoadFromExisting(Model.Section data)
    {
        this.ID = data.ID;
        this.DefaultContentID = data.DefaultContentID;
        this.Description = data.Description;
        return this;
    }

}</pre>
<h3>Now for Actually Generating Code with T4</h3>
<p>To briefly explain T4, it’s basically a .net virtual machine hosted by visual studio. The code files appear a lot like classic ASP and MVC where you have rendered sections and functional sections. In T4, the token used to start and end a code section is: &lt;# #&gt;.  Like asp, you can include other files to re-use code files. Those files in this example have the ttinclude extension. Normal T4 scripts must end with the “.tt” extension.</p>
<p>Since we’re using what has already been setup for us by the SubSonic templates, we’re re-using their shared files: <em>Settings.ttinclude</em> and<em> SqlServer.ttinclude</em>. The <em>settings.ttinclude </em>file has all your basic shared settings like the global directives, includes, references, and supporting object model for the database structures. The <em>SqlServer.ttinclude </em>file contains the Sql Server specific schema extraction functions.</p>
<p><a href="http://www.integratedwebsystems.com/wp-content/uploads/2009/10/image.png"><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" src="http://www.integratedwebsystems.com/wp-content/uploads/2009/10/image_thumb.png" border="0" alt="image" width="185" height="103" align="right" /></a> Add both these files to your project, and then add a new text file with extension “.tt” to your project.  Copy the content from template.tt into your new tt file. The template content simply includes the shared files for you. Notice every time you save this file, it re-runs itself; so be very aware when you’re saving to avoid running the code accidentally.</p>
<p>Here’s the full script for the partial extension:</p>
<pre class="brush: csharp; gutter: false; toolbar: false;">&lt;#@ template language="C#v3.5" debug="True" hostspecific="True" #&gt;
&lt;#@ include file="SQLServer.ttinclude" #&gt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Linq.Expressions;
using System.Collections;
using System.ComponentModel;
using System.Data.Common;

namespace &lt;#=Namespace #&gt;
{
&lt;#

    var tables = LoadTables();

    foreach(Table tbl in tables)
    {
        if(!ExcludeTables.Contains(tbl.Name) &amp;&amp; !tbl.Name.StartsWith("aspnet"))
        {
#&gt;

    /// &lt;summary&gt;
    /// A class which represents the &lt;#=tbl.Name #&gt; table in the &lt;#=DatabaseName#&gt; Database.
    /// &lt;/summary&gt;
    public partial class &lt;#=tbl.ClassName#&gt;
    {

            public &lt;#=tbl.ClassName #&gt; LoadFromExisting(Model.&lt;#=tbl.ClassName #&gt; data)
            {
&lt;#
            foreach(Column col in tbl.Columns)
            {

                if (tbl.ClassName == col.CleanName)
                {
                    col.CleanName += "X";
                }
#&gt;
                this.&lt;#=col.CleanName #&gt; = data.&lt;#=col.CleanName #&gt;;
&lt;#
            }
#&gt;
                return this;
            }

        }
&lt;#
   }
  }
#&gt;
}</pre>
<p>So as  you can see, it’s very straight forward.  Here, we’re loading up all the tables, spinning through each one and then writing a function that spins its columns to generate assignment expressions.  (this.&lt;#=col.CleanName #&gt; = data.&lt;#=col.CleanName #&gt;; )  You’ll notice a few variable names being used like “Namespace” or ExcludeTables, etc.  With T4, you have to pretend that anything defined in a global scope is really just a member of this virtual class we created as our script. Those names were actually defined earlier in the Settings.ttinclude.  That is also where we’re setting our connection string name for the connection info. It uses the app.config in current project so you don’t have to save it statically in the file, which is another perk of these SubSonic templates.</p>
<p>For partial classes to work, you have to match the namespace and class name in your partial file. This is extremely useful, because I can generate code all day long with this file and then create yet another partial extension for the the more functional fine detail extensions.</p>
<h3>Enum Generator</h3>
<p>Here’s a nice little enum generator I wrote the other day. We typically use lookup tables in a lot of our projects whose names and values match what we have in our tables. This script uses a global list of table names in the <em>Settings.ttinclude </em>file and selects their data to generate enum code with values. The table structure is: (ID int, Name varchar(50), Description varchar(100)). You’ll need to create the table and fill it with your enumeration data first. Then run this script.</p>
<pre class="brush: csharp; gutter: false; toolbar: false;">&lt;#@ template language="C#v3.5" debug="True" hostspecific="True" #&gt;
&lt;#@ include file="SQLServer.ttinclude" #&gt;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;
using System.Linq.Expressions;
using System.Collections;
using System.ComponentModel;
using System.Data.Common;

namespace &lt;#=EnumNamespace #&gt;
{
&lt;#
            var list = GetEnums();
            foreach (KeyValuePair&lt;string, List&lt;EnumValue&gt;&gt; pair in list)
            {

            #&gt;

        /// &lt;summary&gt;
        /// An enumeration that represents the table &lt;#= pair.Key #&gt; in database: &lt;#= DatabaseName #&gt;
        /// &lt;/summary&gt;
        public enum &lt;#=pair.Key#&gt;
        {
&lt;#            int counter = 0;
            foreach(var value in pair.Value)
            {
                counter++;
                if (!string.IsNullOrEmpty(value.Description)) {#&gt;
            /// &lt;summary&gt;
            /// &lt;#= value.Description #&gt;
            /// &lt;/summary&gt;
&lt;# } #&gt;            &lt;#= value.Name #&gt; = &lt;#= value.Value #&gt;&lt;#if (counter &lt; pair.Value.Count) {#&gt;,&lt;#}#&gt;

&lt;#            }#&gt;
        }

&lt;#            }#&gt;
}</pre>
<p>In my case, I dropped these enumerations into a custom namespace since the names were shared with the entities representing the tables.  If you wanted to, you could easily drop these into a class as well.</p>
<h3>Download</h3>
<p><a href="/t4.zip" target="_blank">Here’s the zip file containing the four scripts</a>.</p>
<p><em>Disclaimer/Licensing: All code provided here was derived using some of the code in SubSonic templates; hence, this code is open source under the same license. New BSD, which I&#8217;ve included in the downloadable archive. </em></p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.integratedwebsystems.com/2009/10/simple-linq-to-sql-enhancements-with-t4-templating/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Simple Silverlight Uploader with Progress Bar using HttpRequest or WCF</title>
		<link>http://www.integratedwebsystems.com/2009/08/simple-silverlight-file-uploader-with-progress-bar-using-httprequest-or-wcf/</link>
		<comments>http://www.integratedwebsystems.com/2009/08/simple-silverlight-file-uploader-with-progress-bar-using-httprequest-or-wcf/#comments</comments>
		<pubDate>Mon, 17 Aug 2009 05:00:56 +0000</pubDate>
		<dc:creator>Nathan Bridgewater</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[file]]></category>
		<category><![CDATA[http handlers]]></category>
		<category><![CDATA[HttpRequest]]></category>
		<category><![CDATA[progress]]></category>
		<category><![CDATA[upload]]></category>
		<category><![CDATA[WCF]]></category>
		<category><![CDATA[WebRequest]]></category>

		<guid isPermaLink="false">http://www.integratedwebsystems.com/?p=287</guid>
		<description><![CDATA[I thought I’d write a little bit about a simple Silverlight file uploader I’ve been playing with. I see a lot of postings out there asking how to do a file uploader that can show upload progress using Silverlight. There are a few issues to overcome like: how to you actually measure progress, and while [...]]]></description>
			<content:encoded><![CDATA[<p>I thought I’d write a little bit about a simple Silverlight file uploader I’ve been playing with. I see a lot of postings out there asking how to do a file uploader that can show upload progress using Silverlight. There are a few issues to overcome like: how to you actually measure progress, and while using the HttpRequest, how do you update the UI from the worker thread?  So this project will hopefully answer some of your questions.</p>
<h3>Client-Side</h3>
<p><a href="http://www.integratedwebsystems.com/wp-content/uploads/2009/08/image4.png"><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" src="http://www.integratedwebsystems.com/wp-content/uploads/2009/08/image_thumb4.png" border="0" alt="image" width="407" height="149" /></a></p>
<p><a href="http://www.integratedwebsystems.com/wp-content/uploads/2009/08/image5.png"><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" src="http://www.integratedwebsystems.com/wp-content/uploads/2009/08/image_thumb5.png" border="0" alt="image" width="418" height="121" /></a></p>
<p>I should make a quick mention that this can be done using either WCF or a simple HTTP request. In my opinion, I think using HTTP request provides better performance and comes with less deployment and maintenance hassle; but likewise it leaves a few other loose ends like security and message integrity (if left unhandled). For this example, I’ll mostly only discuss the HTTP request method. My sample code includes a WCF implementation for reference. (Maybe some of you WCF gurus can tell me how that looks). <img src='http://www.integratedwebsystems.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> <span id="more-287"></span></p>
<p><a href="http://www.integratedwebsystems.com/wp-content/uploads/2009/08/image6.png"><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" src="http://www.integratedwebsystems.com/wp-content/uploads/2009/08/image_thumb6.png" border="0" alt="image" width="221" height="768" align="right" /></a></p>
<p>So first of all, progress&#8230;  How can we measure it?  Due to the max request length constraints in your web application, 4MB by default in Asp.Net, we’ll need to chunk the file by hand to accommodate large files. And in doing so, we can count each time a chunk was successfully sent to the server. So progress is simply counting the number of chunks sent divided by the total number of chunks that need to be sent.  In most cases, on smaller files, you probably won’t have too many chunks. Also, larger chunks seem to perform the better during upload. I tried several different chunk sizes, and it seemed around 100-500k gave me the best of both worlds with having a good progress measurement and not being too chatty where it slows down the upload too much.</p>
<p>All of the file handling and server communication is managed by a FileSender object, which is responsible for a single file upload. ListItem encapsulates the FileSender to make it easier to work with. It’s also initialized using the ListItem control’s Dispatcher property for UI thread callbacks later on during its Completed and ProgressChanged events.</p>
<p>During upload, every chunk that is sent to the server is hashed before sending it and after receiving it to make sure it was a valid transfer. The entire file is also hashed after all chunks are sent to validate the end result matches the original file. If any chunk fails to pass the hash test, it’s kicked back and re-sent. It will attempt to resend the same chunk up to four times (by default) before failing completely and killing the upload.  If the full file hash fails, it will not try to resend the data; it will only notify the UI that the upload has failed.</p>
<p>This diagram shows the basic structure of the client-side program flow.</p>
<p><a href="http://www.integratedwebsystems.com/wp-content/uploads/2009/08/image7.png"><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" src="http://www.integratedwebsystems.com/wp-content/uploads/2009/08/image_thumb7.png" border="0" alt="image" width="302" height="500" /></a></p>
<p>When the upload has finished, it will invoke the Completed event to let the caller know it’s done uploading. It will pass along the new filename or any errors that occurred during the upload. One of the challenges I mentioned earlier was related to invoking code in the UI after using the HttpRequest object. For this, we used the parent control’s Dispatcher property to invoke Completed and ProgressChanged. With the custom event delegates already defined, this worked out real well.</p>
<pre class="brush: csharp; toolbar: false;">void OnCompleted(SendStatus status, string newFilename, string message)
{
    if (_Completed != null)
    {
        Delegate d = new FileSenderCompletedEventHandler(_Completed);

        FileSenderCompletedEventArgs e = new FileSenderCompletedEventArgs();
        e.NewFilename = newFilename;
        e.Status = status;
        e.Message = message;

       this._UIDispatcher.BeginInvoke(d, null, e);//use the UI Dispatcher to invoke the event
    }
}</pre>
<h3>Server-side</h3>
<p>So now for the server side.  The destination folder is configured via an AppSettings variable called <em>StorageFolder</em>.  I set the default value to ~/Repo.  I built a generic handler to handle the request and pass data around using serialized XML of the request and response objects.</p>
<p>As requests come in, the handler peeks at the first element of the message, identifies its type, deserializes it, and hands it off to a processor function. The basic idea is to receive all the chunks identified by the same token and append them to a file. When the handler receives a FinishRequest for that token, the file is renamed and moved to a more permanent location, and the new file information is returned in a response.  For new files, an empty Guid is passed along with the first chunk. The handler starts a brand new file and responds with a new Guid token, which the caller will use in subsequent requests.</p>
<p><strong>NOTE:</strong> There are many enhancements that can be made to this code. Like for example dead uploads.  If one fails, the guid temp file may live out there forever unless you clean it up. So a good tool to build would be one to go through and wipe files that haven’t been touched for awhile. Another important enhancement is to include security. Since this is just a sample; it&#8217;s totally open ended. It would be a good idea to lock out anonymous requests by using authentication/authorization or another security mechanism.</p>
<p>Anyway, the serialization works pretty consistently between Silverlight and full .Net, so I copied my request and response objects to both projects (client and server) and use them to serialize and deserialize the messages. This is where a small chunk size can hurt the upload performance since there is a little bit of overhead data using XML.  A higher performance alternative to XML would be to use query string parameters for all the details and write the file data to the request stream. As I said before, it’s pretty open ended at this point.</p>
<h3>Where’s The Code!</h3>
<p>(NOTE: Default.aspx = WCF and HTTPUpload.aspx = HTTP method described above)</p>
<p><a href="http://www.integratedwebsystems.com/UploaderSL.zip">UploaderSL.zip</a> 1.2MB  (Updated 12/19/09 with minor pathing fix mentioned in comments)</p>
<p>To open this project, you’ll need the free <a href="http://www.microsoft.com/Downloads/details.aspx?familyid=9442B0F2-7465-417A-88F3-5E7B5409E9DD&amp;displaylang=en" target="_blank">Silverlight3 Tools</a>.</p>
<h3>In Summary</h3>
<p>My philosophy with samples like this is to leave them completely open ended for you all to modify and play with. I left quite a few things unfinished both on server side and client side; so I encourage you to change whatever you like. And let me know what you think! Just email me at nathan at integrated web systems dot com.</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.integratedwebsystems.com/2009/08/simple-silverlight-file-uploader-with-progress-bar-using-httprequest-or-wcf/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>Blank Silverlight Viewer After Deploying to Windows 2003 IIS6</title>
		<link>http://www.integratedwebsystems.com/2009/07/blank-silverlight-viewer-after-deploying-to-windows-2003-iis6/</link>
		<comments>http://www.integratedwebsystems.com/2009/07/blank-silverlight-viewer-after-deploying-to-windows-2003-iis6/#comments</comments>
		<pubDate>Wed, 15 Jul 2009 20:37:28 +0000</pubDate>
		<dc:creator>Nathan Bridgewater</dc:creator>
				<category><![CDATA[Silverlight]]></category>
		<category><![CDATA[iis6]]></category>
		<category><![CDATA[MIME]]></category>

		<guid isPermaLink="false">http://www.integratedwebsystems.com/?p=311</guid>
		<description><![CDATA[I found this article very helpful when troubleshooting an issue with my vanilla Windows 2003 server.  Earlier this week, I deployed an application that used Silverlight. The app worked fine in my development environment and my Windows 2008 test environment. After I deployed it to my 2003 IIS6 sandbox server, I noticed all my Silverlight [...]]]></description>
			<content:encoded><![CDATA[<p>I found this article very helpful when troubleshooting an issue with my vanilla Windows 2003 server.  Earlier this week, I deployed an application that used Silverlight. The app worked fine in my development environment and my Windows 2008 test environment. After I deployed it to my 2003 IIS6 sandbox server, I noticed all my Silverlight controls weren’t appearing in the browser. You could right click on them and get the Silverlight context menu, but the controls themselves were not loaded.</p>
<p>After googling around a bit, I found this article extremely useful. MIME Types… My server had nothing on it but IIS and Asp.Net. Naturally, Silverlight components were not setup in IIS. So this was a super easy fix by just adding the three new MIME types to the IIS Properties dialog. Check out the link for more details.</p>
<p><a href="http://learn.iis.net/page.aspx/262/silverlight/">http://learn.iis.net/page.aspx/262/silverlight/</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.integratedwebsystems.com/2009/07/blank-silverlight-viewer-after-deploying-to-windows-2003-iis6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
