<?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>Kristof Claes</title>
	<atom:link href="http://www.kristofclaes.be/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.kristofclaes.be</link>
	<description>ASP.NET web developer</description>
	<lastBuildDate>Fri, 18 Nov 2011 13:21:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Using a FileStreamResult with a MemoryStream in ASP.NET MVC 3</title>
		<link>http://www.kristofclaes.be/blog/2011/11/18/using-a-filestreamresult-with-a-memorystream-in-asp-net-mvc-3/</link>
		<comments>http://www.kristofclaes.be/blog/2011/11/18/using-a-filestreamresult-with-a-memorystream-in-asp-net-mvc-3/#comments</comments>
		<pubDate>Fri, 18 Nov 2011 13:21:28 +0000</pubDate>
		<dc:creator>Kristof</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[mvc]]></category>

		<guid isPermaLink="false">http://www.kristofclaes.be/?p=714</guid>
		<description><![CDATA[I was playing around with EO.Pdf 2011.2 for .NET from Essential Objects to see how easy it would be to use HTML and Razor to generate a report and convert it to a PDF file. EO.Pdf allows you to save &#8230; <a href="http://www.kristofclaes.be/blog/2011/11/18/using-a-filestreamresult-with-a-memorystream-in-asp-net-mvc-3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>I was playing around with <a href="http://www.essentialobjects.com/Products/EOPdf/Default.aspx" title="EO.Pdf 2011.2 for .NET">EO.Pdf 2011.2 for .NET</a> from Essential Objects to see how easy it would be to use HTML and Razor to generate a report and convert it to a PDF file.</p>
<p>EO.Pdf allows you to save a PDF document on disk or to a <code>Stream</code>. Since ASP.NET MVC 3 lets you return a <code>FileStreamResult</code> based on a <code>Stream</code>, I thought this would be the easiest solution and I came up with something like this:</p>
<pre class="brush:csharp">
[HttpGet]
public FileResult Download()
{
    var doc = new EO.Pdf.PdfDocument();
    EO.Pdf.HtmlToPdf.ConvertUrl("http://www.google.com/", doc);

    var ms = new MemoryStream();
    doc.Save(ms);

    return new FileStreamResult(ms, "application/pdf")
               {
                   FileDownloadName = "download.pdf"
               };
}
</pre>
<p>When trying it out, all I got was a corrupt PDF file. Something was wrong. But what? Apparently, you have to reset the <code>Position</code> of the <code>MemoryStream</code> before you pass it to the <code>FileStreamResult</code> constructor. Adding this solved the problem.</p>
<pre class="brush:csharp;highlight:10">
[HttpGet]
public FileResult Download()
{
    var doc = new EO.Pdf.PdfDocument();
    EO.Pdf.HtmlToPdf.ConvertUrl("http://www.google.com/", doc);

    var ms = new MemoryStream();
    doc.Save(ms);

    ms.Position = 0;

    return new FileStreamResult(ms, "application/pdf")
               {
                   FileDownloadName = "download.pdf"
               };
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.kristofclaes.be/blog/2011/11/18/using-a-filestreamresult-with-a-memorystream-in-asp-net-mvc-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An HtmlHelper to display if a field is required or not in ASP.NET MVC 3</title>
		<link>http://www.kristofclaes.be/blog/2011/08/26/an-htmlhelper-to-display-if-a-field-is-required-or-not-in-aspnet-mvc-3/</link>
		<comments>http://www.kristofclaes.be/blog/2011/08/26/an-htmlhelper-to-display-if-a-field-is-required-or-not-in-aspnet-mvc-3/#comments</comments>
		<pubDate>Fri, 26 Aug 2011 12:31:36 +0000</pubDate>
		<dc:creator>Kristof</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[asp.net mvc]]></category>
		<category><![CDATA[htmlhelper]]></category>

		<guid isPermaLink="false">http://www.kristofclaes.be/?p=691</guid>
		<description><![CDATA[A lot of the users I develop web applications for would like some sort of visual indication for required fields. A commonly used approach for this is putting an asterisk behind the input element. I could manually put an asterisk &#8230; <a href="http://www.kristofclaes.be/blog/2011/08/26/an-htmlhelper-to-display-if-a-field-is-required-or-not-in-aspnet-mvc-3/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A lot of the users I develop web applications for would like some sort of visual indication for required fields. A commonly used approach for this is putting an asterisk behind the input element.</p>
<p>I could manually put an asterisk behind every required field in my Views, but then I&#8217;d have to change my Views whenever the &#8220;requiredness&#8221; of a field changes. Since I&#8217;m using DataAnnotations on my ViewModels to indicate if a field is required or not, it would be nice if I could reuse that information in my Views.</p>
<p>Unfortunately, there is no standard HtmlHelper available to do this. Luckily, it&#8217;s rather easy to build one yourself:</p>
<pre class="brush:csharp">
using System;
using System.ComponentModel.DataAnnotations;
using System.Linq.Expressions;
using System.Reflection;
using System.Web.Mvc;

public static partial class ExtensionMethods
{
    public static MvcHtmlString RequiredSymbolFor&lt;TModel, TProperty>(
        this HtmlHelper&lt;TModel> htmlHelper,
        Expression&lt;Func&lt;TModel, TProperty>> expression,
        string symbol = "*",
        string cssClass = "editor-field-required")
    {
        ModelMetadata modelMetadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);

        if (modelMetadata.IsRequired)
        {
            var builder = new TagBuilder("span");
            builder.AddCssClass(cssClass);
            builder.InnerHtml = symbol;

            return new MvcHtmlString(builder.ToString(TagRenderMode.Normal));
        }

        return new MvcHtmlString("");
    }
}
</pre>
</p>
<h2>An example</h2>
<p>Let&#8217;s assume this is our ViewModel. Only the <code>Firstname</code> is required. The <code>Lastname</code> is optional.</p>
<pre class="brush:csharp">
public class Person
{
    [Required]
    public string Firstname { get; set; }
    public string Lastname { get; set; }
}
</pre>
</p>
<p>Then you can use it like this in your View:</p>
<pre class="brush:xhtml;highlight:[8,17]">
@using (Html.BeginForm())
{
    &lt;div class="editor-label">
        @Html.LabelFor(model => model.Firstname)
    &lt;/div>
    &lt;div class="editor-field">
        @Html.TextBoxFor(model => model.Firstname)
        @Html.RequiredSymbolFor(model => model.Firstname)
        @Html.ValidationMessageFor(model => model.Firstname)
    &lt;/div>

    &lt;div class="editor-label">
        @Html.LabelFor(model => model.Lastname)
    &lt;/div>
    &lt;div class="editor-field">
        @Html.TextBoxFor(model => model.Lastname)
        @Html.RequiredSymbolFor(model => model.Lastname)
        @Html.ValidationMessageFor(model => model.Lastname)
    &lt;/div>
}
</pre>
</p>
<p>This will render something like this:</p>
<p><img src="http://www.kristofclaes.be/wp-content/uploads/required-field-example.png" alt="RequiredSymbolFor HtmlHelper" title="RequiredSymbolFor HtmlHelper" width="328" height="125" class="size-full wp-image-703" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.kristofclaes.be/blog/2011/08/26/an-htmlhelper-to-display-if-a-field-is-required-or-not-in-aspnet-mvc-3/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hosting Nancy from a console application</title>
		<link>http://www.kristofclaes.be/blog/2011/08/23/hosting-nancy-from-a-console-application/</link>
		<comments>http://www.kristofclaes.be/blog/2011/08/23/hosting-nancy-from-a-console-application/#comments</comments>
		<pubDate>Tue, 23 Aug 2011 18:04:51 +0000</pubDate>
		<dc:creator>Kristof</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[nancy]]></category>

		<guid isPermaLink="false">http://www.kristofclaes.be/?p=678</guid>
		<description><![CDATA[A few day ago I needed to add some functionality to an old ASP.NET 1.1 web application in Visual Studio 2003. The version of the .NET framework and Visual Studio are irrelevant to the story, but I just wanted to &#8230; <a href="http://www.kristofclaes.be/blog/2011/08/23/hosting-nancy-from-a-console-application/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>A few day ago I needed to add some functionality to an old ASP.NET 1.1 web application in Visual Studio 2003. The version of the .NET framework and Visual Studio are irrelevant to the story, but I just wanted to share my pain. What <em>is</em> relevant, is that the web application needed to perform an HTTP POST request from code-behind to an external website.</p>
<p>After I had added the required code to the old web application, I wanted to test this somehow. Maybe there are easier ways to do this, but I decided I&#8217;d quickly create a new blank ASP.NET web site and let the old application send the HTTP POST request to the new dummy site.</p>
<p>That was easier said than done. I don&#8217;t know why, but IIS was in a foul mood and refused to cooperate with me that day. I guess he had been flirting with a hot looking Apache server the day before and had tried to get frisky with her but she responded with a <a href="http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html#sec10.4.12" target="_blank">411 error</a>. Anyhow, after wrestling with for over an hour and throwing ASP.NET MVC 3 sites and regular ASP.NET WebForms sites at it, IIS only gave me 404 and 403 errors. At this point I was so mad that I didn&#8217;t even want to try Cassini or IIS Express.</p>
<p>Instead, I did what should have done a lot earlier. I just created a new console app, used NuGet to add <code>Nancy.Hosting.Self</code>, added a small <code>NancyModule</code> class and I was finished. I literally had a working solution in less than 3 minutes. And that was the first time I had ever created a self hosted instance of Nancy. I&#8217;m starting to understand what they mean with the super-duper-happy-path.</p>
<h2>Talk is cheap, show me the codes!</h2>
<p>No problem! Just start Visual Studio and create a new Console Application. Open the Package Manager Console and enter <code>Install-Package Nancy.Hosting.Self</code>. This will add <code>Nancy</code> and <code>Nancy.Hosting.Self</code> to your application.</p>
<p>Adjust your <code>main</code> method so it looks like this:</p>
<pre class="brush:csharp">
static void Main(string[] args)
{
    var nancyHost = new Nancy.Hosting.Self.NancyHost(new Uri("http://localhost:1234"));
    nancyHost.Start();

    Console.ReadLine();
    nancyHost.Stop();
}
</pre>
<p>Now add a new class called <em>MainModule.cs</em> (you can actually name it whatever you want) and add this code:</p>
<pre class="brush:csharp">
public class MainModule : Nancy.NancyModule
{
    public MainModule()
    {
        Get["/"] = x =>
                       {
                           return "Hello world!";
                       };
    }
}
</pre>
<p>Now run your application, open a browser and surf to <code>http://localhost:1234</code>. Impressive, no?</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kristofclaes.be/blog/2011/08/23/hosting-nancy-from-a-console-application/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Building a photoblog with Nancy and Simple.Data Part 7: The archives</title>
		<link>http://www.kristofclaes.be/blog/2011/07/29/building-a-photoblog-with-nancy-and-simple-data-part-7-the-archives/</link>
		<comments>http://www.kristofclaes.be/blog/2011/07/29/building-a-photoblog-with-nancy-and-simple-data-part-7-the-archives/#comments</comments>
		<pubDate>Fri, 29 Jul 2011 21:01:05 +0000</pubDate>
		<dc:creator>Kristof</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[MyPhotoBlog]]></category>
		<category><![CDATA[nancy]]></category>
		<category><![CDATA[simple.data]]></category>

		<guid isPermaLink="false">http://www.kristofclaes.be/?p=637</guid>
		<description><![CDATA[This is the seventh part in my Building a photoblog with Nancy and Simple.Data series: Setting up the project Defining the routes Rendering some views Adding the database Updating Simple.Data Adding comments The archives Once again, it&#8217;s been a while &#8230; <a href="http://www.kristofclaes.be/blog/2011/07/29/building-a-photoblog-with-nancy-and-simple-data-part-7-the-archives/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is the seventh part in my <em>Building a photoblog with Nancy and Simple.Data</em> series:</p>
<ol>
<li><a href="http://www.kristofclaes.be/blog/2011/04/03/building-a-photoblog-with-nancy-and-simple-data-part-1-setting-up-the-project/">Setting up the project</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/04/04/building-a-photoblog-with-nancy-and-simple-data-part-2-defining-the-routes/">Defining the routes</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/04/09/building-a-photoblog-with-nancy-and-simple-data-part-3-rendering-some-views/">Rendering some views</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/04/16/building-a-photoblog-with-nancy-and-simple-data-part-4-adding-the-database/">Adding the database</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/05/02/building-a-photoblog-with-nancy-and-simple-data-part-5-updating-simple-data/">Updating Simple.Data</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/06/25/building-a-photoblog-with-nancy-and-simple-data-part-6-adding-comments/">Adding comments</a></li>
<li>The archives</li>
</ol>
<p>Once again, it&#8217;s been a while since the last post. The people behind Nancy and Simple.Data get a lot more work done than I can, so we&#8217;ll start this post by updating Nancy and Simple.Data again. Once that is done we tackle the archives pages. With that, we&#8217;ll complete the front-end!</p>
<h2>Updating Simple.Data</h2>
<p>Just like before, open the <em>Package Manager Console</em> and enter <code>Update-Package Simple.Data.SqlCompact40</code>. This will update all three Simple.Data packages to their latest version. At the moment that I&#8217;m writing this, that&#8217;s version 0.8.2.</p>
<h2>Updating Nancy</h2>
<p>Remember how we switched to the NuGet versions of the Nancy packages in the previous post? Well, because of that updating Nancy is as easy as updating Simple.Data. Just enter <code>Update-Package Nancy.Hosting.Aspnet</code> and <code>Update-Package Nancy.Viewengine.Razor</code>. This will update all of the Nancy packages to their latest version. At the moment that I&#8217;m writing this, that&#8217;s version 0.7.1.</p>
<p>There&#8217;s one little thing we&#8217;ll have to change in our code to ensure that everything works. Open the <code>PhotoBootstrapper</code> class and change the line about the <code>CookieBasedSessions</code> to this:</p>
<pre class="brush:csharp;highlight:[6,7,8]">
public class PhotoBootstrapper : DefaultNancyBootstrapper
{
	protected override void InitialiseInternal(TinyIoC.TinyIoCContainer container)
	{
		base.InitialiseInternal(container);
		Nancy.Session.CookieBasedSessions.Enable(
            this,
            Nancy.Cryptography.CryptographyConfiguration.Default);
	}
}
</pre>
<h2>Adding the archives pages</h2>
<p>As you might remember from <a href="http://www.kristofclaes.be/blog/2011/04/04/building-a-photoblog-with-nancy-and-simple-data-part-2-defining-the-routes/">the second post</a>, we have defined three routes for the archives. We&#8217;ll deal with them one by one.</p>
<h3>The general archives</h3>
<p>This page will show a list of all years and months in which photo&#8217;s have been published. For example:</p>
<ul>
<li>
        <a href="#">2011</a> (5)
<ul>
<li><a href="#">April</a> (2)</li>
<li><a href="#">March</a> (1)</li>
<li><a href="#">February</a> (1)</li>
<li><a href="#">January</a> (1)</li>
</ul>
</li>
<li>
        <a href="#">2010</a> (8)
<ul>
<li><a href="#">December</a> (5)</li>
<li><a href="#">November</a> (3)</li>
</ul>
</li>
</ul>
<p>Let&#8217;s first add a view model for the general archives. Add a class called <code>GeneralArchives</code> to the <em>Models</em> directly and add the following code:</p>
<pre class="brush:csharp">
public class GeneralArchives
{
	public List&lt;YearInfo> Years { get; set; }

	public GeneralArchives()
	{
		Years = new List&lt;YearInfo>();
	}
}

public class YearInfo
{
	public int Year { get; set; }
	public int NumberOfPhotos { get; set; }
	public List&lt;MonthInfo> Months { get; set; }

	public YearInfo()
	{
		Months = new List&lt;MonthInfo>();
	}
}

public class MonthInfo
{
	public int Month { get; set; }
	public string MonthName { get; set; }
	public int NumberOfPhotos { get; set; }
}
</pre>
<p>Now that we have a view model to pass to our view, we can add code to the <code>Get[""]</code> route in the <code>ArchivesModule</code>:</p>
<pre class="brush:csharp">
Get[""] = parameters =>
{
	List&lt;DateTime> allDates = DB.Photos
                                .Query()
                                .Select(DB.Photos.DatePublished)
                                .Where(DB.Photos.Published == true)
                                .OrderByDatePublishedDescending()
                                .ToScalarList&lt;DateTime>();

	var model = new GeneralArchives
					{
						Years = (from date in allDates
								 group date by date.Year
								 into yearGroup
								 select new YearInfo
											{
												Year = yearGroup.Key,
												NumberOfPhotos = yearGroup.Count(),
												Months = (from yearDate in yearGroup
														  group yearDate by yearDate.Month
														  into monthGroup
														  select new MonthInfo
																	 {
																		 Month = monthGroup.Key,
																		 MonthName = monthGroup.First().ToString("MMMM"),
																		 NumberOfPhotos = monthGroup.Count()
																	 }).ToList()
											}).ToList()
					};

	return View["general-archives", model];
};
</pre>
<p>That looks like a lot of code, but there are actually only three things happening. On lines 3 to 8, we ask Simple.Data for a list of all dates on which photo&#8217;s have been published. On lines 10 to 29 we use a LINQ operation to transform that list of dates into an instance of our <code>GeneralArchives</code> class filled with nested lists of years and months. Finally, on line 31, we return a view with the <code>GeneralArchives</code> instance as the model.</p>
<p>Speaking of the view, let&#8217;s add that one too! Add a file called <em>general-archives.cshtml</em> to the <em>Views</em> directory and add the following code:</p>
<pre class="brush:xml;highlight:[20,23,25,27]">
&lt;!doctype html>
&lt;html>
&lt;head>
    &lt;meta charset="utf-8" />
    &lt;meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

    &lt;title>Archives&lt;/title>
    &lt;link rel="Stylesheet" type="text/css" href="/Content/Css/reset.css" />
    &lt;link rel="Stylesheet" type="text/css" href="/Content/Css/photoblog.css" />

    &lt;script type="text/javascript" src="/Content/Scripts/modernizr-1.7.min.js">&lt;/script>
&lt;/head>
&lt;body>
    &lt;header>&lt;a href="/">MyPhotoBlog&lt;/a>&lt;/header>
    &lt;div id="main">
        &lt;h1>Archives&lt;/h1>
        &lt;div id="photo">
            &lt;div>
                &lt;ul class="years">
                @foreach (var yearInfo in Model.Years)
                {
                    &lt;li>
                        &lt;a href="/archives/@yearInfo.Year">@yearInfo.Year&lt;/a> (@yearInfo.NumberOfPhotos)
                        &lt;ul class="months">
                            @foreach (var monthInfo in yearInfo.Months)
                            {
                                &lt;li>&lt;a href="/archives/@yearInfo.Year/@monthInfo.Month">@monthInfo.MonthName&lt;/a> (@monthInfo.NumberOfPhotos)&lt;/li>
                            }
                        &lt;/ul>
                    &lt;/li>
                }
                &lt;/ul>
            &lt;/div>
        &lt;/div>
    &lt;/div>
    &lt;footer>MyPhotoBlog is built with &lt;a href="https://github.com/NancyFX/Nancy">Nancy&lt;/a> and &lt;a href="https://github.com/markrendle/Simple.Data">Simple.Data&lt;/a>.&lt;/footer>

    &lt;script type="text/javascript" src="/Content/Scripts/jquery-1.5.2.min.js">&lt;/script>
&lt;/body>
&lt;/html>
</pre>
<p>On line 20, we start to loop over the <code>YearInfo</code> items in the <code>Years</code> property of our view model. On line 23 we create a link to the yearly archives page for the current <code>YearInfo</code> item and on line 25 we start to loop over the <code>MonthInfo</code> items in the <code>Months</code> property of the current <code>YearInfo</code> item. Finally, on line 27, we also add a link to the monthly archives page for the current <code>MonthInfo</code> item.</p>
<h3>The yearly archives</h3>
<p>This page will show a list of all photo&#8217;s that have been published in the specified year. Building this page is very similar to the general archives. We start with the view model. Add a <code>YearlyArchives</code> class to the <em>Models</em> directory and add this code:</p>
<pre class="brush:csharp">
public class YearlyArchives
{
	public List&lt;Photo> Photos { get; set; }
	public int Year { get; set; }

	public YearlyArchives()
	{
		Photos = new List&lt;Photo>();
	}
}
</pre>
<p>Now we can modify the <code>Get[@"/(?&lt;year>19[0-9]{2}|2[0-9]{3})"]</code> route in the <code>ArchivesModule</code>:</p>
<pre class="brush:csharp">
Get[@"/(?&lt;year>19[0-9]{2}|2[0-9]{3})"] = parameters =>
{
	int year = Convert.ToInt32((string)parameters.year);
	DateTime start = new DateTime(year, 1, 1);
	DateTime end = start.AddYears(1);

	List&lt;Photo> photos = DB.Photos
                           .FindAllByDatePublishedAndPublished(start.ToString("yyyy-MM-dd").to(end.ToString("yyyy-MM-dd")), true)
                           .OrderByDatePublished()
                           .ToList&lt;Photo>();

	var model = new YearlyArchives
					{
						Photos = photos,
						Year = year
					};

	return View["yearly-archives", model];
};
</pre>
<p>As far as I know, it&#8217;s not possible to filter records based on a part of the date with Simple.Data. That&#8217;s why we just get all records between two dates. To do this, we can use the following Simple.Data notation: <code>FindByDate("2011-01-01".to("2011-12-31"))</code>, as you can see on line 8.</p>
<p>Once we have our list of photo&#8217;s, we can create an instance of our <code>YearlyArchives</code> view model class and pass it on to a view.</p>
<p>For the view, add a file called <em>yearly-archives.cshtml</em> to the <em>Views</em> directory with the following code:</p>
<pre class="brush:xml;highlight:[7,16,20,22]">
&lt;!doctype html>
&lt;html>
&lt;head>
    &lt;meta charset="utf-8" />
    &lt;meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

    &lt;title>Archives for @Model.Year&lt;/title>
    &lt;link rel="Stylesheet" type="text/css" href="/Content/Css/reset.css" />
    &lt;link rel="Stylesheet" type="text/css" href="/Content/Css/photoblog.css" />

    &lt;script type="text/javascript" src="/Content/Scripts/modernizr-1.7.min.js">&lt;/script>
&lt;/head>
&lt;body>
    &lt;header>&lt;a href="/">MyPhotoBlog&lt;/a>&lt;/header>
    &lt;div id="main">
        &lt;h1>Archives for @Model.Year&lt;/h1>
        &lt;div id="photo">
            &lt;div>
                &lt;ul class="photolist">
                @foreach (var photo in Model.Photos)
                {
                    &lt;li>&lt;a href="/photo/@photo.Slug">@photo.Name&lt;/a> &lt;span class="photodate">(@photo.DatePublished.ToLongDateString())&lt;/span>&lt;/li>
                }
                &lt;/ul>
            &lt;/div>
        &lt;/div>
        &lt;div id="backtoarchives">&lt;a href="/archives">Back to the archives&lt;/a>&lt;/div>
    &lt;/div>
    &lt;footer>MyPhotoBlog is built with &lt;a href="https://github.com/NancyFX/Nancy">Nancy&lt;/a> and &lt;a href="https://github.com/markrendle/Simple.Data">Simple.Data&lt;/a>.&lt;/footer>

    &lt;script type="text/javascript" src="/Content/Scripts/jquery-1.5.2.min.js">&lt;/script>
&lt;/body>
&lt;/html>
</pre>
<p>On lines 7 and 16 we show the correct title for the yearly archive, based on the chosen year. On lines 20 to 23, we loop through the list of photo&#8217;s and display a link to the detail page of the photo.</p>
<h3>The monthly archives</h3>
<p>The monthly archives are very similar to the yearly ones, so I&#8217;ll just show the relevant code.</p>
<p>The <code>MonthlyArchives</code> view model class in the <em>Models</em> directory:</p>
<pre class="brush:csharp">
public class MonthlyArchives
{
	public string Month { get; set; }
	public List&lt;Photo> Photos { get; set; }

	public MonthlyArchives()
	{
		Photos = new List&lt;Photo>();
	}
}
</pre>
<p>The <code>Get[@"/(?&lt;year>19[0-9]{2}|2[0-9]{3})/(?&lt;month>[1-9]|1[012])"]</code> route in the <code>ArchivesModule</code>:</p>
<pre class="brush:csharp">
Get[@"/(?&lt;year>19[0-9]{2}|2[0-9]{3})/(?&lt;month>[1-9]|1[012])"] = parameters =>
{
	int year = Convert.ToInt32((string)parameters.year);
	int month = Convert.ToInt32((string)parameters.month);
	DateTime start = new DateTime(year, month, 1);
	DateTime end = start.AddMonths(1);

	List&lt;Photo> photos = DB.Photos
                           .FindAllByDatePublishedAndPublished(start.ToString("yyyy-MM-dd").to(end.ToString("yyyy-MM-dd")), true)
                           .OrderByDatePublished()
                           .ToList&lt;Photo>();

	var model = new MonthlyArchives
	{
		Photos = photos,
		Month = start.ToString("MMMM yyyy")
	};

	return View["monthly-archives", model];
};
</pre>
<p>The <em>monthly-archives.cshtml</em> view in the <em>Views</em> directory:</p>
<pre class="brush:xml">
&lt;!doctype html>
&lt;html>
&lt;head>
    &lt;meta charset="utf-8" />
    &lt;meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

    &lt;title>Archives for @Model.Month&lt;/title>
    &lt;link rel="Stylesheet" type="text/css" href="/Content/Css/reset.css" />
    &lt;link rel="Stylesheet" type="text/css" href="/Content/Css/photoblog.css" />

    &lt;script type="text/javascript" src="/Content/Scripts/modernizr-1.7.min.js">&lt;/script>
&lt;/head>
&lt;body>
    &lt;header>&lt;a href="/">MyPhotoBlog&lt;/a>&lt;/header>
    &lt;div id="main">
        &lt;h1>Archives for @Model.Month&lt;/h1>
        &lt;div id="photo">
            &lt;div>
                &lt;ul class="photolist">
                @foreach (var photo in Model.Photos)
                {
                    &lt;li>&lt;a href="/photo/@photo.Slug">@photo.Name&lt;/a> &lt;span class="photodate">(@photo.DatePublished.ToLongDateString())&lt;/span>&lt;/li>
                }
                &lt;/ul>
            &lt;/div>
        &lt;/div>
        &lt;div id="backtoarchives">&lt;a href="/archives">Back to the archives&lt;/a>&lt;/div>
    &lt;/div>
    &lt;footer>MyPhotoBlog is built with &lt;a href="https://github.com/NancyFX/Nancy">Nancy&lt;/a> and &lt;a href="https://github.com/markrendle/Simple.Data">Simple.Data&lt;/a>.&lt;/footer>

    &lt;script type="text/javascript" src="/Content/Scripts/jquery-1.5.2.min.js">&lt;/script>
&lt;/body>
&lt;/html>
</pre>
<h2>That&#8217;s it!</h2>
<p>Whew. Three view models, three routes and three views. I&#8217;ve earned myself a <a href="http://www.absolutdrinks.com/en/drinks/fancy-nancy/" target="_blank">drink</a>!</p>
<p>As usual, the code is available on <a href="https://github.com/kristofclaes/MyPhotoBlog/tree/BlogPost7">GitHub</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kristofclaes.be/blog/2011/07/29/building-a-photoblog-with-nancy-and-simple-data-part-7-the-archives/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Building a photoblog with Nancy and Simple.Data Part 6: Adding comments</title>
		<link>http://www.kristofclaes.be/blog/2011/06/25/building-a-photoblog-with-nancy-and-simple-data-part-6-adding-comments/</link>
		<comments>http://www.kristofclaes.be/blog/2011/06/25/building-a-photoblog-with-nancy-and-simple-data-part-6-adding-comments/#comments</comments>
		<pubDate>Sat, 25 Jun 2011 13:52:40 +0000</pubDate>
		<dc:creator>Kristof</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[MyPhotoBlog]]></category>
		<category><![CDATA[nancy]]></category>
		<category><![CDATA[simple.data]]></category>

		<guid isPermaLink="false">http://www.kristofclaes.be/?p=595</guid>
		<description><![CDATA[This is the sixth part in my Building a photoblog with Nancy and Simple.Data series: Setting up the project Defining the routes Rendering some views Adding the database Updating Simple.Data Adding comments The archives It&#8217;s been a while since my &#8230; <a href="http://www.kristofclaes.be/blog/2011/06/25/building-a-photoblog-with-nancy-and-simple-data-part-6-adding-comments/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is the sixth part in my <em>Building a photoblog with Nancy and Simple.Data</em> series:</p>
<ol>
<li><a href="http://www.kristofclaes.be/blog/2011/04/03/building-a-photoblog-with-nancy-and-simple-data-part-1-setting-up-the-project/">Setting up the project</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/04/04/building-a-photoblog-with-nancy-and-simple-data-part-2-defining-the-routes/">Defining the routes</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/04/09/building-a-photoblog-with-nancy-and-simple-data-part-3-rendering-some-views/">Rendering some views</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/04/16/building-a-photoblog-with-nancy-and-simple-data-part-4-adding-the-database/">Adding the database</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/05/02/building-a-photoblog-with-nancy-and-simple-data-part-5-updating-simple-data/">Updating Simple.Data</a></li>
<li>Adding comments</li>
<li><a href="http://www.kristofclaes.be/blog/2011/07/29/building-a-photoblog-with-nancy-and-simple-data-part-7-the-archives/">The archives</a></li>
</ol>
<p>It&#8217;s been a while since my last post and a lot of things have changed since then. In this post we&#8217;ll update Simple.Data to version 0.6.7 and Nancy to 0.6. Then we&#8217;ll see what we need to do to finish the page that displays a photo. Let&#8217;s get cracking!</p>
<h2>Updating Simple.Data</h2>
<p>This is probably the easiest part. Just like before, open the <em>Package Manager Console</em> and enter <code>Update-Package Simple.Data.SqlCompact40</code>. This will update all three Simple.Data packages to their latest version. At the moment that I&#8217;m writing this, that&#8217;s version 0.6.7.</p>
<h2>Updating Nancy</h2>
<p>Remember how we added the different Nancy assemblies manually because not all parts were available on Nuget? Well, that&#8217;s changed and the release of Nancy 0.6 seems like a good occasion to remove the manually added assemblies and use Nuget to get the latest version of Nancy!</p>
<p>In the <em>Solution Explorer</em>, right click <em>Nancy</em> and choose <em>Remove</em>. Repeat this for <em>Nancy.Hosting.Aspnet</em> and <em>Nancy.ViewEngines.Razor</em>. Delete the three dll-files from the <em>Lib</em> directory in the solution directory as well.</p>
<p>Open the <em>Package Manager Console</em> and enter <code>Install-Package Nancy</code>. When Nancy has been added, use <code> Install-Package Nancy.ViewEngines.Razor</code> and <code>Install-Package Nancy.Hosting.Aspnet</code> to add the rest.</p>
<p>When you rebuild your project, everything should be working just fine. That wasn&#8217;t too hard, was it?</p>
<h2>Update the PhotoModule</h2>
<p>Let&#8217;s update the <code>Get["/{slug}"]</code> route so that it displays the requested photo and provides links to the next and previous photo. Because of the amazing work of Mark Rendle on Simple.Data, this is extremely easy:</p>
<pre class="brush:csharp">
Get["/{slug}"] = parameters =>
{
	string slug = (string)parameters.slug;
	Models.Photo photo = DB.Photos.FindBySlug(slug);

	if (photo == null)
	{
		// No photo found with this slug, we'll just redirect to the homepage
		return Response.AsRedirect("/");
	}
	else
	{
		var model = new Models.PhotoDetail();
		model.Photo = photo;

		model.PreviousSlug = DB.Photos
		                       .Query()
							   .Select(DB.Photos.Slug)
							   .Where(DB.Photos.Published == true &#038;&#038; DB.Photos.DatePublished &lt; photo.DatePublished.Value)
							   .OrderByDatePublishedDescending()
							   .Take(1)
							   .ToScalarOrDefault&lt;string>();

		model.NextSlug = DB.Photos
		                   .Query()
						   .Select(DB.Photos.Slug)
						   .Where(DB.Photos.Published == true &#038;&#038; DB.Photos.DatePublished > photo.DatePublished.Value)
						   .OrderByDatePublished()
						   .Take(1)
						   .ToScalarOrDefault&lt;string>();

		return View["photodetail", model];
	}
};
</pre>
<p>How neat is that? First we select the requested photo, based on the slug. Next we select the slug of previous and next photo&#8217;s, put them in the model and let Nancy pass it on to the <em>photodetail.cshtml</em> view. That&#8217;s the same view we use for the homepage.</p>
<h2>Adding comments</h2>
<p>Now that we can browse the photo&#8217;s, let&#8217;s see how we can give visitors the possibility to add comments. </p>
<h3>The Comment class</h3>
<p>We already have a table in the database to store the comments. We also need a class that corresponds to that table. Add a new class <code>Comment</code> to the <em>Models</em> directory and give it the following code:</p>
<pre class="brush:csharp">
public class Comment
{
	public int Id { get; set; }
	public string Name { get; set; }
	public string Email { get; set; }
	public string Website { get; set; }
	public string Message { get; set; }
	public int PhotoId { get; set; }
	public bool Approved { get; set; }

	public bool IsValid()
	{
		if (String.IsNullOrWhiteSpace(Name)) return false;
		if (String.IsNullOrWhiteSpace(Email))
		{
			return false;
		}
		else
		{
			bool validAddress = true;
			try
			{
				var address = new System.Net.Mail.MailAddress(Email).Address;
			}
			catch (FormatException)
			{
				validAddress = false;
			}

			if (!validAddress) return false;
		}

		if (String.IsNullOrWhiteSpace(Message))
		{
			return false;
		}
		else
		{
			Uri uri;
			if (!System.Uri.TryCreate(Website, UriKind.Absolute, out uri)) return false;
		}

		return true;
	}
}
</pre>
<p>As you can see we have a property for each column in the database table. They have the same name so Simple.Data can map them correctly. I have also added a method called <code>IsValid()</code> to the <code>Comment</code> class. In a larger application you probably want to use a separate validator class, but in this case we&#8217;ll just stick with this approach.</p>
<h3>Updating our PhotoDetail view model</h3>
<p>Since the comments of a photo need to be passed to the view, we need to add some code to the <code>PhotoDetail</code> class:</p>
<pre class="brush:csharp">
public class PhotoDetail
{
	public Photo Photo { get; set; }

	public string NextSlug { get; set; }
	public bool HasNext { get { return !String.IsNullOrEmpty(this.NextSlug); } }

	public string PreviousSlug { get; set; }
	public bool HasPrevious { get { return !String.IsNullOrEmpty(this.PreviousSlug); } }

	public string ErrorMessage { get; set; }
	public bool HasErrorMessage { get { return !String.IsNullOrEmpty(this.ErrorMessage); } }

	public List&lt;Comment> Comments { get; set; }

	public PhotoDetail()
	{
		Comments = new List&lt;Comment>();
	}
}
</pre>
<p>Next to the comments (line 14), I have also added an <code>ErrorMessage</code> property (lines 11 and 12). This will enable us to pass an error message to the view when a user enters incorrect information while adding a comment.</p>
<h3>Updating the view</h3>
<p>To display the list of comments and a form to add a new comment, I have added this code to the <em>photodetail.cshtml</em> file (right below the <code>&lt;/nav></code>-tag):</p>
<pre class="brush:xml;highlight:[24,33,39,45,50]">
&lt;div id="comments">
	&lt;h2>Comments&lt;/h2>
	&lt;div id="commentsform">
		&lt;a name="comments">&lt;/a>

		@foreach (var comment in @Model.Comments)
		{
			&lt;div class="comment">
				&lt;div class="commenter">
					@if (String.IsNullOrEmpty(comment.Website))
					{
						@comment.Name &lt;text> wrote:&lt;/text>
					}
					else
					{
						&lt;a href="@comment.Website">@comment.Name&lt;/a> &lt;text> wrote:&lt;/text>
					}
				&lt;/div>
				&lt;div class="message">@comment.Message&lt;/div>
			&lt;/div>
		}

		&lt;h3>Add a comment&lt;/h3>
		&lt;form action="/photo/@Model.Photo.Slug/addcomment" method="POST">
			@if (@Model.HasErrorMessage)
			{
				&lt;div id="errormessage">
					@Model.ErrorMessage
				&lt;/div>
			}
			&lt;div class="formitem">
				&lt;label for="Name">Your name&lt;/label>
				&lt;input type="text" id="Name" name="Name" />
				&lt;span class="mandatory">*&lt;/span>
			&lt;/div>

			&lt;div class="formitem">
				&lt;label for="Email">Your email address&lt;/label>
				&lt;input type="text" id="Email" name="Email" />
				&lt;span class="mandatory">*&lt;/span>
			&lt;/div>

			&lt;div class="formitem">
				&lt;label for="Website">Your website&lt;/label>
				&lt;input type="text" id="Website" name="Website" />
			&lt;/div>

			&lt;div class="formitem">
				&lt;label for="Message">Your message&lt;/label>
				&lt;textarea id="Message" name="Message">&lt;/textarea>
				&lt;span class="mandatory">*&lt;/span>
			&lt;/div>

			&lt;div class="formitem">
				&lt;input type="submit" id="commentsubmit" name="commentsubmit" value="Submit" />
			&lt;/div>
		&lt;/form>
	&lt;/div>
&lt;/div>
</pre>
<p>Notice how the four input elements have the same name as the properties of our <code>Comment</code> class. We&#8217;ll see why this is important in a moment. As you can see on line 24, the form will post to <code>/photo/{slug}/addcomment</code>. This route is defined in our <em>PhotoModule</em>. Let&#8217;s update it!</p>
<h3>Adding a comment</h3>
<p>Here&#8217;s the new code for the <code>Post["/{slug}/addcomment"]</code> route:</p>
<pre class="brush:csharp">
Post["/{slug}/addcomment"] = parameters =>
{
	string photoSlug = (string)parameters.slug;

	int? photoId = DB.Photos
	                 .Query()
					 .Select(DB.Photos.Id)
					 .Where(DB.Photos.Slug == photoSlug)
					 .ToScalarOrDefault&lt;int?>();

	if (photoId.HasValue)
	{
		Models.Comment comment = this.Bind&lt;Models.Comment>("Id", "PhotoId", "Approved");
		comment.PhotoId = photoId.Value;
		comment.Approved = true;

		if (comment.IsValid())
		{
			DB.Comments.Insert(comment);
		}
		else
		{
			Session["commenterror"] = true;
		}

		return Response.AsRedirect(String.Format("/photo/{0}#comments", photoSlug));
	}
	else
	{
		// No photo found with this slug, we'll just redirect to the homepage
		return Response.AsRedirect("/");
	}
};
</pre>
<p>On line 5 we&#8217;re asking Simple.Data for the Id of the photo the comment should be added to. If no photo is found, we just redirect to the homepage (line 31).</p>
<p>On line 13 we are taking advantage of the ModelBinding capabilities of Nancy. It will try to map the incoming request parameters to the properties of the provided class, <code>Comment</code> in this case. That&#8217;s why we gave the input fields in our view the same name as the corresponding properties in the <code>Comment</code> class. The three parameters (<code>Id</code>, <code>PhotoId</code> and <code>Approved</code>) we pass to the <code>Bind&lt;T>()</code> method are blacklisted properties. This means that the Nancy ModelBinder will ignore these properties. We do this to prevent someone from manually posting to our route and proving for example an Id-parameter.</p>
<p>If you&#8217;re can&#8217;t get this to compile because the <code>Bind&lt;T>()</code> method can&#8217;t be found, you&#8217;ll probably need to add a <code>using Nancy.ModelBinding;</code> since the <code>Bind&lt;T>()</code> method is actually an extension method for the <code>NancyModule</code> class and it is located in the <code>Nancy.ModelBinding</code> namespace.</p>
<p>Next we check if the entered comment is valid or not. If it is, we ask Simple.Data to add it to the database for us. As you can see this is also very easy to do. You can just pass an object and Simple.Data will figure out what to do with it. If the comment isn&#8217;t valid, we set a session variable called <code>commenterror</code> to <code>true</code>. Finally we redirect to the page of the photo to which the comment was or should have been added.</p>
<h3>Enabling Session</h3>
<p>On line 23 of the <code>Post["/{slug}/addcomment"]</code> route, we set a session variable. If you run the application at this time, that would not work because the session state in Nancy is disabled by default. To enable it, we need to add a bootstrapper to our application. This, like most of the things in Nancy, is easier than it sounds.</p>
<p>Just add a class called <code>PhotoBootstrapper</code> to the root of our project, let it inherit from <code>DefaultNancyBootstrapper</code> and add an override for the <code>InitialiseInternal</code> method:</p>
<pre class="brush:csharp">
public class PhotoBootstrapper : DefaultNancyBootstrapper
{
	protected override void InitialiseInternal(TinyIoC.TinyIoCContainer container)
	{
		base.InitialiseInternal(container);
		Nancy.Session.CookieBasedSessions.Enable(this, "ThePassphrase", "SomeSeasoning", "HeresMyHMAC");
	}
}
</pre>
<p>That&#8217;s it. Nancy is smart enough to detect your bootstrapper and use it instead of it&#8217;s own default bootstrapper. The four parameters we need to pass to <code>CookieBasedSessions.Enable()</code> are an <code>IApplicationPipelines</code>, a passphrase, a salt and and and <a href="http://en.wikipedia.org/wiki/HMAC" target="_blank">hmac</a>Passphrase respectively. You should pick something more random than the values I have provided of course.</p>
<h3>Displaying the comments</h3>
<p>Now that users are able to add comments, we need to add some code so the comments actually get displayed. This needs to be done in two places: the <code>Get["/{slug}"]</code> route in the <code>PhotoModule</code> class and the <code>Get["/"]</code> route in the <code>RootModule</code> class.</p>
<p>Here is the code for the <code>Get["/{slug}"]</code> route:</p>
<pre class="brush:csharp;highlight:[32,33,34,35,36,37,38,39,40,41,42,43]">
Get["/{slug}"] = parameters =>
{
	string slug = (string)parameters.slug;
	Models.Photo photo = DB.Photos.FindBySlug(slug);

	if (photo == null)
	{
		// No photo found with this slug, we'll just redirect to the homepage
		return Response.AsRedirect("/");
	}
	else
	{
		var model = new Models.PhotoDetail();
		model.Photo = photo;

		model.PreviousSlug = DB.Photos
		                       .Query()
							   .Select(DB.Photos.Slug)
							   .Where(DB.Photos.Published == true &#038;&#038; DB.Photos.DatePublished &lt; photo.DatePublished.Value)
							   .OrderByDatePublishedDescending()
							   .Take(1)
							   .ToScalarOrDefault&lt;string>();

		model.NextSlug = DB.Photos
		                   .Query()
						   .Select(DB.Photos.Slug)
						   .Where(DB.Photos.Published == true &#038;&#038; DB.Photos.DatePublished > photo.DatePublished.Value)
						   .OrderByDatePublished()
						   .Take(1)
						   .ToScalarOrDefault&lt;string>();

		IEnumerable&lt;Models.Comment> comments = DB.Comments
		                                            .FindAll(DB.Comments.PhotoId == model.Photo.Id &#038;&#038; DB.Comments.Approved == true)
													.Cast&lt;Models.Comment>();

		if (comments != null) model.Comments = comments.ToList();

		bool commenterror = false;
		if (Boolean.TryParse(Convert.ToString(Session["commenterror"]), out commenterror))
		{
			model.ErrorMessage = "Please fill out all required fields and make sure the email address you enter is valid.";
			Session.Delete("commenterror");
		}

		return View["photodetail", model];
	}
};
</pre>
<p>We ask Simple.Data for a list of comments for the requested photo (lines 32-34) and add it to our view model (line 36). Next we check if the session variable <code>commenterror</code> is set to true or not. If it is, we add an error message to our view model and delete the session variable.</p>
<p>Since the comments also need to be displayed on the homepage, we need to add some code to the <code>Get["/"]</code> route as well:</p>
<pre class="brush:csharp;highlight:[15,16,17,18,19]">
Get["/"] = parameters =>
{
	var photos = DB.Photos.FindAllByPublished(true).OrderByDatePublishedDescending().Take(2);
	List&lt;Models.Photo> photoList = photos.ToList&lt;Models.Photo>();

	if (photoList.Count > 0)
	{
		var model = new Models.PhotoDetail();
		model.Photo = photoList[0];
		model.NextSlug = String.Empty;

		if (photoList.Count > 1) model.PreviousSlug = photoList[1].Slug;
		else model.PreviousSlug = String.Empty;

		IEnumerable&lt;Models.Comment> comments = DB.Comments
		                                         .FindAll(DB.Comments.PhotoId == model.Photo.Id &#038;&#038; DB.Comments.Approved == true)
												 .Cast&lt;Models.Comment>();

		if (comments != null) model.Comments = comments.ToList();

		return View["photodetail", model];
	}
	else
	{
		return View["nophoto"];
	}
};
</pre>
<h2>That&#8217;s it!</h2>
<p>That&#8217;s it for today. Quite a lot of code, but nothing to complicated. As you have seen, Nancy and Simple.Data really make things easy for you!</p>
<p>As usual, the complete code is available on <a href="https://github.com/kristofclaes/MyPhotoBlog/tree/BlogPost6">GitHub</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kristofclaes.be/blog/2011/06/25/building-a-photoblog-with-nancy-and-simple-data-part-6-adding-comments/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Building a photoblog with Nancy and Simple.Data Part 5: Updating Simple.Data</title>
		<link>http://www.kristofclaes.be/blog/2011/05/02/building-a-photoblog-with-nancy-and-simple-data-part-5-updating-simple-data/</link>
		<comments>http://www.kristofclaes.be/blog/2011/05/02/building-a-photoblog-with-nancy-and-simple-data-part-5-updating-simple-data/#comments</comments>
		<pubDate>Mon, 02 May 2011 16:14:05 +0000</pubDate>
		<dc:creator>Kristof</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[MyPhotoBlog]]></category>
		<category><![CDATA[nancy]]></category>
		<category><![CDATA[simple.data]]></category>

		<guid isPermaLink="false">http://www.kristofclaes.be/?p=579</guid>
		<description><![CDATA[This is the fifth part in my Building a photoblog with Nancy and Simple.Data series: Setting up the project Defining the routes Rendering some views Adding the database Updating Simple.Data Adding comments The archives In the previous post we added &#8230; <a href="http://www.kristofclaes.be/blog/2011/05/02/building-a-photoblog-with-nancy-and-simple-data-part-5-updating-simple-data/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is the fifth part in my <em>Building a photoblog with Nancy and Simple.Data</em> series:</p>
<ol>
<li><a href="http://www.kristofclaes.be/blog/2011/04/03/building-a-photoblog-with-nancy-and-simple-data-part-1-setting-up-the-project/">Setting up the project</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/04/04/building-a-photoblog-with-nancy-and-simple-data-part-2-defining-the-routes/">Defining the routes</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/04/09/building-a-photoblog-with-nancy-and-simple-data-part-3-rendering-some-views/">Rendering some views</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/04/16/building-a-photoblog-with-nancy-and-simple-data-part-4-adding-the-database/">Adding the database</a></li>
<li>Updating Simple.Data</li>
<li><a href="http://www.kristofclaes.be/blog/2011/06/25/building-a-photoblog-with-nancy-and-simple-data-part-5-adding-comments/">Adding comments</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/07/29/building-a-photoblog-with-nancy-and-simple-data-part-7-the-archives/">The archives</a></li>
</ol>
<p>In the previous post we added a SQL Server Compact 4.0 database to our project and we used Simple.Data to fetch the latest photo to display it on the homepage.</p>
<p>In the previous we were using Simple.Data 0.5.6.0. Since then quite a few things have changed in Simple.Data 0.6.1.0. It is now possible to do paging and sorting at the database level. Let&#8217;s see how this impacts our code from the previous post.</p>
<h2>Updating Simple.Data</h2>
<p>Open the <em>Package Manager Console</em> and enter this command: <code>Update-Package Simple.Data.SqlCompact40</code>. This will fetch the latest version of <code>Simple.Data.SqlCompact40</code> (and its dependencies <code>Simple.Data.Core</code> and <code>Simple.Data.Ado</code>) from the official NuGet feed and add them to our project. The old versions get removed. That was easy!</p>
<h2>Updating our RootModule</h2>
<p>Remember how we had to select all published photo&#8217;s and manually sort them?</p>
<pre class="brush:csharp">
// Get all photo's that are published
var photos = DB.Photos.FindAllByPublished(true);
List&lt;Models.Photo> photoList = photos.ToList&lt;Models.Photo>();

// Order them so the newest come first
photoList = photoList.OrderByDescending(p => p.DatePublished).ToList();
</pre>
<p>That&#8217;s not good for two reasons:</p>
<ol>
<li>We are requesting an unbound result set. If I happened to be a very active photographer (which I&#8217;m not <img src='http://www.kristofclaes.be/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> ), that could mean that we are asking the database to return a million records at once. That&#8217;s bad.</li>
<li>We have to sort everything in our code. In combination with the unbound result set, this could become very imperformant.</li>
</ol>
<p>Let&#8217;s see how we can solve this with the new features in Simple.Data.</p>
<p>To sort the records directly in the database, we just append <code>.OrderByXXX()</code> or <code>.OrderByXXXDescending()</code> where <code>XXX</code> is the name of column belonging to the table we are querying:</p>
<pre class="brush:csharp">
var photos = DB.Photos.FindAllByPublished(true).OrderByDatePublishedDescending();
</pre>
</p>
<p>We now get list of photo&#8217;s where <code>Published</code> is set to <code>true</code> and is ordered by the <code>DatePublished</code> field with the highest date first. So now we have an ordered result set, but it&#8217;s still an unbound result set. Fixing that is also easy. Since we only need the first two photo&#8217;s, we need a <code>top 2</code>. This is solved in a very LINQish way in Simple.Data. We can simply append <code>.Take(2)</code>:</p>
<pre class="brush:csharp">
var photos = DB.Photos.FindAllByPublished(true).OrderByDatePublishedDescending().Take(2);
</pre>
</p>
<p>That&#8217;s all there is to it!</p>
<p>Here is the complete code for the <code>Get["/"]</code> route:</p>
<pre class="brush:csharp">
Get["/"] = parameters =>
{
	var photos = DB.Photos.FindAllByPublished(true).OrderByDatePublishedDescending().Take(2);
	List&lt;Models.Photo> photoList = photos.ToList&lt;Models.Photo>();

	if (photoList.Count > 0)
	{
		var model = new Models.PhotoDetail();
		model.Photo = photoList[0];
		model.NextSlug = String.Empty;

		if (photoList.Count > 1) model.PreviousSlug = photoList[1].Slug;
		else model.PreviousSlug = String.Empty;

		return View["photodetail", model];
	}
	else
	{
		return View["nophoto"];
	}
};
</pre>
</p>
<p>That&#8217;s it for this time. As usual, the changes to the source code can found on <a href="https://github.com/kristofclaes/MyPhotoBlog/tree/BlogPost4">Github</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kristofclaes.be/blog/2011/05/02/building-a-photoblog-with-nancy-and-simple-data-part-5-updating-simple-data/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Building a photoblog with Nancy and Simple.Data Part 4: Adding the database</title>
		<link>http://www.kristofclaes.be/blog/2011/04/16/building-a-photoblog-with-nancy-and-simple-data-part-4-adding-the-database/</link>
		<comments>http://www.kristofclaes.be/blog/2011/04/16/building-a-photoblog-with-nancy-and-simple-data-part-4-adding-the-database/#comments</comments>
		<pubDate>Sat, 16 Apr 2011 14:36:39 +0000</pubDate>
		<dc:creator>Kristof</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[MyPhotoBlog]]></category>
		<category><![CDATA[nancy]]></category>
		<category><![CDATA[simple.data]]></category>

		<guid isPermaLink="false">http://www.kristofclaes.be/?p=499</guid>
		<description><![CDATA[This is the fourth part in my Building a photoblog with Nancy and Simple.Data series: Setting up the project Defining the routes Rendering some views Adding the database Updating Simple.Data Adding comments The archives In the previous post we made &#8230; <a href="http://www.kristofclaes.be/blog/2011/04/16/building-a-photoblog-with-nancy-and-simple-data-part-4-adding-the-database/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is the fourth part in my <em>Building a photoblog with Nancy and Simple.Data</em> series:</p>
<ol>
<li><a href="http://www.kristofclaes.be/blog/2011/04/03/building-a-photoblog-with-nancy-and-simple-data-part-1-setting-up-the-project/">Setting up the project</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/04/04/building-a-photoblog-with-nancy-and-simple-data-part-2-defining-the-routes/">Defining the routes</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/04/09/building-a-photoblog-with-nancy-and-simple-data-part-3-rendering-some-views/">Rendering some views</a></li>
<li>Adding the database</li>
<li><a href="http://www.kristofclaes.be/blog/2011/05/02/building-a-photoblog-with-nancy-and-simple-data-part-5-updating-simple-data/">Updating Simple.Data</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/06/25/building-a-photoblog-with-nancy-and-simple-data-part-5-adding-comments/">Adding comments</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/07/29/building-a-photoblog-with-nancy-and-simple-data-part-7-the-archives/">The archives</a></li>
</ol>
<p>In the previous post we made a few adjustments to the routes and modules we created in the second post. We added our first view and instructed Nancy to return it when calling a certain route. We also enabled the usage of CSS and Javascript files. We added a Views and Content directory. In this post we will add a SQL Server Compact 4.0 database to the project, setup Simple.Data and make our view a bit more dynamic.</p>
<h2>Enabling SQL Server Compact 4.0</h2>
<p>
Maybe you don&#8217;t have the required components to use SQL Server Compact 4.0 databases. To verify this, <a href="http://www.microsoft.com/web/downloads/platform.aspx">download the Microsoft Web Platform Installer</a> and run it. Select <em>Products</em> in the top part, select <em>Database</em> in the left and check the list on the right for <em>Microsoft SQL Server Compact 4.0</em> and <em>Microsoft SQL Server Compact 4.0 Tools</em>. If they are marked as <em>Installed</em>, you&#8217;re good to go. If not, click <em>Add</em> next to both of them and finally click <em>Install</em> in the bottom of the application.<br />
<a href="http://www.kristofclaes.be/wp-content/uploads/04-02-InstallSQLCE.png"><img src="http://www.kristofclaes.be/wp-content/uploads/04-02-InstallSQLCE-610x422.png" alt="Verify that you can use SQL Server Compact 4.0" title="04-02-InstallSQLCE" width="610" height="422" class="alignnone size-medium wp-image-506" /></a></p>
<h2>Adding the database</h2>
<p>Right click your project in the Solution Explorer, choose <em>Add</em>, <em>Add ASP.NET Folder</em> and <em>App_Data</em>. This adds the <em>App_Data</em> directory to our project. Right click the <em>App_Data</em> directory and choose <em>Add</em> and <em>New Item&#8230;</em>. In the <em>Add New Item</em> dialog, select <em>SQL Server Compact 4.0 Local Database</em> and enter <em>MyPhotoBlog.sdf</em> as the name.<br />
<a href="http://www.kristofclaes.be/wp-content/uploads/04-01-AddDatabase.png"><img src="http://www.kristofclaes.be/wp-content/uploads/04-01-AddDatabase-610x421.png" alt="Add the database to the project" title="04-01-AddDatabase" width="610" height="421" class="alignnone size-medium wp-image-503" /></a></p>
<h2>Creating the tables</h2>
<p><img src="http://www.kristofclaes.be/wp-content/uploads/04-03-ServerExplorer.png" alt="The Server Explorer" title="04-03-ServerExplorer" width="241" height="176" class="alignright size-full wp-image-516" />Doubleclick the <em>MyPhotoBlog.sdf</em> database in the Solution Explorer. This opens up the Server Explorer you see on the right here. Let&#8217;s add a table for our photo&#8217;s. To do that, right click the <em>Tables</em> node and choose <em>Create Table</em>. That will open a new window where we can choose a name for the table and add the desired columns.</p>
<p>Enter <em>Photos</em> for the table name and add these columns:</p>
<ul>
<li>Id (int, Primary Key, Identity)</li>
<li>Name (nvarchar(100))</li>
<li>Slug (nvarchar(100))</li>
<li>Filename (nvarchar(100))</li>
<li>Camera (nvarchar(100))</li>
<li>Lens (nvarchar(100))</li>
<li>Aperture (nvarchar(100))</li>
<li>Exposure (nvarchar(100))</li>
<li>ISO (nvarchar(100))</li>
<li>DatePosted (datetime)</li>
<li>Published (bit)</li>
<li>DatePublished (datetime)</li>
</ul>
<p>Click <em>OK</em> to save the table and add another one. Call it <em>Comments</em> and add these columns:</p>
<ul>
<li>Id (int, Primary Key, Identity)</li>
<li>PhotoId (int, Allow Nulls = No)</li>
<li>Name (nvarchar(100))</li>
<li>Email (nvarchar(100))</li>
<li>Website (nvarchar(100))</li>
<li>Message (nvarchar(4000))</li>
<li>Approved (bit)</li>
</ul>
<p>Click <em>OK</em> to save it again.
</p>
<p>
To add a relation between the two tables, you can right click the <em>Comments</em> table and pick <em>Table Properties</em>. In the <em>Table Properties</em> window, select <em>Add Relations</em> on the left. Enter these details:</p>
<ul>
<li><strong>Relation Name:</strong> PhotoComments</li>
<li><strong>Update Rule:</strong> NO ACTION</li>
<li><strong>Delete Rule:</strong> CASCADE</li>
<li><strong>Primary Key Table:</strong> Photos</li>
<li><strong>Foreign Key Table:</strong> Comments</li>
<li><strong>Primary Key Table Column:</strong> Id</li>
<li><strong>Foreign Key Table Column:</strong> PhotoId</li>
</ul>
<p><a href="http://www.kristofclaes.be/wp-content/uploads/04-04-AddRelationship.png"><img src="http://www.kristofclaes.be/wp-content/uploads/04-04-AddRelationship-610x502.png" alt="Add the relation between Photos and Comments" title="04-04-AddRelationship" width="610" height="502" class="alignnone size-medium wp-image-524" /></a></p>
<p>Click <em>Add Columns</em> and then <em>Add Relation</em> to save the relation.
</p>
<h2>Adding some test data</h2>
<p>To test Simple.Data, we will start with trying to fetch data from the database. Before we can do that, we need to add some data to the database so we will actually <em>have</em> something to fetch.</p>
<p>Right click the <em>MyPhotoBlog.sdf</em> database in the <em>Server Explorer</em> and choose <em>New Query</em>. An <em>Add Table</em> window will popup asking us to add tables. We&#8217;ll just ignore this and click <em>Close</em>. We see the query view is divided in four parts. We will only need the third one that shows &#8220;SELECT FROM&#8221; by default. Replace the &#8220;SELECT FROM&#8221; with this code:</p>
<pre class="brush:sql">
insert into Photos (Name, Slug, Filename, Camera, Lens, Aperture, Exposure, ISO, DatePosted, Published, DatePublished) values ('First post', 'first-post', 'firstpost.jpg', 'Sony A200', 'Sony 50mm F1.8', 'f/2.0', '1/800', '100', '2011/01/01 12:00:00', 1, '2011/01/01 12:00:00');
insert into Photos (Name, Slug, Filename, Camera, Lens, Aperture, Exposure, ISO, DatePosted, Published, DatePublished) values ('Second post', 'second-post', 'secondpost.jpg', 'Sony A200', 'Sony 50mm F1.8', 'f/4.0', '1/250', '200', '2011/02/01 12:00:00', 1, '2011/02/01 12:00:00');
insert into Photos (Name, Slug, Filename, Camera, Lens, Aperture, Exposure, ISO, DatePosted, Published, DatePublished) values ('Third post', 'third-post', 'thirdpost.jpg', 'Sony A200', 'Tamron 90mm Macro', 'f/8.0', '1/125', '200', '2011/03/01 12:00:00', 1, '2011/03/01 12:00:00');
insert into Photos (Name, Slug, Filename, Camera, Lens, Aperture, Exposure, ISO, DatePosted, Published, DatePublished) values ('Fourth post', 'fourth-post', 'fourthpost.jpg', 'Sony A200', 'Sony 50mm F1.8', 'f/1.8', '1/3200', '100', '2011/04/01 12:00:00', 1, '2011/04/01 12:00:00');
insert into Photos (Name, Slug, Filename, Camera, Lens, Aperture, Exposure, ISO, DatePosted, Published, DatePublished) values ('Fifth post', 'fifth-post', 'fifthpost.jpg', 'Sony A200', 'Sony 50mm F1.8', 'f/16', '8"', '100', '2011/04/09 12:00:00', 1, '2011/04/09 12:00:00');
</pre>
<p>Now we can press CTRL+R or click the red exclamation mark in the toolbar to execute the query. We get a warning telling us that the query definitions differ and that the query cannot be represented graphically in the Diagram and Criteria Pane. That&#8217;s normal. It&#8217;s because there is no way to graphically represent insert statements. We&#8217;ll Just click <em>Continue</em>. We now get notified that five rows were affected by the last query.</p>
<p>To verify this, right click the <em>MyPhotoBlog.sdf</em> database again and choose <em>Show Table Data</em>. Our five test records are present in the table!</p>
<p><img src="http://www.kristofclaes.be/wp-content/uploads/04-05-DataDirectory.png" alt="The Data directory" title="04-05-DataDirectory" width="266" height="374" class="alignright size-full wp-image-533" />In addition to some test records in the database, we will also need a photo for each record. We will keep photo&#8217;s of our photoblog in a separate directory. Let&#8217;s add it to our project. Create a directory called <em>Data</em> in the root of your project and copy the <em>Web.Config</em> file from the <em>Content</em> directory to the new <em>Data</em> directory so Nancy won&#8217;t interfere when trying to serve static files from that directory. Now we can put five test photo&#8217;s in the <em>Data</em> directory. You can <a href="http://www.kristofclaes.be/sources/Data-04.zip">download the samples I use</a>, or you can put some of your own there. Just make sure the names are correct (&#8220;firstpost.jpg&#8221;, &#8220;secondpost.jpg&#8221;, &#8230;, &#8220;fifthpost.jpg&#8221;). My photo&#8217;s are all 960 pixels wide to fit in the &#8220;design&#8221; of the photoblog.</p>
<h2>Adding Simple.Data to our Modules</h2>
<p>The <a href="https://github.com/ToJans/NerdBeers">NerdBeers</a> application provided me with some inspiration on how to add Simple.Data to our Modules.</p>
<h3>Creating the DBFactory</h3>
<p>Add a new directory called <em>Services</em> to your project and add an interface called <em>IDBFactory</em> to it. This is a very simple interface because this is all the code it needs:</p>
<pre class="brush:csharp">
public interface IDBFactory
{
	dynamic DB();
}
</pre>
<p>Just an interface won&#8217;t do it. We need something that implements it. Add a new class called <em>DBFactory</em> to the <em>Services</em> directory and add the following code:</p>
<pre class="brush:csharp">
public class DBFactory : IDBFactory
{
	protected dynamic _db = null;

	public DBFactory()
	{

	}

	public dynamic DB()
	{
		if (_db == null)
		{
			var c = System.Web.HttpContext.Current;
			var s = ConfigurationManager.ConnectionStrings["MyPhotoBlog"];

			if (s == null || String.IsNullOrWhiteSpace(s.ConnectionString))
			{
				_db = Simple.Data.Database.OpenFile(c.Server.MapPath("~/App_Data/MyPhotoBlog.sdf"));
			}
			else
			{
				_db = Simple.Data.Database.OpenConnection(s.ConnectionString);
			}
		}

		return _db;
	}
}
</pre>
<p>The <code>DBFactory</code> class has one method: <code>DB()</code>. This method checks if there is a connection string listening to the name &#8220;MyPhotoBlog&#8221; present in the <em>Web.Config</em> file. If it is, Simple.Data uses that connection string to establish a connection to the database and if it isn&#8217;t, we tell Simple.Data to fall back to our <em>MyPhotoBlog.sdf</em> in the <em>App_Data</em> directory.
</p>
<p>&#8220;Wait a minute,&#8221; you say. &#8220;What&#8217;s this? The <code>DB()</code> method just returns a <code>dynamic</code>. We need something like a <code>DbContext</code>, no?&#8221; No we don&#8217;t. Simple.Data is built using the awesomeness of dynamics and we&#8217;ll get to that in just a minute!</p>
<h3>Adding the DBFactory to our Modules</h3>
<p>Remember that we created a base class called <em>PhotoblogModule</em> in part 2 of this blog? Well, there was a good reason for that. We&#8217;ll use it to take care of calling <code>DBFactory.DB()</code> for all other modules.</p>
<p>Open the <em>PhotoblogModule.cs</em> file (in the <em>Modules</em> directory) and add a dynamic object called <em>DB</em>:</p>
<pre class="brush:csharp; highlight:3">
public abstract class PhotoblogModule : NancyModule
{
	protected dynamic DB;

	public PhotoblogModule() : base()
	{

	}

	public PhotoblogModule(string modulePath) : base(modulePath)
	{

	}
}
</pre>
</p>
<p>
We now have an object that can store what the <code>DBFactory.DB()</code> will return. We can add <code>this.DB = new DBFactory().DB();</code> right? Well, yes, we <em>could</em> do that, but there is a better solution. We can make use of something called <em>Dependency Injection</em>. Dependency Injection (or DI) is a form of Inversion of Control (or IoC). What that means is that it inverses the flow of control by injecting dependencies in order to reduce the coupling between components. If you&#8217;re not familiar with DI or IoC you&#8217;ll probably be a bit confused after reading that. I know I was when I first heard about it.</p>
<p>Let&#8217;s say we just use <code>this.DB = new DBFactory().DB();</code> in the constructor of our <code>PhotoblogModule</code> class. When we do that, we create a tight coupling between the <code>PhotoblogModule</code> class and the <code>DBFactory</code> class. If we ever want to replace the <code>DBFactory</code> class with something else, we would probably have to change our <code>PhotoblogModule</code> as well because they are tightly coupled. Or if we want to Unit Test our <code>PhotoblogModule</code> we would be forced to have a database ready when doing the tests because the <code>PhotoblogModule</code> relies on the <code>DBFactory</code> class.</p>
<p>Dependency Injection solves this for us. In this case we will give the constructors of the <code>PhotoblogModule</code> class a parameter of the type <code>IDBFactory</code> like this:</p>
<pre class="brush:csharp; highlight:[5,7,10,12]">
public abstract class PhotoblogModule : NancyModule
{
	protected dynamic DB;

	public PhotoblogModule(IDBFactory dbFactory) : base()
	{
		DB = dbFactory.DB();
	}

	public PhotoblogModule(IDBFactory dbFactory, string modulePath) : base(modulePath)
	{
		DB = dbFactory.DB();
	}
}
</pre>
</p>
<p>Now, the <code>PhotoblogModule</code> class knows &#8220;Ok, I will be provided with something that implements the <code>IDBFactory</code> interface. I don&#8217;t know what concrete object I will receive or where it comes from, and frankly, I don&#8217;t even care. I only know that whatever is passed to me will at least have a <code>DB()</code> methods which returns a <code>dynamic</code>.&#8221;</p>
<p>What is responsible for passing in concrete object implement the <code>IDBFactory</code> interface? In our case, the built in IoC container in Nancy called TinyIoC will take care of everything for us. When creating modules, it will notice that the <code>PhotoblogModule</code> has a dependency on the <code>IDBFactory</code> interface. It will then look for a class implementing that interface and it will inject an instance of that class into the module. Pretty neat, huh?</p>
<p>When we try to build our project, we will get a few errors at this point. That&#8217;s because the modules inheriting from our <code>PhotoblogModule</code> will call incorrect constructors of their base class. To fix this, add <code>IDBFactory dbFactory</code> as the first argument of each constructor and pass it to the <code>base()</code> statement like this:</p>
<pre class="brush:csharp">
public ArchivesModule(IDBFactory dbFactory) : base(dbFactory, "/archives")
{
    ...
}
</pre>
</p>
<p>Now all our modules have access to a dynamic <code>DB</code> object created by Simple.Data. However, when we build and run the project (CTRL+F5), we get an error! It took me a while to figure this one out, be it appears that Simple.Data.SqlCe40 also needs Simple.Data.Ado to function. Adding it is easy thanks to NuGet. Just enter &#8220;Install-Package Simple.Data.Ado&#8221; in the <em>Package Manager Console</em> and we&#8217;re set!</p>
<h2>Reading from the database with Simple.Data</h2>
<p>
Open the <code>RootModule</code> class. We&#8217;ll see how we can get the latest published photo. All we have is the dynamic <code>DB</code> object from our <code>PhotoblogModule</code> base class. Because it is dynamic, we can type <code>DB.</code> followed by whatever we want. Simple.Data will figure out during runtime what to do with whatever you typed.</p>
<p>When we are going to query the database, we will need something to represent the data that is returned. So before we can actually fetch some data, we will need add a <code>Photo</code> class to our project. Create a new directory called <em>Models</em> and in it, create a new class called <em>Photo</em>:</p>
<pre class="brush:csharp">
public class Photo
{
	public int Id { get; set; }
	public string Name { get; set; }
	public string Slug { get; set; }
	public string Filename { get; set; }
	public string Camera { get; set; }
	public string Lens { get; set; }
	public string Aperture { get; set; }
	public string Exposure { get; set; }
	public string ISO { get; set; }
	public DateTime DatePosted { get; set; }
	public bool Published { get; set; }
	public DateTime? DatePublished { get; set; }
}
</pre>
<p>As you can see, this looks very much like what our <em>Photos table</em> in the database looks like.
</p>
<p>Add another class to the <em>Models</em> directory and call it <em>PhotoDetail</em>. Add the following code:</p>
<pre class="brush:csharp">
public class PhotoDetail
{
	public Photo Photo { get; set; }

	public string NextSlug { get; set; }
	public bool HasNext { get { return !String.IsNullOrEmpty(this.NextSlug); } }

	public string PreviousSlug { get; set; }
	public bool HasPrevious { get { return !String.IsNullOrEmpty(this.PreviousSlug); } }
}
</pre>
<p>This will serve as the model to pass to our view. It has a way of letting the view know if there is a previous and a next photo and telling it what the slugs are.
</p>
<p>Now we can finally try to get something out of our database. On the homepage we need the most recent published photo. That&#8217;s the photo where <em>Published</em> is <em>True</em> with the highest <em>DatePublished</em>. Add this code to the <code>Get["/"]</code> route in the <code>RootModule</code> class:</p>
<pre class="brush:csharp">
Get["/"] = parameters =>
{
	// Get all photo's that are published
	var photos = DB.Photos.FindAllByPublished(true);
	List&lt;Models.Photo> photoList = photos.ToList&lt;Models.Photo>();

	// Order them so the newest come first
	photoList = photoList.OrderByDescending(p => p.DatePublished).ToList();

	// Get most recent photo
	var latestPhoto = photoList.FirstOrDefault();

	if (latestPhoto != null)
	{
		var model = new Models.PhotoDetail();
		model.Photo = latestPhoto;
		model.NextSlug = String.Empty;

		if (photoList.Count > 1) model.PreviousSlug = photoList[1].Slug;
		else model.PreviousSlug = String.Empty;

		return View["photodetail", model];
	}
	else
	{
		return View["nophoto"];
	}
};
</pre>
</p>
<p>
On line 4, we are telling Simple.Data that we want a list of photo&#8217;s where the <em>Published</em> field is true. Then we ask for the results as a <code>List&lt;Models.Photo></code> on line 5.
</p>
<p>
Of the next part, I&#8217;m not really sure if I&#8217;m doing this the right way. This is the first time I&#8217;m working with Simple.Data and the available documentation is a bit sparse at the moment, but I can&#8217;t find a way to pass in an order by clause to the database. That&#8217;s why we are doing the sorting of the photo&#8217;s on their publication date in the code on line 8. <strong>Update:</strong> <a href="http://twitter.com/#!/markrendle">Mark Rendle</a>, the author of Simple.Data just told me that sorting and paging is scheduled for version 0.6.
</p>
<p>After the list is sorted, we can get the photo with the highest publication data on line 11. It is of course possible that there is no photo in the database, so we check for that on line 13.</p>
<p>If there is a photo, we put it in an instance of <code>PhotoDetail</code> (line 16). Since this is the latest photo, NextSlug is always empty (line 17). On lines 19 and 20 we check if there is a previous photo. If there is, we set the slug. Finally, we pass our model to the view on line 22.</p>
<p>If no photo was found, we&#8217;ll return a view called &#8220;nophoto&#8221;.</p>
<h2>Updating our views</h2>
<p>Now that we are sending data back to our view, we need to update our view so it display the incoming data. Change <em>photodetail.cshtml</em> so it looks like this:</p>
<pre class="brush:xml;highlight:[16,18,21,22,23,24,25,28,29,30,31,32,33,34,35,39,40,41,42,43,44,45,46]">
&lt;!doctype html>
&lt;html>
&lt;head>
    &lt;meta charset="utf-8" />
    &lt;meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

    &lt;title>My First View&lt;/title>
    &lt;link rel="Stylesheet" type="text/css" href="/Content/Css/reset.css" />
    &lt;link rel="Stylesheet" type="text/css" href="/Content/Css/photoblog.css" />

    &lt;script type="text/javascript" src="/Content/Scripts/modernizr-1.7.min.js">&lt;/script>
&lt;/head>
&lt;body>
    &lt;header>MyPhotoBlog&lt;/header>
    &lt;div id="main">
        &lt;div id="name">@Model.Photo.Name&lt;/div>
        &lt;div id="photo">
            &lt;img src="/Data/@Model.Photo.Filename" />
        &lt;/div>
        &lt;div id="exif">
            &lt;span class="type">Camera:&lt;/span> &lt;span id="camera" class="value camera">@Model.Photo.Camera&lt;/span>
            &lt;span class="type">Lens:&lt;/span> &lt;span id="lens" class="value">@Model.Photo.Lens&lt;/span>
            &lt;span class="type">Aperture:&lt;/span> &lt;span id="aperture" class="value">@Model.Photo.Aperture&lt;/span>
            &lt;span class="type">Exposure:&lt;/span> &lt;span id="exposure" class="value">@Model.Photo.Exposure&lt;/span>
            &lt;span class="type">ISO:&lt;/span> &lt;span id="iso" class="value">@Model.Photo.ISO&lt;/span>
        &lt;/div>
        &lt;nav>
            @if (Model.HasPrevious)
            {
                &lt;a id="previous" href="/photos/@Model.PreviousSlug">&laquo; Previous&lt;/a>
            }
            else
            {
                &lt;span id="previous">&laquo; Previous&lt;/span>
            }

            &lt;a href="/archives" id="archives">Archives&lt;/a>

            @if (Model.HasNext)
            {
                &lt;a id="next" href="/photos/@Model.NextSlug">Next &raquo;&lt;/a>
            }
            else
            {
                &lt;span id="next">Next &raquo;&lt;/span>
            }
        &lt;/nav>
    &lt;/div>
    &lt;footer>MyPhotoBlog is built with &lt;a href="https://github.com/NancyFX/Nancy">Nancy&lt;/a> and &lt;a href="https://github.com/markrendle/Simple.Data">Simple.Data&lt;/a>.&lt;/footer>

    &lt;script type="text/javascript" src="/Content/Scripts/jquery-1.5.2.min.js">&lt;/script>
&lt;/body>
&lt;/html>
</pre>
</p>
<h2>Testing everything</h2>
<p>Ok, this is exciting! Press CTRL+F5 to see if everything works. Isn&#8217;t it amazing?<br />
<a href="http://www.kristofclaes.be/wp-content/uploads/04-06-ItWorks.png"><img src="http://www.kristofclaes.be/wp-content/uploads/04-06-ItWorks-610x465.png" alt="It works!" title="04-06-ItWorks" width="610" height="465" class="alignnone size-medium wp-image-564" /></a>
</p>
<h2>The &#8220;nophoto&#8221; view</h2>
<p>Since we return a &#8220;nophoto&#8221; view when there are no photo&#8217;s in the database, we need to add that view to our <em>Views</em> directory. Add a new HTM File and call it <em>nophoto.cshtml</em> and add the following code:</p>
<pre class="brush:xml">
&lt;!doctype html>
&lt;html>
&lt;head>
    &lt;meta charset="utf-8" />
    &lt;meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

    &lt;title>Photo's gone missing&lt;/title>
    &lt;link rel="Stylesheet" type="text/css" href="/Content/Css/reset.css" />
    &lt;link rel="Stylesheet" type="text/css" href="/Content/Css/photoblog.css" />

    &lt;script type="text/javascript" src="/Content/Scripts/modernizr-1.7.min.js">&lt;/script>
&lt;/head>
&lt;body>
    &lt;header>MyPhotoBlog&lt;/header>
    &lt;div id="main">
        &lt;div id="photo">
            &lt;div>Oops. All our photo's have gone missing. If you find one, please let us know!&lt;/div>
        &lt;/div>
    &lt;/div>
    &lt;footer>MyPhotoBlog is built with &lt;a href="https://github.com/NancyFX/Nancy">Nancy&lt;/a> and &lt;a href="https://github.com/markrendle/Simple.Data">Simple.Data&lt;/a>.&lt;/footer>

    &lt;script type="text/javascript" src="/Content/Scripts/jquery-1.5.2.min.js">&lt;/script>
&lt;/body>
&lt;/html>
</pre>
</p>
<h2>Wrapping it up</h2>
<p><a href="http://www.kristofclaes.be/wp-content/uploads/04-07-Project.png"><img src="http://www.kristofclaes.be/wp-content/uploads/04-07-Project-150x150.png" alt="Our project structure" title="04-07-Project" width="150" height="150" class="alignright size-thumbnail wp-image-567" /></a>That&#8217;s it for today. We&#8217;ve done quite a lot actually. We have installed SQL Server Compact 4.0, added a database to our project, created tables and added test data. Next we have created an <code>IDBFactory</code> interface and a <code>DBFactory</code> class and we have injected it in our modules. Finally, we have made changes to our homepage so that it always show the most recently published photo. On the right you can see the project stucture at this point (click it for a bigger image).</p>
<p>As usual, the changes to the source code can found on <a href="https://github.com/kristofclaes/MyPhotoBlog/tree/BlogPost4">Github</a>.</p>
<p>Next time we&#8217;ll take care of the rest of the front end views: the <code>PhotoModule</code> and the <code>ArchivesModule</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kristofclaes.be/blog/2011/04/16/building-a-photoblog-with-nancy-and-simple-data-part-4-adding-the-database/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Building a photoblog with Nancy and Simple.Data Part 3: Rendering some views</title>
		<link>http://www.kristofclaes.be/blog/2011/04/09/building-a-photoblog-with-nancy-and-simple-data-part-3-rendering-some-views/</link>
		<comments>http://www.kristofclaes.be/blog/2011/04/09/building-a-photoblog-with-nancy-and-simple-data-part-3-rendering-some-views/#comments</comments>
		<pubDate>Sat, 09 Apr 2011 17:56:40 +0000</pubDate>
		<dc:creator>Kristof</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[MyPhotoBlog]]></category>
		<category><![CDATA[nancy]]></category>

		<guid isPermaLink="false">http://www.kristofclaes.be/?p=459</guid>
		<description><![CDATA[This is the third part in my Building a photoblog with Nancy and Simple.Data series: Setting up the project Defining the routes Rendering some views Adding the database Updating Simple.Data Adding comments The archives In the previous post we added &#8230; <a href="http://www.kristofclaes.be/blog/2011/04/09/building-a-photoblog-with-nancy-and-simple-data-part-3-rendering-some-views/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is the third part in my <em>Building a photoblog with Nancy and Simple.Data</em> series:</p>
<ol>
<li><a href="http://www.kristofclaes.be/blog/2011/04/03/building-a-photoblog-with-nancy-and-simple-data-part-1-setting-up-the-project/">Setting up the project</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/04/04/building-a-photoblog-with-nancy-and-simple-data-part-2-defining-the-routes/">Defining the routes</a></li>
<li>Rendering some views</li>
<li><a href="http://www.kristofclaes.be/blog/2011/04/16/building-a-photoblog-with-nancy-and-simple-data-part-4-adding-the-database/">Adding the database</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/05/02/building-a-photoblog-with-nancy-and-simple-data-part-5-updating-simple-data/">Updating Simple.Data</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/06/25/building-a-photoblog-with-nancy-and-simple-data-part-5-adding-comments/">Adding comments</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/07/29/building-a-photoblog-with-nancy-and-simple-data-part-7-the-archives/">The archives</a></li>
</ol>
<p>In the <a href="http://www.kristofclaes.be/blog/2011/04/04/building-a-photoblog-with-nancy-and-simple-data-part-2-defining-the-routes/">previous post</a> we added some <em>NancyModules</em> to our project and defined some routes in them. To test the routes, we let them send a simple string back to the browser. In this post we will first make some small adjustments to our routes and modules based on feedback on the previous post. Next we will see how we can use Razor views to send a response back to the browser. Let&#8217;s get started!</p>
<h2>Creating an AuthenticationModule</h2>
<p>In a comment on the previous post, <a href="http://www.grumpydev.com/">Steven Robbins</a> (also know as <a href="http://twitter.com/#!/grumpydev">@grumpydev on Twitter</a>) explained that the built in security, which we will use, secures routes at the module level. When we secure the <code>AdminModule</code> class, the login page will also be secured. That means you would have to be logged in to log in. Obviously, we don&#8217;t want that <img src='http://www.kristofclaes.be/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  That&#8217;s why will put the login routes in their own module.</p>
<p>Just like we did in the previous post, we will create a new class in the <em>Modules</em> directory. Let&#8217;s call it <em>AuthenticationModule</em>. As you will know by know, the class should inherit from <code>PhotoblogModule</code>. Add these routes:</p>
<pre class="brush:c-sharp">
public class AuthenticationModule : PhotoblogModule
{
	public AuthenticationModule() : base()
	{
		Get["/login"] = parameters =>
		{
			return "Display the login form";
		};

		Post["/login"] = parameters =>
		{
			// Perform validation, then redirect
			return Response.AsRedirect("/admin/photos");
		};

		Post["/logout"] = parameters =>
		{
			// Logout and redirect
			return Response.AsRedirect("/login");
		};
	}
}
</pre>
</p>
<h2>Updating the AdminModule</h2>
<p>Now that we have put the login routes in the <code>AuthenticationModule</code>, we can remove them from the <code>AdminModule</code>. We also have to add a new route, one which I didn&#8217;t think about when writing the previous post. We have added routes to add and edit a photo, but there is no way to delete one. Let&#8217;s add that one. After removing the <code>Get[""]</code> and <code>Post["/login"]</code> and adding the <code>Get["/photos/delete/{slug}"]</code> and <code>Post["/photos/delete/{slug}"]</code> routes, our <code>AdminModule</code> looks like this:</p>
<pre class="brush:c-sharp">
public class AdminModule : PhotoblogModule
{
	public AdminModule() : base("/admin")
	{
		Get["/photos"] = parameters =>
		{
			return "A list of all the photo's.";
		};

		Get["/photos/add"] = parameters =>
		{
			return "Display the form to add a photo.";
		};

		Post["/photos/add"] = parameters =>
		{
			// Add the photo, then redirect
			string slug = "newPhoto";
			return Response.AsRedirect("/admin/photos/edit/" + slug);
		};

		Get["/photos/edit/{slug}"] = parameters =>
		{
			return String.Format("Display the form to edit a photo called '{0}'.",
				parameters.slug);
		};

		Post["/photos/edit/{slug}"] = parameters =>
		{
			// Edit the photo, then redirect
			string slug = Convert.ToString(parameters.slug);
			return Response.AsRedirect("/admin/photos/edit/" + slug);
		};

		Get["/photos/delete/{slug}"] = parameters =>
		{
			return String.Format("Are you sure you want to delete the photo called '{0}'?",
				parameters.slug);
		};

		Post["/photos/delete/{slug}"] = parameters =>
		{
			// Delete the photo, then redirect
			return Response.AsRedirect("/admin/photos");
		};

		Get["/comments"] = parameters =>
		{
			return "A list of all the comments.";
		};

		Post["/comments/delete/{id}"] = parameters =>
		{
			// Delete the comment, then redirect
			return Response.AsRedirect("/admin/comments");
		};
	}
}
</pre>
</p>
<h2>Improving the ArchivesModule</h2>
<p>As <a href="http://thecodejunkie.com">TheCodeJunkie</a> (<a href="http://twitter.com/#!/TheCodeJunkie">@TheCodeJunkie on Twitter</a>), the main author of Nancy, suggests, we can use a regular expression in the route definitions to filter the archives by year and/or month. I came up with these:</p>
<pre class="brush:c-sharp; highlight:[10,16]">
public class ArchivesModule : PhotoblogModule
{
	public ArchivesModule() : base("/archives")
	{
		Get[""] = parameters =>
		{
			return "All photo's of all years and months.";
		};

		Get[@"/(?&lt;year>19[0-9]{2}|2[0-9]{3})"] = parameters =>
		{
			return String.Format("All photo's of the year {0}",
				parameters.year);
		};

		Get[@"/(?&lt;year>19[0-9]{2}|2[0-9]{3})/(?&lt;month>0[1-9]|1[012])"] = parameters =>
		{
			return String.Format("All photo's of month {0} of the year {1}",
				parameters.month,
				parameters.year);
		};
	}
}
</pre>
<p>This makes sure that the routes only get called when the <code>year</code> parameter is a numerical value between 1900 and 2999. Maybe not ideal, but it does the trick. The <code>month</code> parameter has to be a numerical value between 1 and 12.
</p>
<p>That&#8217;s it for the changes. On with the show!</p>
<p><a name="razorview"></a></p>
<h2>Adding our first Razor view</h2>
<p>At the moment of writing this post, Nancy expects all views to be located in a <em>Views</em> directory in the root of your application. The view location conventions will get updated in a few weeks, but for now we have to follow the current rules. So, let&#8217;s create a new directory called <em>Views</em> in the root of our application. Right click the directory and choose <em>Add</em> and <em>New Item&#8230;</em>. Select the <em>HTML Page</em> type, pick <em>photodetail</em> as the name and change the extension to <em>cshtml</em>.</p>
<p><a href="http://www.kristofclaes.be/wp-content/uploads/03-01-AddView.png"><img src="http://www.kristofclaes.be/wp-content/uploads/03-01-AddView-610x421.png" alt="Add the first view" title="03-01-AddView" width="610" height="421" class="alignnone size-medium wp-image-477" /></a>
</p>
<p>Unfortunately, the Razor ViewEngine implementation in Nancy doesn&#8217;t support the use of Layouts (yet?) because the code that enables this isn&#8217;t located in the Razor assembly but in the System.Web.Mvc assembly, so each of our Razor files will have contain the complete markup for the page.</p>
<p>Add the following code to the newly created <em>photodetail.cshtml</em> file:</p>
<pre class="brush:xml">
&lt;!doctype html>
&lt;html>
&lt;head>
    &lt;meta charset="utf-8" />
    &lt;meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">

    &lt;title>My First View&lt;/title>
    &lt;link rel="Stylesheet" type="text/css" href="/Content/Css/reset.css" />
    &lt;link rel="Stylesheet" type="text/css" href="/Content/Css/photoblog.css" />

    &lt;script type="text/javascript" src="/Content/Scripts/modernizr-1.7.min.js">&lt;/script>
&lt;/head>
&lt;body>
    &lt;header>MyPhotoBlog&lt;/header>
    &lt;div id="main">
        &lt;div id="photo">
            &lt;img src="" width="960" height="640" />
        &lt;/div>
        &lt;div id="exif">
            &lt;span class="type">Camera:&lt;/span> &lt;span id="camera" class="value camera">Sony A200&lt;/span>
            &lt;span class="type">Lens:&lt;/span> &lt;span id="lens" class="value">Sony DT 50mm F1.8 SAM&lt;/span>
            &lt;span class="type">Aperture:&lt;/span> &lt;span id="aperture" class="value">f/4&lt;/span>
            &lt;span class="type">Exposure:&lt;/span> &lt;span id="exposure" class="value">1/250&lt;/span>
            &lt;span class="type">ISO:&lt;/span> &lt;span id="iso" class="value">200&lt;/span>
        &lt;/div>
        &lt;nav>
            &lt;a href="#" id="previous">&laquo; Previous&lt;/a>
            &lt;a href="#" id="archives">Archives&lt;/a>
            &lt;a href="#" id="next">Next &raquo;&lt;/a>
        &lt;/nav>
    &lt;/div>
    &lt;footer>MyPhotoBlog is built with &lt;a href="https://github.com/thecodejunkie/Nancy">Nancy&lt;/a> and &lt;a href="https://github.com/markrendle/Simple.Data">Simple.Data&lt;/a>.&lt;/footer>

    &lt;script type="text/javascript" src="/Content/Scripts/jquery-1.5.2.min.js">&lt;/script>
&lt;/body>
&lt;/html>
</pre>
</p>
<h2>Calling the view from a route</h2>
<p>Now that we have created a view, we need to tell Nancy when to call it. Let&#8217;s make this view the homepage view. The root route (hehe) is located in our <code>RootModule</code> class. Open that file and adjust the <code>Get["/"]</code> route so that looks like this:</p>
<pre class="brush:c-sharp">
Get["/"] = parameters =>
{
    return View["photodetail"];
};
</pre>
</p>
<h2>Using CSS and Javascript</h2>
<p>
As you might have noticed, the view we just created uses two CSS and two Javascript files. We&#8217;ll put all content files (CSS, Javascript and images) in a dedicated directory. Create a directory called <em>Content</em> in the root of your project and add two subdirectories in it: <em>Css</em> and <em>Scripts</em>. I won&#8217;t put the full source of the four files in this post, but if you want to follow along, <a href="http://www.kristofclaes.be/sources/Content-03.zip">you can download them here</a>.
</p>
<h2>Testing the view</h2>
<p>
When you press CTRL+F5, you&#8217;ll see that the Nancy now sends our view to the browser. But it looks a bit dull doesn&#8217;t it?</p>
<p><a href="http://www.kristofclaes.be/wp-content/uploads/03-02-Dull.png"><img src="http://www.kristofclaes.be/wp-content/uploads/03-02-Dull-610x465.png" alt="What a dull view!" title="03-02-Dull" width="610" height="465" class="alignnone size-medium wp-image-481" /></a></p>
<p>It looks like our CSS isn&#8217;t applied. How is that possible? Well. Nancy intercepts <em>all</em> requests. That means that Nancy will also answer requests for CSS or Javascript files and because it doesn&#8217;t find a suitable route in of our modules, Nancy returns a <em>404 Page not found</em> error.
</p>
<p>To solve this, we need to hack the Nancy.dll assembly with a hex editor and add some assembly code to override certain low level function calls. Luckily for you, that&#8217;s not true <img src='http://www.kristofclaes.be/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  All we need to do is give the <em>Content</em> directory its own <em>Web.Config</em> file and disable Nancy for that directory. So add a new <em>Web.Config</em> file to the <em>Content</em> directory (right click the directory, pick <em>Add</em>, <em>New Item&#8230;</em> and choose <em>Web Configuration File</em>) and add the following content to it:</p>
<pre class="brush:xml">
&lt;?xml version="1.0"?>
&lt;configuration>
    &lt;system.web>
        &lt;httpHandlers>
            &lt;remove verb="*" path="*"/>
        &lt;/httpHandlers>
    &lt;/system.web>

    &lt;system.webServer>
        &lt;handlers>
            &lt;remove name="Nancy" />
        &lt;/handlers>
    &lt;/system.webServer>
&lt;/configuration>
</pre>
</p>
<p>Press CTRL+F5 again (or just refresh the browser if it&#8217;s still open) and behold! The page still looks a bit dull, but a little less so <img src='http://www.kristofclaes.be/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p><a href="http://www.kristofclaes.be/wp-content/uploads/03-03-LittleLessDull.png"><img src="http://www.kristofclaes.be/wp-content/uploads/03-03-LittleLessDull-610x465.png" alt="A little less dull view!" title="03-03-LittleLessDull" width="610" height="465" class="alignnone size-medium wp-image-482" /></a>
</p>
<h2>Wrapping things up</h2>
<p><img src="http://www.kristofclaes.be/wp-content/uploads/03-04-ProjectStructure.png" alt="The current project structure" title="03-04-ProjectStructure" width="326" height="480" class="alignright size-full wp-image-486" />In this post we have made a few adjustments to the routes and modules we created in the previous post. We have added our first view and instructed Nancy to return it when calling a certain route. We&#8217;ve also enabled the usage of CSS and Javascript files. We have added a <em>Views</em> and <em>Content</em> directory. Our project structure now looks like the one on the right.</p>
<p>The changes to source code can be found on <a href="https://github.com/kristofclaes/MyPhotoBlog/tree/BlogPost3">Github</a>.</p>
<p>In the next post we&#8217;ll see how we can replace the static content of the view with something more dynamic by letting Nancy pass in a viewmodel and maybe we&#8217;ll finally get started with Simple.Data.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kristofclaes.be/blog/2011/04/09/building-a-photoblog-with-nancy-and-simple-data-part-3-rendering-some-views/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Building a photoblog with Nancy and Simple.Data Part 2: Defining the routes</title>
		<link>http://www.kristofclaes.be/blog/2011/04/04/building-a-photoblog-with-nancy-and-simple-data-part-2-defining-the-routes/</link>
		<comments>http://www.kristofclaes.be/blog/2011/04/04/building-a-photoblog-with-nancy-and-simple-data-part-2-defining-the-routes/#comments</comments>
		<pubDate>Mon, 04 Apr 2011 17:30:22 +0000</pubDate>
		<dc:creator>Kristof</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[MyPhotoBlog]]></category>
		<category><![CDATA[nancy]]></category>

		<guid isPermaLink="false">http://www.kristofclaes.be/?p=414</guid>
		<description><![CDATA[This is the second part in my Building a photoblog with Nancy and Simple.Data series: Setting up the project Defining the routes Rendering some views Adding the database Updating Simple.Data Adding comments The archives In the previous post we created &#8230; <a href="http://www.kristofclaes.be/blog/2011/04/04/building-a-photoblog-with-nancy-and-simple-data-part-2-defining-the-routes/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is the second part in my <em>Building a photoblog with Nancy and Simple.Data</em> series:</p>
<ol>
<li><a href="http://www.kristofclaes.be/blog/2011/04/03/building-a-photoblog-with-nancy-and-simple-data-part-1-setting-up-the-project/">Setting up the project</a></li>
<li>Defining the routes</li>
<li><a href="http://www.kristofclaes.be/blog/2011/04/09/building-a-photoblog-with-nancy-and-simple-data-part-3-rendering-some-views/">Rendering some views</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/04/16/building-a-photoblog-with-nancy-and-simple-data-part-4-adding-the-database/">Adding the database</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/05/02/building-a-photoblog-with-nancy-and-simple-data-part-5-updating-simple-data/">Updating Simple.Data</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/06/25/building-a-photoblog-with-nancy-and-simple-data-part-5-adding-comments/">Adding comments</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/07/29/building-a-photoblog-with-nancy-and-simple-data-part-7-the-archives/">The archives</a></li>
</ol>
<p>In the <a href="http://www.kristofclaes.be/blog/2011/04/03/building-a-photoblog-with-nancy-and-simple-data-part-1-setting-up-the-project/">previous post</a> we created the Visual Studio solution, added the necessary references to Nancy and Simple.Data and tested two basic routes to see if Nancy was setup correctly. In this post we will decide what routes we will need in the application and we will configure our NancyModules accordingly. Let&#8217;s get started!</p>
<h2>What routes do we need?</h2>
<p>To answer that question, we first need to determine what kind of information our application needs to expose and how people should interact with it. Once we know that, we can map the requirements to a route and a method (POST or GET). To make things a bit easier, we will split up the requirements in two parts: front end and back end. The front end of the photoblog is visible for everyone while the back end is only visible for the logged in administrator, me.</p>
<h3>Front end requirements</h3>
<ul>
<li>
    Visit the homepage to view the latest photo<br />
    &nbsp;&nbsp;Route: /<br />
    &nbsp;&nbsp;Method: GET</p>
</li>
<li>
    Visit a specific photo with its comments<br />
    &nbsp;&nbsp;Route: /photo/{slug}<br />
    &nbsp;&nbsp;Method: GET</p>
</li>
<li>
    Add a comment to a specific photo<br />
    &nbsp;&nbsp;Route: /photo/{slug}/addcomment<br />
    &nbsp;&nbsp;Method: POST</p>
</li>
<li>
    Visit the general archives<br />
    &nbsp;&nbsp;Route: /archives<br />
    &nbsp;&nbsp;Method: GET</p>
</li>
<li>
    Visit the archives for a certain year<br />
    &nbsp;&nbsp;Route: /archives/{year}<br />
    &nbsp;&nbsp;Method: GET</p>
</li>
<li>
    Visit the archives for a certain month of a certain year<br />
    &nbsp;&nbsp;Route: /archives/{year}/{month}<br />
    &nbsp;&nbsp;Method: GET</p>
</li>
</ul>
<h3>Back end requirement</h3>
<ul>
<li>
    View the login form<br />
    &nbsp;&nbsp;Route: /admin<br />
    &nbsp;&nbsp;Method: GET</p>
</li>
<li>
    Login on the system<br />
    &nbsp;&nbsp;Route: /admin/login<br />
    &nbsp;&nbsp;Method: POST</p>
</li>
<li>
    View the list of photo&#8217;s<br />
    &nbsp;&nbsp;Route: /admin/photos<br />
    &nbsp;&nbsp;Method: GET</p>
</li>
<li>
    Add a new photo<br />
    &nbsp;&nbsp;Route: /admin/photos/add<br />
    &nbsp;&nbsp;Method: GET and POST</p>
</li>
<li>
    Edit a photo<br />
    &nbsp;&nbsp;Route: /admin/photos/edit/{slug}<br />
    &nbsp;&nbsp;Method: GET and POST</p>
</li>
<li>
    View a list of comments<br />
    &nbsp;&nbsp;Route: /admin/comments<br />
    &nbsp;&nbsp;Method: GET</p>
</li>
<li>
    Delete a comment<br />
    &nbsp;&nbsp;Route: /admin/comments/delete/{id}<br />
    &nbsp;&nbsp;Method: POST</p>
</li>
</ul>
<p>Now we have that figured out, we can start organizing the routes into modules.</p>
<h2>Creating the modules</h2>
<p>I think it&#8217;s probably easier to split the routes into multiple modules. I think we will need five:</p>
<ol>
<li>One for the homepage</li>
<li>One for the photo&#8217;s</li>
<li>One for the archives</li>
<li>One for the admin stuff</li>
<li>A base class to provide common functionality to the other modules</li>
</ol>
<h3>The base class</h3>
<p>For now, the base class doesn&#8217;t need to do anything special, but as soon as we start working with the database it will come in handy. Let&#8217;s create the base class first so all other modules are future proof.</p>
<p>Create a new directory in the root of the project and call it <em>Modules</em>. Add a new class called <em>PhotoblogModule</em> to that new directory. Make the class <code>abstract</code>, let it inherit from <code>NancyModule</code> and add the following code to the class:</p>
<pre class="brush:c-sharp">
public abstract class PhotoblogModule : NancyModule
{
	public PhotoblogModule() : base()
	{

	}

	public PhotoblogModule(string modulePath) : base(modulePath)
	{

	}
}
</pre>
<p>This gives us two constructors. We&#8217;ve already used the default parameterless constructor in the first post. The second constructor however is new. It accepts one parameter called <code>modulePath</code> and we&#8217;ll see what that does in just a moment.
</p>
<h3>The homepage module</h3>
<p>
Add another class to the <em>Modules</em> directory and call it <em>RootModule</em>. Let it inherit from the <code>PhotoblogModule</code> class we just made and the one route it should support:</p>
<pre class="brush:c-sharp">
public class RootModule : PhotoblogModule
{
	public RootModule() : base()
	{
		Get["/"] = parameters =>
		{
			return "Homepage";
		};
	}
}
</pre>
</p>
<h3>The photo module</h3>
<p>Just like before, add a new class to the <em>Modules</em> directory, call it <em>PhotoModule</em>, let it inherit from <code>PhotoblogModule</code> as well and add the two routes it needs to take care of:</p>
<pre class="brush:c-sharp">
using Nancy;

public class PhotoModule : PhotoblogModule
{
	public PhotoModule() : base("/photo")
	{
		Get["/{slug}"] = parameters =>
		{
			return String.Format("Photo '{0}'", parameters.slug);
		};

		Post["/{slug}/addcomment"] = parameters =>
		{
			string photoSlug = Convert.ToString(parameters.slug);
			return Response.AsRedirect("/photo/" + photoSlug);
		};
	}
}
</pre>
<p>Did you see how we are calling <code>base("/photo")</code>? That&#8217;s the second constructor of our <code>PhotoblogModule</code> class. The <code>modulePath</code> parameter makes sure that all routes specified in the <code>Get[]</code> and <code>Post[]</code> indexers are <em>relative</em> to the modulePath. So when we add <code>Get["/{slug}"]</code>, we are actually adding <code>Get["/photo/{slug}"]</code>.
</p>
<h3>The archives module</h3>
<p>Again, add a new class to the <em>Modules</em> directory, call it <em>ArchivesModule</em>, let it inherit from <code>PhotoblogModule</code> as well and add the routes it needs to handle:</p>
<pre class="brush:c-sharp">
public class ArchivesModule : PhotoblogModule
{
	public ArchivesModule() : base("/archives")
	{
		Get[""] = parameters =>
		{
			return "All photo's of all years and months.";
		};

		Get["/{year}"] = parameters =>
		{
			return String.Format("All photo's of the year {0}",
				parameters.year);
		};

		Get["/{year}/{month}"] = parameters =>
		{
			return String.Format("All photo's of month {0} of the year {1}",
				parameters.month,
				parameters.year);
		};
	}
}
</pre>
<p>See how we used the second constructor again to specify a modulePath?
</p>
<h3>The admin module</h3>
<p>The last one! Add another class to the <em>Modules</em> directory, call it <em>AdminModule</em>, let it inherit from <code>PhotoblogModule</code> as well and add these routes:</p>
<pre class="brush:c-sharp">
public class AdminModule : PhotoblogModule
{
	public AdminModule() : base("/admin")
	{
		Get[""] = parameters =>
		{
			return "Display the login form.";
		};

		Post["/login"] = parameters =>
		{
			// Perform validation, then redirect
			return Response.AsRedirect("/admin/photos");
		};

		Get["/photos"] = parameters =>
		{
			return "A list of all the photo's.";
		};

		Get["/photos/add"] = parameters =>
		{
			return "Display the form to add a photo.";
		};

		Post["/photos/add"] = parameters =>
		{
			// Add the photo, then redirect
			string slug = "newPhoto";
			return Response.AsRedirect("/admin/photos/edit/" + slug);
		};

		Get["/photos/edit/{slug}"] = parameters =>
		{
			return String.Format("Display the form to edit a photo called '{0}'.",
				parameters.slug);
		};

		Post["/photos/edit/{slug}"] = parameters =>
		{
			// Edit the photo, then redirect
			string slug = Convert.ToString(parameters.slug);
			return Response.AsRedirect("/admin/photos/edit/" + slug);
		};

		Get["/comments"] = parameters =>
		{
			return "A list of all the comments.";
		};

		Post["/comments/delete/{id}"] = parameters =>
		{
			// Delete the comment, then redirect
			return Response.AsRedirect("/admin/comments");
		};
	}
}
</pre>
<p>There. That was the last of our modules.
</p>
<h2>Wrapping things up</h2>
<p><img src="http://www.kristofclaes.be/wp-content/uploads/02-01-ProjectStructure.png" alt="The project structure" title="02-01-ProjectStructure" width="293" height="287" class="alignright size-full wp-image-444" />Now that we have our five modules in the <em>Modules</em> directory, we can delete the <em>MainModule.cs</em> we created in the first post since we won&#8217;t be needing it anymore. All modules and routing information are nicely grouped in the <em>Modules</em> directory. Our project now looks like the one on the right.</p>
<p>The changes to source code can be found on <a href="https://github.com/kristofclaes/MyPhotoBlog/tree/BlogPost2">Github</a>.</p>
<p>In the next post we&#8217;ll try to replace those temporarily returned strings with Razor views.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.kristofclaes.be/blog/2011/04/04/building-a-photoblog-with-nancy-and-simple-data-part-2-defining-the-routes/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Building a photoblog with Nancy and Simple.Data Part 1: Setting up the project</title>
		<link>http://www.kristofclaes.be/blog/2011/04/03/building-a-photoblog-with-nancy-and-simple-data-part-1-setting-up-the-project/</link>
		<comments>http://www.kristofclaes.be/blog/2011/04/03/building-a-photoblog-with-nancy-and-simple-data-part-1-setting-up-the-project/#comments</comments>
		<pubDate>Sun, 03 Apr 2011 18:31:46 +0000</pubDate>
		<dc:creator>Kristof</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[MyPhotoBlog]]></category>
		<category><![CDATA[nancy]]></category>
		<category><![CDATA[simple.data]]></category>

		<guid isPermaLink="false">http://www.kristofclaes.be/?p=372</guid>
		<description><![CDATA[This is the first part in my Building a photoblog with Nancy and Simple.Data series: Setting up the project Defining the routes Rendering some views Adding the database Updating Simple.Data Adding comments The archives As an amateur photographer, I&#8217;m currently &#8230; <a href="http://www.kristofclaes.be/blog/2011/04/03/building-a-photoblog-with-nancy-and-simple-data-part-1-setting-up-the-project/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>This is the first part in my <em>Building a photoblog with Nancy and Simple.Data</em> series:</p>
<ol>
<li>Setting up the project</li>
<li><a href="http://www.kristofclaes.be/blog/2011/04/04/building-a-photoblog-with-nancy-and-simple-data-part-2-defining-the-routes/">Defining the routes</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/04/09/building-a-photoblog-with-nancy-and-simple-data-part-3-rendering-some-views/">Rendering some views</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/04/16/building-a-photoblog-with-nancy-and-simple-data-part-4-adding-the-database/">Adding the database</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/05/02/building-a-photoblog-with-nancy-and-simple-data-part-5-updating-simple-data/">Updating Simple.Data</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/06/25/building-a-photoblog-with-nancy-and-simple-data-part-5-adding-comments/">Adding comments</a></li>
<li><a href="http://www.kristofclaes.be/blog/2011/07/29/building-a-photoblog-with-nancy-and-simple-data-part-7-the-archives/">The archives</a></li>
</ol>
<p>As an amateur photographer, I&#8217;m currently running a <a href="http://foto.kristofclaes.be/" target="_blank">photoblog</a> based on WordPress. While that&#8217;s working just fine, I have a feeling that WordPress is a bit too over-featured for a simple photoblog. Since I&#8217;m not only an amateur photographer but also a professional web developer, I have the perfect excuse to build very own little photoblog!</p>
<p>As a .NET developer, the evident choice would be between ASP.NET WebForms or ASP.NET MVC. If those two would be my only options, I would pick MVC without a doubt, but there are some other, open source, options. One of them is called <a href="https://github.com/NancyFX/Nancy">Nancy</a> and it&#8217;s been getting quite a lot of attention lately.</p>
<p>For data access I could go with a nice ORM like NHibernate or Entity Framework, but if WordPress is overkill for a photoblog, then NHibernate and Entity Framework are triple overkill. Instead I&#8217;ll go with another open source alternative: <a href="https://github.com/markrendle/Simple.Data">Simple.Data</a>.</p>
<p>Both Nancy and Simple.Data claim to be lightweight and easy to work with. In this series of blog posts, I&#8217;m going to describe my experiences with them while building my photoblog.</p>
<h2>Creating the solution in Visual Studio</h2>
<p>As far as I know, the easiest way to get started with Nancy is to create a new empty ASP.NET Web Application. So start Visual Studio, click <em>File > New Project&#8230;</em>, select the <em>ASP.NET Empty Web Application</em> template, enter a name for the project (I&#8217;m bad with names, so I&#8217;ve chosen MyPhotoBlog), make sure that <em>Create directory for solution</em> is checked and click <em>OK</em>.<br />
<a href="http://www.kristofclaes.be/wp-content/uploads/01-01-NewProject.png"><img src="http://www.kristofclaes.be/wp-content/uploads/01-01-NewProject-610x421.png" alt="Create a new project" title="01-01-NewProject" width="610" height="421" class="alignnone size-medium wp-image-380" /></a></p>
<p>This gives a nice clean base to start from. Now we need to add references to the necessary Nancy and Simple.Data libraries.</p>
<h2>Adding Simple.Data</h2>
<p>Adding Simple.Data is easy. All we need is available through NuGet. Just fire up the <em>Package Manager Console</em>, enter <code>Install-Package Simple.Data.SqlCompact40</code> and press enter. This will add the <code>Simple.Data.SqlCompact40</code> library, but also the <code>Simple.Data.Core</code> library since that last one is listed as a dependency. You will also notice that some Rx (Reactive Extensions) libraries are added as well. Isn&#8217;t NuGet awesome?</p>
<h2>Adding Nancy</h2>
<p>The different Nancy functionalities are split up in multiple libraries and unfortunately, not all of them are available through NuGet. So to add Nancy, we will download the source from Github, build it manually and copy the required libraries over to our solution.</p>
<ol>
<li>Go to <a href="https://github.com/NancyFX/Nancy">the Nancy repository on Github</a> and download the source. Of course you can also fork the project pull everything in using Git.</li>
<li>If you have Ruby 1.8.7 or later installed, you can just run the <code>rake</code> command in the Nancy directory. This will run all unit tests, build all projects and put the libraries in a build directory. If you don&#8217;t have Ruby installed you can also open the Nancy.sln file in Visual Studio and build everything manually. Either way, you end up with a lot of dll-files.</li>
<li>Open the directory of the photoblog project in Windows Explorer and create a new directory called <em>Libs</em>. Copy these Nancy libraries to the Libs directory: Nancy.dll, Nancy.Hosting.Aspnet.dll and Nancy.ViewEngines.Razor.dll.<br />
<a href="http://www.kristofclaes.be/wp-content/uploads/01-02-LibsFolder.png"><img src="http://www.kristofclaes.be/wp-content/uploads/01-02-LibsFolder-610x495.png" alt="Directory structure" title="01-02-LibsFolder" width="610" height="495" class="alignnone size-medium wp-image-391" /></a></li>
<li>Add the three libraries as a reference to your photoblog project in Visual Studio. <img src="http://www.kristofclaes.be/wp-content/uploads/01-03-AddReferences.png" alt="Add the Nancy references" title="01-03-AddReferences" width="482" height="408" class="alignnone size-full wp-image-390" /></li>
</ol>
<h2>Configuring Nancy</h2>
<p>Nancy can be configured using some Web.Config settings. To enable the default configuration, which is OK for this project I believe, just modify your Web.Config file so that it looks like this:</p>
<pre class="brush:xml">
&lt;?xml version="1.0"?>
&lt;configuration>
    &lt;system.web>
        &lt;compilation debug="true" targetFramework="4.0" />
        &lt;httpHandlers>
            &lt;add verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*"/>
        &lt;/httpHandlers>
    &lt;/system.web>

    &lt;system.webServer>
        &lt;modules runAllManagedModulesForAllRequests="true"/>
        &lt;validation validateIntegratedModeConfiguration="false"/>
        &lt;handlers>
            &lt;add name="Nancy" verb="*" type="Nancy.Hosting.Aspnet.NancyHttpRequestHandler" path="*"/>
        &lt;/handlers>
    &lt;/system.webServer>
&lt;/configuration>
</pre>
<p>That&#8217;s all there is to it! Nancy is ready to go!
</p>
<h2>Adding our first NancyModule</h2>
<p>If we would have used ASP.NET MVC, we would now need to setup routing in the Global.asax file, create at least one Controller class with at least one Action method and make sure that the Action method corresponds to a route. Using Nancy, it all becomes a little simpler. A <code>NancyModule</code> class replaces the Controller, and the Action method and route become integrated into that <code>NancyModule</code>.</p>
<p>To end this first post, we&#8217;ll create such a <code>NancyModule</code> to verify that everything is working correctly (Simple.Data excluded, well get to that later).</p>
<p>Add a class to the root of your project. I&#8217;ve called mine <em>MainModule</em>.</p>
<p> Let the class inherit from <code>NancyModule</code> (located in the <code>Nancy</code>-namespace):</p>
<pre class="brush:c-sharp">
public class MainModule : NancyModule
{
    public MainModule()
    {
    }
}
</pre>
</p>
<p>Now we&#8217;ll make sure that the root URL (&#8220;/&#8221;) returns something to the browser. Adjust the class so that it looks like this:</p>
<pre class="brush:c-sharp">
public class MainModule : NancyModule
{
	public MainModule()
	{
		Get["/"] = parameters =>
		{
			return "&lt;h1>Welcome to My Photoblog!&lt;/h1>&lt;p>Nothing to see here at the moment.&lt;/p>";
		};
	}
}
</pre>
<p>That&#8217;s doing exactly what it looks like: it is telling Nancy to listing to incoming GET-requests corresponding to &#8220;/&#8221; and telling it to return a string of text to the browser. Don&#8217;t believe me? Press CTRL+F5 and be amazed!<br />
<img src="http://www.kristofclaes.be/wp-content/uploads/01-04-Browser1-610x495.png" alt="It works!" title="01-04-Browser1" width="610" height="495" class="alignnone size-medium wp-image-398" />
</p>
<p>Now let&#8217;s add another route. Let&#8217;s add one with a parameter! Modify the class so that it looks like this:</p>
<pre class="brush:c-sharp">
public class MainModule : NancyModule
{
	public MainModule()
	{
		Get["/"] = parameters =>
		{
			return "&lt;h1>Welcome to My Photoblog!&lt;/h1>&lt;p>Nothing to see here at the moment.&lt;/p>";
		};

		Get["/photo/{slug}"] = parameters =>
		{
			return String.Format("&lt;h1>I'm sorry&lt;/h1>&lt;p>We're having some problems finding photo '{0}' for the moment.&lt;/p>", parameters.slug);
		};
	}
}
</pre>
<p>What do you think that this will do? Correct! It tells Nancy to listen for incoming GET-requests starting with &#8220;/photo/&#8221; followed by anything. Because we have defined it as <code>{slug}</code>, whatever comes behind the &#8220;/photo/&#8221; part, gets put in the <code>slug</code> property of the <code>parameters</code> variable. See how we pass it to the <code>String.Format()</code> method? It all works dynamically! To see this in action, just surf to &#8220;/photo/big-dog&#8221; for example. Isn&#8217;t that awesome?<br />
<img src="http://www.kristofclaes.be/wp-content/uploads/01-05-Browser2-610x495.png" alt="That&#039;s too bad. I really wanted to see a big dog..." title="01-05-Browser2" width="610" height="495" class="alignnone size-medium wp-image-400" /></p>
<h2>Conclusion</h2>
<p>That&#8217;s it for the first post of the series. As you have seen it is really <em>really</em> easy to start using Nancy. From what I&#8217;ve read, using Simple.Data is equally easy, but we&#8217;ll save that for a future post.</p>
<p>In the next post, we&#8217;ll think about what we want our photoblog to do and add all the routes we&#8217;ll need for that.</p>
<h2>Interesting links</h2>
<ul>
<li><a href="https://github.com/NancyFX/Nancy">Nancy on Github</li>
<li><a href="http://twitter.com/#!/search/%23nancyfx">Nancy on Twitter</a></li>
<li><a href="https://github.com/markrendle/Simple.Data">Simple.Data on Github</a></li>
<li><a href="https://github.com/kristofclaes/MyPhotoBlog/tree/BlogPost1">The source code for this post of MyPhotoBlog on Github</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.kristofclaes.be/blog/2011/04/03/building-a-photoblog-with-nancy-and-simple-data-part-1-setting-up-the-project/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
	</channel>
</rss>

