<?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>Gojko Adzic &#187; monorail</title>
	<atom:link href="http://gojko.net/tag/monorail/feed/" rel="self" type="application/rss+xml" />
	<link>http://gojko.net</link>
	<description>Building software that matters</description>
	<lastBuildDate>Wed, 04 Aug 2010 11:38:56 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Introducing Alt.NET courses at Skills Matter</title>
		<link>http://gojko.net/2008/12/22/introducing-altnet-courses-at-skills-matter/</link>
		<comments>http://gojko.net/2008/12/22/introducing-altnet-courses-at-skills-matter/#comments</comments>
		<pubDate>Mon, 22 Dec 2008 08:42:35 +0000</pubDate>
		<dc:creator>gojko</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[alt.net]]></category>
		<category><![CDATA[altdotnet]]></category>
		<category><![CDATA[castle]]></category>
		<category><![CDATA[cruise control]]></category>
		<category><![CDATA[monorail]]></category>
		<category><![CDATA[mvc]]></category>
		<category><![CDATA[nhibernate]]></category>
		<category><![CDATA[orm]]></category>
		<category><![CDATA[rhino mocks]]></category>
		<category><![CDATA[scriptsharp]]></category>
		<category><![CDATA[selenium]]></category>
		<category><![CDATA[skillsmatter]]></category>

		<guid isPermaLink="false">http://gojko.net/?p=555</guid>
		<description><![CDATA[From February 2009, Skills Matter will start organising public Alt.NET courses (first in London and then across Europe). Opensource .NET tools crash course The first will be a three-day crash course on tools and practices aimed at .NET developers that want to learn about Alt.NET tools and Java developers that are migrating to .NET and [...]]]></description>
			<content:encoded><![CDATA[<p>From February 2009, Skills Matter will start organising public Alt.NET courses (first in London and then across Europe). </p>
<h2>Opensource .NET tools crash course</h2>
<p>The first will be <a href="http://skillsmatter.com/course/open-source-dot-net/opensource-dot-net-tools-crash-course">a three-day crash course</a> on tools and practices aimed at .NET developers that want to learn about Alt.NET tools and Java developers that are migrating to .NET and looking for good equivalents to the tools that they are used to working with. The course gives an overview of the most popular opensource .net tools and introduces modern development practices that these tools promote, such as test driven development, continuous integration, dependency injection, object-relational mapping and web development using the model-view-controller pattern. </p>
<p>Learn how to:</p>
<ul>
<li>Implement TDD in .NET using NUnit, MBUnit, Rhino Mocks and FitNesse</li>
<li>Utilise Aspect oriented programming and Dependency Injection using Castle Windsor</li>
<li>Efficiently build Web applications using the MVC pattern in Monorail and utilising Monorail and Script# for Ajax and test them using Selenium Remote Console.</li>
<li>Manage persistence easily using ORM tools such as ActiveRecord and NHibernate</li>
<li>Introduce continuous integration in your projects using CruiseControl.NET and CI Factory</li>
</ul>
<p>See the <a href="http://skillsmatter.com/course/open-source-dot-net/opensource-dot-net-tools-crash-course">full programme</a>.</p>
<h2>Agile Web Development with the Castle Framework</h2>
<p>The second one is a <a href="http://skillsmatter.com/course/open-source-dot-net/agile-web-development-with-the-castle-framework">two-day course on Agile Web Development using the Castle project</a>, teaching the basics of the Castle Framework and helping people develop a solid understanding of its benefits. Over the course of the two days, attendees will create a simple but complete web application using agile Web development practices such as Inversion of Control, Dependency Injection, Aspect Oriented Programming, Object/Relational Mapping and applying the Model-View-Controller pattern.</p>
<p>Learn how to</p>
<ul>
<li>Apply agile web development practices like MVC and dependency injection</li>
<li>Use ActiveRecord to manage the object-relational mapping and the database layer</li>
<li>Use the Monorail MVC engine to create web applications that are easy to maintain and test</li>
<li>Explain the basics of Monorail views, layouts, rescues</li>
<li>Use the NVelocity view engine to build web UIs for Monorail</li>
<li>Apply Windsor Microkernel to configure and wire application components</li>
<li>Unit test the data access layer with Castle</li>
<li>Unit test web controllers</li>
<li>Describe how Castle components come together to help us develop web applications easier</li>
<li>Explain why this approach is much more effective than ASP.NET</li>
<li>Apply best practices, common pitfalls, and tips and tricks for Castle Web development</li>
</ul>
<p>See the <a href="http://skillsmatter.com/course/open-source-dot-net/agile-web-development-with-the-castle-framework">full programme</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://gojko.net/2008/12/22/introducing-altnet-courses-at-skills-matter/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Video: Developing Ajax Web Applications with Castle Monorail</title>
		<link>http://gojko.net/2008/07/18/video-developing-ajax-web-applications-with-castle-monorail/</link>
		<comments>http://gojko.net/2008/07/18/video-developing-ajax-web-applications-with-castle-monorail/#comments</comments>
		<pubDate>Fri, 18 Jul 2008 20:11:57 +0000</pubDate>
		<dc:creator>gojko</dc:creator>
				<category><![CDATA[presentations]]></category>
		<category><![CDATA[tutorials]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[alt.net]]></category>
		<category><![CDATA[castle]]></category>
		<category><![CDATA[monorail]]></category>
		<category><![CDATA[web 2.0]]></category>

		<guid isPermaLink="false">http://gojko.net/?p=152</guid>
		<description><![CDATA[Here&#8217;s the video from the talk that Dave and I did last month at Skills Matter on developing Ajax Web applications with Castle Monorail. You can download slides and find links from the talk here. (if the video does not load in the embedded player, see it on google video)]]></description>
			<content:encoded><![CDATA[<p><embed id="VideoPlayback" style="width:400px;height:326px;float:left;margin:5px 5px 5px 5px; border: 1px solid black" allowFullScreen="true" src="http://video.google.com/googleplayer.swf?docid=-383418991140556188&#038;hl=en&#038;fs=true" type="application/x-shockwave-flash"></embed>Here&#8217;s the video from the talk that Dave and I did last month at <a href="http://www.skillsmatter.com">Skills Matter</a> on developing Ajax Web applications with Castle Monorail.  You can download slides and find links from the talk <a href="http://gojko.net/2008/06/13/slides-links-and-source-from-the-ajax-monorail-talk/">here</a>. (if the video does not load in the embedded player, see it on <a href="http://video.google.com/videoplay?docid=-383418991140556188" target="_blank">google video</a>)</p>
]]></content:encoded>
			<wfw:commentRss>http://gojko.net/2008/07/18/video-developing-ajax-web-applications-with-castle-monorail/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Slides, links and source from the Ajax Monorail talk</title>
		<link>http://gojko.net/2008/06/13/slides-links-and-source-from-the-ajax-monorail-talk/</link>
		<comments>http://gojko.net/2008/06/13/slides-links-and-source-from-the-ajax-monorail-talk/#comments</comments>
		<pubDate>Fri, 13 Jun 2008 09:57:15 +0000</pubDate>
		<dc:creator>gojko</dc:creator>
				<category><![CDATA[presentations]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[ajax]]></category>
		<category><![CDATA[alt.net]]></category>
		<category><![CDATA[castle]]></category>
		<category><![CDATA[monorail]]></category>

		<guid isPermaLink="false">http://gojko.net/?p=138</guid>
		<description><![CDATA[I really enjoyed talking about Developing Ajax web applications with Castle Monorail yesterday at Skills Matter. It was great to see so many familiar faces &#8212; thanks for coming again and I hope that you enjoyed it as well. Here are the downloads and links that Dave and I promised to put online: Downloads PPT [...]]]></description>
			<content:encoded><![CDATA[<p>I really enjoyed talking about <a target="_blank" href="http://skillsmatter.com/podcast/open-source-dot-net/developing-ajax-web-applications-with-castle-monorail">Developing Ajax web applications with Castle Monorail</a> yesterday at Skills Matter. It was great to see so many familiar faces &mdash; thanks for coming again and I hope that you enjoyed it as well. Here are the downloads and links that Dave and I promised to put online:<span id="more-138"></span></p>
<h2>Downloads</h2>
<ul>
<li><a href="/resources/monorail-ajax-20080612.ppt">PPT slides</a></li>
<li><a href="/resources/monorail-ajax-20080612-superpowers.zip">Source code for the SuperPowers app</a> (drag &#038; drop, scriptaculous and prototype effects demo) </li>
<li><a href="/resources/monorail-ajax-20080612-jsondemo.zip">Source code for the JSonDemo app</a> (comparing the three options for ajax with monorail; requires castle trunk DLLs)</li>
</ul>
<h2>Links with more details on the stuff from our talk</h2>
<ul>
<li>Hammett&#8217;s post about <a href="http://hammett.castleproject.org/?p=97" target="_blank">Generating JS commands from actions </a> (option #1 from the PPT). For all available functions in $page helper, see the source code of  <a target="_blank" href='http://svn.castleproject.org:8080/svn/castle/trunk/MonoRail/Castle.MonoRail.Framework/JSGeneration/Prototype/PrototypeGenerator.cs'>PrototypeGenerator.cs</a> and <a target="_blank" href='http://svn.castleproject.org:8080/svn/castle/trunk/MonoRail/Castle.MonoRail.Framework/JSGeneration/Prototype/PrototypeElementGenerator.cs'>PrototypeElementGenerator.cs</a> classes.
</li>
<li>Hammett&#8217;s post on <a target="_blank" href="http://hammett.castleproject.org/?p=247">JSON return binders</a> (option #3 from the PPT)</li>
<li><a href="http://skillsmatter.com/podcast/open-source-dot-net/agile-web-development-with-the-castle-framework">Video </a>, <a href="http://gojko.net/2008/05/15/links-and-slides-from-the-castle-talk/">links and slides</a> from my earlier talk on agile web development with Castle and Monorail</li>
<li><a href="http://gojko.net/tag/castle/">Castle-related articles on this web site</a> including the demo app that explains how to develop monorail controllers and how to unit test them.</li>
</ul>
<h2>Some general links</h2>
<ul>
<li><a target="_blank" href="http://www.castleproject.org/MonoRail">Monorail web site</a>
</li>
<li><a target="_blank" href="http://hammett.castleproject.org">Hammett&#8217;s blog</a> and <a target="_blank" href="http://www.ayende.com/blog">Ayende&#8217;s blog</a> are excellent resources for all stuff about Castle.</li>
<li><a target="_blank" href="http://www.prototypejs.org">Prototype JS library docs</a>
</li>
<li><a target="_blank" href="http://script.aculo.us">Scriptaculous JS library docs</a>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://gojko.net/2008/06/13/slides-links-and-source-from-the-ajax-monorail-talk/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Castle Demo App #4: Unit testing Monorail web sites</title>
		<link>http://gojko.net/2008/06/09/castle-demo-app-4-unit-testing-monorail-web-sites/</link>
		<comments>http://gojko.net/2008/06/09/castle-demo-app-4-unit-testing-monorail-web-sites/#comments</comments>
		<pubDate>Mon, 09 Jun 2008 08:51:13 +0000</pubDate>
		<dc:creator>gojko</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[castle]]></category>
		<category><![CDATA[monorail]]></category>
		<category><![CDATA[testing]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://gojko.net/?p=133</guid>
		<description><![CDATA[One of the best things about Castle Monorail MVC engine is that it allows us to test controllers from the IDE, without actually deploying anything to the web server. A major problem with most web development environments, including classic ASP.NET, is that the workflow and session logic can only be tested through the UI. User [...]]]></description>
			<content:encoded><![CDATA[<p>One of the best things about Castle Monorail MVC engine is that it allows us to test controllers from the IDE, without actually deploying anything to the web server. A major problem with most web development environments, including classic ASP.NET, is that the workflow and session logic can only be tested through the UI. User interface testing is slow, pain to maintain and <a href='http://gojko.net/2007/09/25/effective-user-interface-testing/'>generally does not pay off as much as code unit tests do</a>. Monorail’s programming model allows us to test workflow and session logic from the code, leaving only the actual rendering outside the reach of unit tests. That is how Monorail empowers us to really apply agile principles to web development, and saves us even more time and effort.<span id="more-133"></span></p>
<p>For those of you that have just joined this tutorial, this is the fourth iteration of the EvilLink web application, that I am building as a way to demonstrate features of the Castle Project application framework and to present some of the best practices for web application development using the Castle Project. Previous articles in this tutorials are:</p>
<ul>
<li><a href='http://gojko.net/2008/05/07/castle-demo-app-activerecord-basics-and-unit-testing/'>ActiveRecord basics and unit testing</a></li>
<li><a href='http://gojko.net/2008/05/13/castle-demo-app-2-monorail-basics/'>Monorail basics</a></li>
<li><a href='http://gojko.net/2008/05/26/castle-demo-app-3-saving-time-and-effort-with-advanced-monorail-features/'>Saving time and effort with advanced Monorail features</a></li>
</ul>
<p>So far, we have developed a skeleton of the web application that has user operations and link management functionality. Now we write some unit tests for the controllers. </p>
<p><i>A quick note before we begin. If you are in UK this week, you might want to come to the free session on <a href='http://skillsmatter.com/event/open-source-dot-net/developing-ajax-web-applications-with-castle-monorail'>developing Ajax applications with Monorail that will take place on Thursday (12/06) afternoon at Skills Matter offices in London</a>. This will give us a chance to discuss any questions about this application as well face to face.</i></p>
<h3>Isolating controllers</h3>
<p>The first thing we need to do in order to make our controllers unit testable is to isolate them from any external dependencies, including the System.Web.Http objects. Most of the code that would normally be bound to those objects is handled by Monorail anyway. The only place where System.Web objects are used directly is in the UserContext session wrapper. So let’s replace the UserContext object with an interface and a default implementation. Then we can provide a dummy or mock implementation for unit testing. </p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>using</span><span> System.Web;</span>
<span style='color:blue'>using</span><span> EvilLink.Database;</span>
<span style='color:blue'>namespace</span><span style='font-size: 10.0pt;font-family:"Courier New"'> EvilLink.Controllers</span>
<span>{</span>
<span>    <span style='color:blue'>public</span> <span style='color:blue'>interface</span> <span style='color:teal'>IUserContext</span> {</span>
<span>        <span style='color:blue'>int</span>? CurrentUserId { <span style='color:blue'>get</span>; <span style='color:blue'>set</span>;}</span>
<span>        <span style='color:teal'>User</span> CurrentUser { <span style='color:blue'>get</span>; }</span>
<span>    }</span>
<span>    <span style='color:blue'>public</span> <span style='color:blue'>class</span> <span style='color:teal'>WebUserContext</span>:<span style='color:teal'>IUserContext</span> </span>
<span>    {</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>int</span>? CurrentUserId</span>
<span>        {</span>
<span>            <span style='color:blue'>get</span></span>
<span>            { </span>
<span>              <span style='color:blue'>return</span> System.Web.<span style='color:teal'>HttpContext</span>.Current.Session[<span style='color:maroon'>&quot;currentUserId&quot;</span>]</span>
<span>               <span style='color:blue'>as</span> <span style='color:blue'>int</span>?; </span>
<span>            }</span>
<span>            <span style='color:blue'>set</span></span>
<span>            { </span>
<span>              System.Web.<span style='color:teal'>HttpContext</span>.Current.Session[<span style='color:maroon'>&quot;currentUserId&quot;</span>] = <span style='color:blue'>value</span>;</span>
<span>            }</span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> <span style='color:teal'>User</span> CurrentUser</span>
<span>        {</span>
<span>            <span style='color:blue'>get</span> { <span style='color:blue'>return</span> <span style='color:teal'>User</span>.Find(CurrentUserId); }</span>
<span>        }</span>
<span>    }</span>
<span>}</span>
</pre>
</div>
<p>Now we have to propagate this change to the controllers. Change the field type to IUserContext and create two constructors. The no-parameter constructor will automatically set the default implementation so that our application continues to work as before, but we can also set the context from the outside using the constructor with a parameter.</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>public</span><span> <span style='color:blue'>class</span> <span style='color:teal'>UserOpsController</span> : <span style='color:teal'>SmartDispatcherController</span></span>
<span>{</span>
<span>    <span style='color:blue'>private</span> <span style='color:teal'>IUserContext</span> context;        </span>
<span>    <span style='color:blue'>public</span> UserOpsController(){</span>
<span>        context=<span style='color:blue'>new</span> <span style='color:teal'>WebUserContext</span>();</span>
<span>    }</span>
<span>    <span style='color:blue'>public</span> UserOpsController(<span style='color:teal'>IUserContext</span> ctx)</span>
<span>    {</span>
<span>        context = ctx;</span>
<span>    }</span>
</pre>
</div>
<p>This is how we would mock out any external services that controllers may be connecting to or other stuff that prevents unit testing. At the moment, the controllers are still tied to the default implementation with a compile-time dependency. In the next article of this tutorial we look into better ways to handle that, using the Windsor dependency injection container.</p>
<h3>Completely detaching from the real Web</h3>
<p>Now create a new project in the solution, called EvilLink.Controllers.Test. Add references to Castle.ActiveRecord, Castle.Monorail.Framework, Castle.Monorail.TestSupport, NHibernate and nunit.framework DLLs. Also add references to EvilLink.Controllers, EvilLink.Database and EvilLink.Database.Test projects that we have developed so far. This new project will host our controller unit tests. </p>
<p>The Castle.Monorail.TestSupport library has almost all the support we need to unit test controllers. It provides us with a mock HTTP environment implementation that allows controllers to execute and be inspected in the code. Class BaseControllerTest does all the heavy lifting, we just need to subclass it and call PrepareController to initialize the controller. Then we can execute any of the controller methods directly and verify the effects on the domain or check controller properties to verify messages or objects prepared for rendering. All subclasses of SmartDispatcherController have a public Context property that allows us to inspect the Rails engine context as well. </p>
<p>There is just one slight problem with the BaseControllerTest. All its interesting methods are protected, so the test class has to subclass BaseControllerTest. It would be ideal to reuse the unit testing support for the data access layer that we developed in <a href='http://gojko.net/2008/05/07/castle-demo-app-activerecord-basics-and-unit-testing/'>the first article</a>, but C# does not support multiple inheritance. A workaround for that is to extend BaseControllerTest once, expose appropriate methods as public, and then embed that into another test class that initialises the data access system. Here is MRTestBase class that provides all the functionality of ARTestBase and also allows us to initialise controllers for testing:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>using</span><span> EvilLink.Database.Test;</span>
<span style='color:blue'>using</span><span> Castle.MonoRail.TestSupport;</span>
<span style='color:blue'>using</span><span> Castle.MonoRail.Framework;</span>
<span style='color:blue'>namespace</span><span style='font-size: 10.0pt;font-family:"Courier New"'> EvilLink.Controllers.Test</span>
<span>{</span>
<span>    <span style='color:blue'>public</span> <span style='color:blue'>class</span> <span style='color:teal'>ConcreteControllerTest</span>:<span style='color:teal'>BaseControllerTest</span>{</span>
<span>        <span style='color:green'>// just expose PrepareController as a public method</span></span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> InitController(<span style='color:teal'>Controller</span> controller)</span>
<span>          {           </span>
<span>            PrepareController(controller);</span>
<span>          }</span>
<span>    }</span>
<span>    <span style='color:blue'>public</span> <span style='color:blue'>class</span> <span style='color:teal'>MRTestBase</span>:<span style='color:teal'>ARTestBase</span></span>
<span>    {</span>
<span>        <span style='color:blue'>private</span> <span style='color:teal'>ConcreteControllerTest</span> context = <span style='color:blue'>new</span> <span style='color:teal'>ConcreteControllerTest</span>();</span>
<span>        <span style='color:green'>// expose InitController</span></span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> InitController(<span style='color:teal'>Controller</span> controller)</span>
<span>        {</span>
<span>            context.InitController(controller);</span>
<span>        }</span>
<span>    }</span>
<span>}</span>
</pre>
</div>
<p>We can use a dummy implementation of the user context, not tied to the real HttpSession object, to verify the session storage (this would be a good place to use a mock factory).</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>using</span><span> EvilLink.Database;</span>
<span style='color:blue'>namespace</span><span style='font-size: 10.0pt;font-family:"Courier New"'> EvilLink.Controllers.Test</span>
<span>{</span>
<span>    <span style='color:blue'>public</span> <span style='color:blue'>class</span> <span style='color:teal'>DummyUserContext</span>:<span style='color:teal'>IUserContext</span></span>
<span>    {</span>
<span>        <span style='color:blue'>private</span> <span style='color:blue'>int</span>? currentuserid;</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>int</span>? CurrentUserId</span>
<span>        {</span>
<span>            <span style='color:blue'>get</span> { <span style='color:blue'>return</span> currentuserid; }</span>
<span>            <span style='color:blue'>set</span> { currentuserid = <span style='color:blue'>value</span>; }</span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> <span style='color:teal'>User</span> CurrentUser</span>
<span>        {</span>
<span>            <span style='color:blue'>get</span> { <span style='color:blue'>return</span> currentuserid == <span style='color:blue'>null</span> ? </span>
<span>                <span style='color:blue'>null</span> : <span style='color:teal'>User</span>.Find(currentuserid); }</span>
<span>        }</span>
<span>    }</span>
<span>}</span>
</pre>
</div>
<h3>Writing NUnit tests</h3>
<p>We can now write a couple of unit tests inspecting the workflow and session behaviour of the user operations controller. In the setup, we initialise context objects, create a user to play with and prepare the controller. Notice that we just call the constructor and then pass the object to PrepareController and that is it &mdash; no black magic involved. We can call the login method and then inspect the user context to check whether the expected user object was stored in the session. We can also try to log in with an incorrect password and verify the message coming out (hint: PropertyBag is a public property of the controller, so we can inspect it directly). The SelectedViewName property will give us a way to check which view was selected for rendering. We can verify that the controller initiated redirection by checking Context.Response.WasRedirected property, but I don’t know of a good way to verify redirection URL at the moment. Jimmy Bogard <a href='http://www.lostechies.com/blogs/jimmy_bogard/archive/2008/02/18/unit-testing-monorail-controllers-redirects.aspx'>explored some options for that like changing the redirect method</a>. Apart from that, we can easily test everything else:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>using</span><span> EvilLink.Database.Test;</span>
<span style='color:blue'>using</span><span> NUnit.Framework;</span>
<span style='color:blue'>using</span><span> EvilLink.Database;</span>
<span style='color:blue'>using</span><span> Castle.MonoRail.TestSupport;</span>
<span>&nbsp;</span>
<span style='color:blue'>namespace</span><span style='font-size: 10.0pt;font-family:"Courier New"'> EvilLink.Controllers.Test</span>
<span>{</span>
<span>    [<span style='color:teal'>TestFixture</span>]</span>
<span>    <span style='color:blue'>public</span> <span style='color:blue'>class</span> <span style='color:teal'>TestUserOps</span>:<span style='color:teal'>MRTestBase</span></span>
<span>    {</span>
<span>        <span style='color:teal'>DummyUserContext</span> wuc;</span>
<span>        <span style='color:teal'>UserOpsController</span> ops;</span>
<span>        <span style='color:teal'>User</span>  mike;</span>
<span>        [<span style='color:teal'>SetUp</span>]</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>override</span> <span style='color:blue'>void</span> SetUp()</span>
<span>        {</span>
<span>            <span style='color:blue'>base</span>.SetUp();</span>
<span>            wuc = <span style='color:blue'>new</span> <span style='color:teal'>DummyUserContext</span>();</span>
<span>            ops = <span style='color:blue'>new</span> <span style='color:teal'>UserOpsController</span>(wuc);</span>
<span>            InitController(ops);            </span>
<span>            mike = <span style='color:blue'>new</span> <span style='color:teal'>User</span>(<span style='color:maroon'>&quot;mike&quot;</span>, <span style='color:maroon'>&quot;mike&quot;</span>, <span style='color:maroon'>&quot;mpass&quot;</span>, <span style='color:maroon'>&quot;m@m.com&quot;</span>);</span>
<span>            mike.SaveAndFlush();</span>
<span>        }</span>
<span>        [Test]</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> TestLogin()</span>
<span>        {</span>
<span>            ops.Login(<span style='color:maroon'>&quot;mike&quot;</span>, <span style='color:maroon'>&quot;mpass&quot;</span>, <span style='color:maroon'>&quot;/home&quot;</span>);          </span>
<span>            <span style='color:teal'>Assert</span>.AreEqual(mike, wuc.CurrentUser);           </span>
<span>        }</span>
<span>        [Test]</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> TestLoginIncorrectPassword()</span>
<span>        {</span>
<span>            ops.Login(<span style='color:maroon'>&quot;mike&quot;</span>, <span style='color:maroon'>&quot;wrongpass&quot;</span>, <span style='color:maroon'>&quot;/home&quot;</span>);</span>
<span>            <span style='color:teal'>Assert</span>.AreEqual(<span style='color:blue'>null</span>, wuc.CurrentUser);           </span>
<span>            <span style='color:teal'>Assert</span>.AreEqual(<span style='color:maroon'>&quot;Username or password incorrect, please try again&quot;</span>,</span>
<span>                   ops.PropertyBag[<span style='color:maroon'>&quot;error&quot;</span>]);</span>
<span>            <span style='color:teal'>Assert</span>.AreEqual(ops.Name+<span style='color:maroon'>&quot;\\index&quot;</span>, ops.SelectedViewName);</span>
<span>            <span style='color:teal'>Assert</span>.AreEqual(<span style='color:maroon'>&quot;/home&quot;</span>, ops.PropertyBag[<span style='color:maroon'>&quot;goBackUrl&quot;</span>]);            </span>
<span>        }</span>
<span>        [Test]</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> TestRegisterUser()</span>
<span>        {</span>
<span>            ops.SubmitRegistration(</span>
<span>              <span style='color:blue'>new</span> <span style='color:teal'>User</span>(<span style='color:maroon'>&quot;tom&quot;</span>, <span style='color:maroon'>&quot;tsmith&quot;</span>, <span style='color:maroon'>&quot;tpass&quot;</span>, <span style='color:maroon'>&quot;t@t.com&quot;</span>));</span>
<span>            <span style='color:teal'>Assert</span>.AreEqual(</span>
<span>             <span style='color:maroon'>&quot;You have registered successfully. You can now log in.&quot;</span>,</span>
<span>                ops.Context.Flash[<span style='color:maroon'>&quot;message&quot;</span>]);</span>
<span>            <span style='color:teal'>Assert</span>.AreEqual(<span style='color:blue'>true</span>, ops.Context.Response.WasRedirected);</span>
<span>            <span style='color:teal'>User</span> u=<span style='color:teal'>User</span>.FindAllByProperty(<span style='color:maroon'>&quot;Username&quot;</span>, <span style='color:maroon'>&quot;tsmith&quot;</span>)[0];</span>
<span>            <span style='color:teal'>Assert</span>.AreEqual(<span style='color:maroon'>&quot;tom&quot;</span>, u.Name);</span>
<span>            <span style='color:teal'>Assert</span>.AreEqual(<span style='color:maroon'>&quot;t@t.com&quot;</span>, u.Email);</span>
<span>        }</span>
<span>    }</span>
<span>}</span>
</pre>
</div>
<p>Build the project, fire up your NUnit test runner, and you should see the tests pass:</p>
<p><img src='/images/nunit-ctrl-small.png'/></p>
<h3>Some links for the end</h3>
<ul>
<li><a href='/resources/EvilLink_i4.zip'>Source code for this iteration</a></li>
<li><a href='http://using.castleproject.org/display/MR/TDDingControllers' target='_blank'>More detailed information about BaseControllerTest</a></li>
<li><a href='http://castleproject.org/monorail/documentation/v1rc2/usersguide/testing.html' target='_blank'>Older library for testing, that works by simulating complete http requests and responses. </a></li>
</ul>
<h3>Stuff to remember</h3>
<ul>
<li>BaseControllerTest class from Castle.Monorail.TestSupport provides a framework to unit test controllers.</li>
<li>Just create the controller as any other object and pass it to the PrepareController method of BaseControllerTest to be able to call its methods directly</li>
<li>SmartDispatcherController exposes almost everything interesting to verify as public properties, including SelectedView, PropertyBag and Context.</li>
</ul>
<h3>Next exercise</h3>
<p>In the next article of this tutorial, we look into injecting services and configuration into controllers using the Windsor dependency injection framework. That article should be online soon. (Subscribe to <a href='http://gojko.net/feed/'>RSS updates</a> to get notified about that). As I mentioned above, if you are in UK, come to the free session on <a href='http://skillsmatter.com/event/open-source-dot-net/developing-ajax-web-applications-with-castle-monorail'>developing Ajax applications with Monorail that will take place on Thursday 12th</a> to learn more about what Castle can do for you.</p>
]]></content:encoded>
			<wfw:commentRss>http://gojko.net/2008/06/09/castle-demo-app-4-unit-testing-monorail-web-sites/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Castle Demo App #3: Saving time and effort with advanced Monorail features</title>
		<link>http://gojko.net/2008/05/26/castle-demo-app-3-saving-time-and-effort-with-advanced-monorail-features/</link>
		<comments>http://gojko.net/2008/05/26/castle-demo-app-3-saving-time-and-effort-with-advanced-monorail-features/#comments</comments>
		<pubDate>Mon, 26 May 2008 17:36:40 +0000</pubDate>
		<dc:creator>gojko</dc:creator>
				<category><![CDATA[articles]]></category>
		<category><![CDATA[.net]]></category>
		<category><![CDATA[activerecord]]></category>
		<category><![CDATA[c#]]></category>
		<category><![CDATA[castle]]></category>
		<category><![CDATA[monorail]]></category>
		<category><![CDATA[web]]></category>

		<guid isPermaLink="false">http://gojko.net/?p=131</guid>
		<description><![CDATA[In the third part of the Castle tutorial, we look into the features of Monorail that allow us to save a lot of time and effort when developing web applications. We explore advanced Monorail concepts that help us delegate error processing and authentication to the framework and reuse templates. We also look into how Monorail [...]]]></description>
			<content:encoded><![CDATA[<p>In the third part of the Castle tutorial, we look into the features of Monorail that allow us to save a lot of time and effort when developing web applications. We explore advanced Monorail concepts that help us delegate error processing and authentication to the framework and reuse templates. We also look into how Monorail integrates nicely with ActiveRecord to automatically load and modify database objects based on HTML forms.<span id="more-131"></span></p>
<p>For those of you that have just joined this tutorial, this is the third iteration of the EvilLink web application. <a href='http://gojko.net/2008/05/07/castle-demo-app-activerecord-basics-and-unit-testing/'>In the first iteration</a>, we used basic features of ActiveRecord to set up a domain model and back it with a database. <a href='http://gojko.net/2008/05/13/castle-demo-app-2-monorail-basics/'>In the second iteration</a>, we created a basic web site using Monorail that allowed users to register and log in. If you have not worked with Monorail or ActiveRecord before, read those two articles before continuing with this one. </p>
<p>A quick note before we begin. Hammett from the Castle project was kind enough to correct me about ActiveRecord and mixing domain logic with storage. It turns out that there is a nice way to implement the repository pattern with ActiveRecord directly. Read about the ActiveRecord Mediator that allows that in <a href='http://hammett.castleproject.org/?p=287' target='_blank'>this post</a> (including the comments). </p>
<p>Unlike the previous two tutorials, this one will not list all the source code for all project classes and web files. We’ll just focus on the most important stuff. You can download the full source code for this iteration from <a href='/resources/EvilLink_i3.zip'>here</a>.</p>
<p>Let’s continue with the remaining user stories:</p>
<ul>
<li>As a user, I want to record my web links online, so that I can access them from anywhere.</li>
<li>As a user, I want to review the links that I previously recorded so that I can visit the interesting sites. </li>
<li>As a user, I want to edit details and descriptions of the links that I previously recorded, so that I can keep them up to date.</li>
</ul>
<p>To implement these stories, we will create a new controller to manage links. We will prevent anonymous users from accessing this controller by checking whether the user is logged in, and if not, redirecting them to the login page.</p>
<h2>Modifying the model</h2>
<p>To implement these stories, we will need to create the Link record type and describe the relationship between users and links. We add a Links collection to User class to record links that the user has registered. It’s best to have the type as a IList interface rather than a particular list to avoid data mapping problems. Instead of [Property], we mark this as [HasMany] to signal that it is a one-to-many mapping.</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>private</span><span> <span style='color:teal'>IList</span>&lt;<span style='color:teal'>Link</span>&gt; links = <span style='color:blue'>new</span> <span style='color:teal'>List</span>&lt;<span style='color:teal'>Link</span>&gt;();</span>
<span>[<span style='color:teal'>HasMany</span>]</span>
<span style='color:blue'>public</span><span> <span style='color:teal'>IList</span>&lt;<span style='color:teal'>Link</span>&gt; Links</span>
<span>{</span>
<span>    <span style='color:blue'>get</span> { <span style='color:blue'>return</span> links; }</span>
<span>    <span style='color:blue'>set</span> { links=<span style='color:blue'>value</span>; }</span>
<span>}</span>
</pre>
</div>
<p>The Link class is fairly straight-forward. The only interesting part is the other end of the one-to-many relationship. We mark it as [BelongsTo] and also specify that the Link collection should get saved and updated automatically when the User is saved.</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
[BelongsTo(Cascade = CascadeEnum.SaveUpdate)]
public User Owner
{
    get { return owner; }
    set { owner= value; }
}
</pre>
</div>
<h2>Dynamic binding, AR style</h2>
<p>One of the best things about the Castle project is how we can learn and use various components in isolation, but they also have added value when used together. Monorail and ActiveRecord together allow us to write web applications with very little boiler-plate code, focusing just on the business problem at hand. In the second part of this tutorial I explained how to use data binding to automatically populate domain objects from HTTP requests. When ActiveRecord comes into the play, this data binding becomes even more powerful. We can tell Monorail to automatically fetch a record object from the database by ID and have it ready for us to either pass to the view or modify. This is very convenient for actions that should display an object or present a HTML form to edit the object. This is done using the ARFetch attribute instead of DataBind and passing the request field that represents the ID of the related record object. For example, this method signature will automatically fetch a link by id from the database and make it available to us for display:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>public</span><span> <span style='color:blue'>void</span> Edit([<span style='color:teal'>ARFetch</span>(<span style='color:maroon'>&quot;id&quot;</span>)] <span style='color:teal'>Link</span> link)</span>
</pre>
</div>
<p>On the way back, we typically want to merge the database object with the request values. There is a shortcut for this as well:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>public</span><span> <span style='color:blue'>void</span> Submit([<span style='color:teal'>ARDataBind</span>(<span style='color:maroon'>&quot;link&quot;</span>,
AutoLoad = <span style='color:teal'>AutoLoadBehavior</span>.NewInstanceIfInvalidKey)] <span style='color:teal'>Link</span> link)</span>
</pre>
</div>
<p>ARDataBind will first find the object in the database, then populate it with changes from the HTTP request. The only thing left to do is to verify that the link is valid and save it. AutoLoadBehavior specifies what to do if the object is not found &mdash; in this case ARDataBind will create a new object, effectively enabling us to use the same method for creating and updating links.</p>
<p>To use these two attributes, our controller has to extend ARSmartDispatcherController, not SmartDispatcherController. The new controller base class and the data load attributes are in the Castle.MonoRail.ActiveRecordSupport.dll library, so add a reference to that DLL as well in your controllers project.</p>
<h2>Advanced Monorail concepts</h2>
<p>Instead of wrapping up here, let’s see what else we can delegate to Monorail and write less code. Monorail has several more tricks to save time and effort while creating web applications. </p>
<h3>Filters</h3>
<p>Filters, in Monorail jargon, are methods that are executed before or after controller actions. They allow us to declaratively add infrastructural functionality to the controller code, similar to Aspect Oriented Programming (Windsor provides better support for AOP in general and we’ll discuss this in one of the following articles in this series. Monorail filters are just simple additions to controller code). For example, we can use a filter to instantly prevent anonymous users from calling any action on the Link controller. A filter is specified on the whole controller class with a FilterAttribute. This one will execute the AuthenticatedUserFilter before each action:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span>[<span style='color:teal'>FilterAttribute</span>(<span style='color:teal'>ExecuteEnum</span>.BeforeAction, <span style='color:blue'>typeof</span>(<span style='color:teal'>AuthenticatedUserFilter</span>))]</span>
</pre>
</div>
<p>The filter class (in this case AuthenticatedUserFilter) has to implement the IFilter interface from Castle.Monorail.Framework. The interface has only one method: Perform. If it returns false, the HTTP request processing will stop at that point and will not proceed to the controller. So let’s check if a user is logged in, and if not then redirect the browser to the login page:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>using</span><span> System;</span>
<span style='color:blue'>using</span><span> System.Collections.Generic;</span>
<span style='color:blue'>using</span><span> System.Text;</span>
<span style='color:blue'>using</span><span> Castle.MonoRail.Framework;</span>
<span>&nbsp;</span>
<span style='color:blue'>namespace</span><span> EvilLink.Controllers</span>
<span>{</span>
<span>    <span style='color:blue'>public</span> <span style='color:blue'>class</span> <span style='color:teal'>AuthenticatedUserFilter</span>: <span style='color:teal'>IFilter</span></span>
<span>    {</span>
<span>        <span style='color:blue'>private</span> <span style='color:teal'>UserContext</span> userContext=<span style='color:blue'>new</span> <span style='color:teal'>UserContext</span>();</span>
<span>&nbsp;</span>
<span>&nbsp;</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>bool</span> Perform(<span style='color:teal'>ExecuteEnum</span> exec, </span>
<span>          <span style='color:teal'>IRailsEngineContext</span> context, <span style='color:teal'>Controller</span> controller)</span>
<span>        {</span>
<span>            <span style='color:blue'>if</span> (userContext.CurrentUserId == <span style='color:blue'>null</span>)</span>
<span>            {              </span>
<span>                context.Response.Redirect(<span style='color:maroon'>&quot;UserOps&quot;</span>,
<span style='color:maroon'>     &quot;index.ashx?goBackUrl=&quot;</span>+context.Request.Uri);</span>
<span>                <span style='color:blue'>return</span> <span style='color:blue'>false</span>;</span>
<span>            }</span>
<span>            <span style='color:blue'>else</span> <span style='color:blue'>return</span> <span style='color:blue'>true</span>;</span>
<span>        }</span>
<span>    }</span>
<span>}</span>
</pre>
</div>
<p>We can now use this filter to quickly mark all controllers that require the customer to be logged in, just by putting an attribute on the class. </p>
<h3>Partial templates</h3>
<p>NVelocity allows us to reuse view code in different templates by just including the file, using #parse(file) command. This is what Rails calls partial templates. For example, we’ll need to display link details after a user registers that link, but we also need to display the same details when the user browses his links. Instead of copying the same content all over the templates, we can extract that into a common view file and just include it. The important thing to remember is that the path of the included file is relative to the views folder, not the current folder. This is an example of the view that prints links using a partial template:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
&lt;h1&gt;My Links&lt;/h1&gt;
#if ($links.Count&gt;0)
&lt;ul&gt;
	#foreach( $link in $links)
	&lt;li&gt;
		#parse ("Link/viewLink.vm")
	&lt;/li&gt;
	#end
&lt;/ul&gt;
#else
You have no saved links.
#end
#parse("Link/newLink.vm")
</pre>
</div>
<h3>Helpers</h3>
<p>NVelocity language intentionally does not allow you to perform complex scripting, to avoid mixing domain and UI code. But sometimes we want to automate generating HTML code in a more complex language. Monorail allows that with Helpers. Helpers allow us to script the UI formatting in C#. We used a forms helper in the second article of this tutorial, to build a HTML form and pre-populate it with values. There are some other interesting helpers included in the Castle distribution, for example Ajax helpers that generate Scriptaculous effects or help with Prototype communication. You can also write your own helpers and add them to the controllers using the Helper attribute.</p>
<h3>View components</h3>
<p>View components are a way to re-use parts of the UI dynamically in various pages. This is typically used to manage common parts of the web pages like menus. </p>
<p>I personally don’t use view components that much, because there are different alternatives that can provide the same functionality with just controllers. For view formatting (without any business functionality), it is often better to use Helpers. To loop through a list of objects and reuse the display functionality, I use partial templates (with NVelocity, you can use #parse to include a template file). Parts that reuse business functionality can be implemented using AJAX DIVs as well. So components are really used only when you need to re-use parts of UI that include some business functionality and layout, but you want to process that on the server as part of the same request (so no AJAX). </p>
<p>We use a component in this case to build the top menu bar, that will display links to log in and register if the user is not yet logged in, and display options to add and review stored links and to log out when a user is logged in. The component class is just like a mini-controller with a single action. To implement the component, we need to extend ViewComponent and override the Render method. PropertyBag is available for the component as well (it is actually shared with the controller). Because there is only one method, the component needs to explicitly specify which view gets rendered.</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>using</span><span> Castle.MonoRail.Framework;</span>
<span style='color:blue'>namespace</span><span> EvilLink.Controllers</span>
<span>{</span>
<span>    <span style='color:blue'>public</span> <span style='color:blue'>class</span> <span style='color:teal'>MenuBarComponent</span>:<span style='color:teal'>ViewComponent</span></span>
<span>    {</span>
<span>        <span style='color:blue'>private</span> <span style='color:teal'>UserContext</span> context=<span style='color:blue'>new</span> <span style='color:teal'>UserContext</span>();</span>
<span>&nbsp;</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>override</span> <span style='color:blue'>void</span> Render()</span>
<span>        {</span>
<span>            <span style='color:blue'>if</span> (context.CurrentUserId != <span style='color:blue'>null</span>)</span>
<span>                PropertyBag[<span style='color:maroon'>&quot;appuser&quot;</span>] = context.CurrentUser;</span>
<span>            RenderView(<span style='color:maroon'>&quot;default&quot;</span>);</span>
<span>        }</span>
<span>    }</span>
<span>}</span>
</pre>
</div>
<p>The view file for the component is similar to the controller view files, but it needs to be in the views\components\MenuBarComponent folder in the web site. To include this component somewhere in the view code, use #component NVelocity extension (this was added for the Castle project and it is not available in the basic NVelocity release). As components are re-usable across pages, they are typically included into the generic layout files, not into individual template views. So here is the changed default layout:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>&lt;</span><span style='color:maroon'>html</span><span style='color:blue'>&gt;</span>
<span style='color:blue'>&lt;</span><span style='color:maroon'>head</span><span style='color:blue'>&gt;&lt;</span><span style=';color:maroon'>title</span><span style='font-size:10.0pt;font-family:"Courier New";color:blue'>&gt;</span><span style='font-size:10.0pt;font-family:"Courier New"'>Evil Link v 1.0<span style='color:blue'>&lt;/</span><span style='color:maroon'>title</span><span style='color:blue'>&gt;&lt;/</span><span style='color:maroon'>head</span><span style='color:blue'>&gt;</span></span>
<span style='color:blue'>&lt;</span><span style='color:maroon'>link</span><span style='color:blue'> </span><span style='color:red'>rel</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>stylesheet</span>&quot;<span style='color:blue'> </span><span style='color:red'>href</span><span style='color:blue'>=</span>&quot;<span style='color:blue'>$siteRoot/views/layouts/default.css</span>&quot;<span style='color:blue'> /&gt;</span></span>
<span style='color:blue'>&lt;</span><span style='color:maroon'>body</span><span style='color:blue'>&gt;</span>
<span>      #component(MenuBarComponent)</span>
<span style='color:blue'>      &lt;</span><span style=';color:maroon'>hr</span><span style=';color:blue'>/&gt;</span>
<span>      #if($message)</span>
<span style='color:blue'>      &lt;</span><span style=';color:maroon'>div</span><span style='font-size:10.0pt;font-family:"Courier New";color:blue'> </span><span style='font-size:10.0pt;font-family:"Courier New";color:red'>class</span><span style='font-size:10.0pt;font-family:"Courier New";color:blue'>=</span><span style='font-size:10.0pt;font-family:"Courier New"'>&quot;<span style='color:blue'>message</span>&quot;<span style='color:blue'>&gt;</span></span>
<span>            $message</span>
<span style='color:blue'>      &lt;/</span><span style=';color:maroon'>div</span><span style='font-size:10.0pt;font-family:"Courier New";color:blue'>&gt;</span>
<span>      #end</span>
<span>&nbsp;</span>
<span>      #if($error)</span>
<span style='color:blue'>      &lt;</span><span style=';color:maroon'>div</span><span style='font-size:10.0pt;font-family:"Courier New";color:blue'> </span><span style='font-size:10.0pt;font-family:"Courier New";color:red'>class</span><span style='font-size:10.0pt;font-family:"Courier New";color:blue'>=</span><span style='font-size:10.0pt;font-family:"Courier New"'>&quot;<span style='color:blue'>error</span>&quot;<span style='color:blue'>&gt;</span></span>
<span>            $error</span>
<span style='color:blue'>      &lt;/</span><span style=';color:maroon'>div</span><span style='font-size:10.0pt;font-family:"Courier New";color:blue'>&gt;</span>
<span>      #end</span>
<span>&nbsp;</span>
<span>      $childContent</span>
<span>&nbsp;</span>
<span style='color:blue'>&lt;/</span><span style='color:maroon'>body</span><span style='color:blue'>&gt;</span>
<span style='font-size:10.0pt;font-family:"Courier New"; color:blue'>&lt;/</span><span style='font-size:10.0pt;font-family:"Courier New"; color:maroon'>html</span><span style='font-size:10.0pt;font-family:"Courier New"; color:blue'>&gt;</span>
</pre>
</div>
<h3>Rescues</h3>
<p>Monorail Rescues allow us to delegate most common error handling cases, when we just display an error message to the user, to the framework. A rescue is just an alternative view that will be displayed in case of an exception, and passing the responsibility for that to the framework allow us to write less code &mdash; instead of try/catch and display error blocks in every action, we just specify an attribute. Rescues can be specified for the whole class or for individual methods, and can be called for a particular exception type or for any exception. For example, to just display an error view in case of any exceptions during processing, we can add a Rescue(&#8220;error&#8221;) attribute to the controller class. The actual view should be stored in the views\rescues folder of the web site. In the view, we can use $context to reference the rails context. See <a target='_blank' href='http://api.castleproject.org/html/AllMembers_T_Castle_MonoRail_Framework_IRailsEngineContext.htm'>IRailsEngineContext API docs</a> for more details on that. Most important is the fact that $context.LastException.Message will give us the exception message. So here is a simple rescue velocity file:</p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>&lt;</span><span style='color:maroon'>div</span><span style='color:blue'> </span><span style='color:red'>class</span><span style='color:blue'>=</span><span>&quot;<span style='color:blue'>error</span>&quot;<span style='color:blue'>&gt;</span></span>
<span>$context.LastException.Message</span>
<span style='color:blue'>&lt;/</span><span style='color:maroon'>div</span><span style='color:blue'>&gt;</span>
</pre>
</div>
<h2>Implementing the Link Controller</h2>
<p>Armed with all this knowledge, we can now easily implement the link controller. We’ll add a filter to prevent people from using any of the link controller actions if they are not logged in, and we will also not write any error handling code &#038;mdash instead it will be delegated to a rescue. We need to implement actions to register a new link and edit an existing link. After the user submits link details, we store them to the database and display new link information. We also want to enable users to view registered links. For that, we’ll create the following actions:</p>
<ul>
<li>NewLink &mdash; display a form for a new link</li>
<li>Edit &mdash; display a form to edit an existing link</li>
<li>MyLinks &mdash; view registered links</li>
<li>Submit &mdash; process a form containing link details, either to create or edit a link</li>
<li>View &mdash; view details of a particular link</li>
</ul>
<p>Edit and View perform the same action essentially, they just load the link details from the database and pass it on to the view to display (but they use different views). We’ll use ARFetch for Edit and View, and we use ARDataBind for Submit. NewLink and Edit should use the same visual template, and MyLinks should use that same template to display links from a collection. For that, we can use the #parse trick. </p>
<div style="padding-bottom:10pt">
<pre style="text-autospace:none;font-size:10.0pt;font-family:Courier New">
<span style='color:blue'>using</span><span> System;</span>
<span style='color:blue'>using</span><span> System.Collections.Generic;</span>
<span style='color:blue'>using</span><span> System.Text;</span>
<span style='color:blue'>using</span><span> Castle.MonoRail.ActiveRecordSupport;</span>
<span style='color:blue'>using</span><span> EvilLink.Database;</span>
<span style='color:blue'>using</span><span> Castle.MonoRail.Framework;</span>
<span style='color:blue'>namespace</span><span> EvilLink.Controllers</span>
<span>{</span>
<span>    [<span style='color:teal'>FilterAttribute</span>(<span style='color:teal'>ExecuteEnum</span>.BeforeAction, <span style='color:blue'>typeof</span>(<span style='color:teal'>AuthenticatedUserFilter</span>))]</span>
<span>    [<span style='color:teal'>Rescue</span>(<span style='color:maroon'>&quot;error&quot;</span>), <span style='color:teal'>Layout</span>(<span style='color:maroon'>&quot;default&quot;</span>)]</span>
<span>    <span style='color:blue'>public</span> <span style='color:blue'>class</span> <span style='color:teal'>LinkController</span> : <span style='color:teal'>ARSmartDispatcherController</span> </span>
<span>    {</span>
<span>        <span style='color:blue'>private</span> <span style='color:teal'>UserContext</span> context=<span style='color:blue'>new</span> <span style='color:teal'>UserContext</span>();</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> NewLink()</span>
<span>        {</span>
<span>            <span style='color:green'>// just display the form</span></span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> Submit([<span style='color:teal'>ARDataBind</span>(<span style='color:maroon'>&quot;link&quot;</span>,</span>
<span>         AutoLoad = <span style='color:teal'>AutoLoadBehavior</span>.NewInstanceIfInvalidKey)] <span style='color:teal'>Link</span> link)</span>
<span>        {</span>
<span>            <span style='color:blue'>if</span> (!link.IsValid())</span>
<span>            {</span>
<span>                PropertyBag[<span style='color:maroon'>&quot;link&quot;</span>] = link;</span>
<span>                Flash[<span style='color:maroon'>&quot;error&quot;</span>] = link.ValidationErrorMessages;</span>
<span>                RenderView(<span style='color:maroon'>&quot;edit&quot;</span>);</span>
<span>                <span style='color:blue'>return</span>;</span>
<span>            }</span>
<span>            link.Owner = context.CurrentUser;</span>
<span>            link.SaveAndFlush();</span>
<span>            Flash[<span style='color:maroon'>&quot;message&quot;</span>] = <span style='color:maroon'>&quot;Link saved&quot;</span>;</span>
<span>            <span style='color:green'>//redirect after post</span></span>
<span>            Redirect(<span style='color:maroon'>&quot;view.ashx?id=&quot;</span>+link.Id);</span>
<span>        }</span>
<span>        <span style='color:green'>// shortcut for loading the object, don't update it with request values</span></span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> View([<span style='color:teal'>ARFetch</span>(<span style='color:maroon'>&quot;id&quot;</span>)] <span style='color:teal'>Link</span> link)</span>
<span>        {</span>
<span>            PropertyBag[<span style='color:maroon'>&quot;link&quot;</span>] = link;</span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> Edit([<span style='color:teal'>ARFetch</span>(<span style='color:maroon'>&quot;id&quot;</span>)] <span style='color:teal'>Link</span> link)</span>
<span>        {</span>
<span>            View(link); <span style='color:green'></span></span>
<span>        }</span>
<span>        <span style='color:blue'>public</span> <span style='color:blue'>void</span> MyLinks()</span>
<span>        {</span>
<span>            PropertyBag[<span style='color:maroon'>&quot;links&quot;</span>] = context.CurrentUser.Links;</span>
<span>        }</span>
<span>    }</span>
<span>}</span>
</pre>
</div>
<h2>Key stuff to remember</h2>
<ul>
<li>Mark one-to-many relationships with [HasMany] and [BelongsTo]</li>
<li>Reuse parts of templates with #parse </li>
<li>Use helpers to perform more complex UI scripting with C#, but avoid putting any business functionality into helper classes</li>
<li>Share business functionality and UI between pages using view components</li>
<li>Delegate error handling to rescues</li>
<li>Use Filters for simple aspect-style programming with Controllers to perform authentication, logging and similar actions</li>
<li>Use ActiveRecord data binding attributes and ARSmartDispatcherController to automatically load objects from the database and merge changes from HTML forms</li>
</ul>
<h2>Next exercise</h2>
<p>In the next part of this tutorial, we look into unit testing Monorail controllers. That tutorial should be online early next week. You can download the full source code for this iteration from <a href='/resources/EvilLink_i3.zip'>here</a>.</p>
<p>Meanwhile, you might be interested in coming to the &#8220;Developing Ajax Web applications with Castle Monorail&#8221; presentation that I will be doing on the 12th of June in London. It&#8217;s free, but you have to register up-front. See <a href='http://skillsmatter.com/event/open-source-dot-net/developing-ajax-web-applications-with-castle-monorail'>Skills Matter site</a> for more information.   </p>
]]></content:encoded>
			<wfw:commentRss>http://gojko.net/2008/05/26/castle-demo-app-3-saving-time-and-effort-with-advanced-monorail-features/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
