philliphaydon.com 2013-05-15T10:02:33-07:00 http://www.philliphaydon.com/ Phillip Haydon Copyright (c) 2009 Phillip Haydon Setup my first Azure Virtual Machine! 2013-05-16T00:00:00-07:00 http://www.philliphaydon.com/2013/05/setup-my-first-azure-virtual-machine/ <p>Every time I touch Azure I&rsquo;m constantly amazed at how much simpler it is compared to when I tried it back when it had the crappy Silverlight management site.</p> <p>Infact every time I touch the thing I over-complicate something only to realize it was dead simple to begin with.</p> <p>I&rsquo;m currently in the process of slowly building a VM to run a few small websites I&rsquo;m building in my own time. Based on what I need Azure will cost me $60 less each month for roughly the same specs (with about 256mb less ram)</p> <p>The first time creating a VM took me a couple of hours to setup and working, nuking it and starting again took about as long as it took to provision the VM (few minutes)</p> <!--excerpt--> <h2>Things I did wrong :(</h2> <ol> <li><p>When I setup the DNS I used the Internal IP Address instead of the Public Virtual IP address.</p> <p><img src="/images/azure-vm-1.png" alt="" /></p></li> <li><p>After sorting out the DNS so ping hit the right IP Address, I needed to add an Endpoint for port 80. Luckily when IIS installs on Windows Server 2012 it configures the Firewall for you. I don&rsquo;t recall it doing that for you on 2008. Needless to say, once the Endpoint was in place, websites became visible!</p> <p><img src="/images/azure-vm-2.png" alt="" /></p></li> <li><p>I didn&rsquo;t want to store my websites, and images/videos on the OS Drive so I needed to create a 2nd drive. Initially I went fluffing around in Storage, creating a new storage and setting blob read/write etc etc&hellip; Turns out I wasted about 20 minutes of my time to find out&hellip;</p> <p><img src="/images/azure-vm-3.png" alt="" /></p> <p>There&rsquo;s a button to add an empty disk to a selected virtual machine&hellip; Arg, well that turned out to be REALLY simple!</p></li> <li><p>I kind of expected the disk to automatically show up in the VM, but then I remembered watching some video on Azure VMs which said you need to enable/format the disk manually. /facepalm</p> <p>So once again jump into the VM, go to the disk management screen and enable/format, now I got storage ready to go!</p></li> </ol> <h2>Conclusion</h2> <p>Weather I&rsquo;m messing around with Serivces, Website, Virtual Machines. Azure has come a long way and its such a pleasure to work with! I was pretty negative towards Azure when it had the Silverlight management screen because it was slow and I couldn&rsquo;t figure out how to do anything. Now its a breeze!</p> NancyFX - Revisiting Content Negotiation & APIs (Part 2) 2013-05-09T00:00:00-07:00 http://www.philliphaydon.com/2013/05/nancyfx-revisiting-content-negotiation-and-apis-part-2/ <ul> <li><a href="/2013/04/nancyfx-revisiting-content-negotiation-and-apis-part-1/">NancyFX &ndash; Revisiting Content Negotiation &amp; APIs (Part 1)</a></li> </ul> <p>In part 1 I went over a really basic scenario, and one of the fiddly things we had was the view name for returning a collection.</p> <p>Using <code>Negotiate</code> gives as more flexibility on what we can return, allowing us to customize the response to respond differently to different media types or returning partial content in some scenarios.</p> <p>Going back to my previous post I said we should be able to use the same API to build our website as we expose. But what about when we want to have additional information on the website that isn&rsquo;t pushed out to the client.</p> <p>Lets say you have a product catalog, and you can view a particular product on your website. You also allow people to pull the content from your site to display on their website as like an affiliate system of some sort. But when you render your product you may have a special, but when you send the product to the consuming client you don&rsquo;t want to include the special for them since it&rsquo;s something specific to your website.</p> <h2>Show me the codez!</h2> <p>So lets update the <code>Product</code> to include <code>SpecialPrice</code></p> <!--excerpt--> <pre><code>public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public decimal? SpecialPrice { get; set; } } </code></pre> <p><em><strong>Note:</strong> and also update the repository to return the Special Price on each <code>Product</code></em></p> <p>We&rsquo;re also going to introduce a new model called <code>PartialProduct</code>. There may be a better name for it, but its what I picked for the purpose of demonstrating. This is going to be the same as <code>Product</code> but without the <code>SpecialPrice</code> property.</p> <pre><code>public class PartialProduct { public PartialProduct() { } public PartialProduct(Product product) { Id = product.Id; Name = product.Name; Price = product.Price; } public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } } </code></pre> <p>The constructor is used to populate the model based on a <code>Product</code>. You may want to use something like AutoMapper to do this for you, or write some extension methods, etc.</p> <p>Now with our route, we want to return the <code>PartialProduct</code> when responding to <code>application/json</code> or <code>application/xml</code></p> <pre><code>Get["/{id}"] = _ =&gt; { var product = productRepository.Get((int)_.id); return Negotiate.WithView("product") .WithModel(product) .WithMediaRangeModel(MediaRange.FromString("application/json"), new PartialProduct(product)) .WithMediaRangeModel(MediaRange.FromString("application/xml"), new PartialProduct(product)); }; </code></pre> <p>So we are saying that we want to negotiate the response with the view <code>product</code> using the model <code>product</code>, but if the MediaRange is <code>application/json</code> we want to return a partial product, likewise if its <code>application/xml</code> we want to also return a partial model. <em>(if it looks like a lot to type, don&rsquo;t worry we can tidy this up)</em></p> <p>Now when we setup our Postman looking for <code>text/html</code> we get the <code>SpecialPrice</code> returned on the product:</p> <p><img src="/images/nancyfx-conneg-updated-part2-1.png" alt="" /></p> <p>However if we update it to <code>application/json</code> we get:</p> <p><img src="/images/nancyfx-conneg-updated-part2-2.png" alt="" /></p> <p>Anddddd <code>application/xml</code> we get:</p> <p><img src="/images/nancyfx-conneg-updated-part2-3.png" alt="" /></p> <p>But&hellip; We kinda had to write a lot of code for the media ranges. Extension methods are awesome though, so we can tidy them up by introducing our own extension methods:</p> <pre><code>public static class NegotiateExtensions { public static Negotiator ForJson(this Negotiator negotiator, object model) { return negotiator.WithMediaRangeModel(MediaRange.FromString("application/json"), model); } public static Negotiator ForXml(this Negotiator negotiator, object model) { return negotiator.WithMediaRangeModel(MediaRange.FromString("application/xml"), model); } } </code></pre> <p>This reduces things down to:</p> <pre><code>Get["/{id}"] = _ =&gt; { var product = productRepository.Get((int)_.id); return Negotiate.WithView("product") .WithModel(product) .ForJson(new PartialProduct(product)) .ForXml(new PartialProduct(product)); }; </code></pre> <p>Still too much? We can introduce one more extension</p> <pre><code>public static Negotiator OrPartial(this Negotiator negotiator, object model) { return negotiator.ForJson(model).ForXml(model); } </code></pre> <p>And now all we have is</p> <pre><code>Get["/{id}"] = _ =&gt; { var product = productRepository.Get((int)_.id); return Negotiate.WithView("product") .WithModel(product) .OrPartial(new PartialProduct(product)); }; </code></pre> <p>Obviously you can play around to figure out what suits you. But this gives us the flexibility to customize outputs for different media types.</p> <p>In part 3 I&rsquo;ll discuss implementing your own Media Type :)</p> RSS/Atom spam :( Sorry... 2013-05-07T00:00:00-07:00 http://www.philliphaydon.com/2013/05/rss-atom-feed-spam-sorry/ <p>Sorry to anyone who subscribes to me, I was setting up an RSS since not everything accepts Atom, and I guess it re-processed everything and has spammed everyone.</p> <p>Real sorry about that :(</p> Disabling Namespaces on folders in Visual Studio 2013-04-26T00:00:00-07:00 http://www.philliphaydon.com/2013/04/visual-studio-disable-namespacing-on-folders/ <p>I just discovered this little trick I found in Visual Studio to turn off namespacing on a folder. Not sure how after 8 years I only just found this.</p> <h2>The Problem</h2> <p>Lets assume we&rsquo;re working with Entity Framework&hellip; (shiver)&hellip; We create a Data Model, add all our Entities and away we go.</p> <p>Then we want to extend one of the Entities, maybe to add some methods and such, so we need to create some partial classes. So far we have:</p> <p><img src="/images/visual-studio-namespacing-1.png" alt="" /></p> <p>We create a new <code>Member.cs</code> class in the <code>Partials</code> folder;</p> <!--excerpt--> <pre><code>namespace SampleNamespacing.Models.Partials { public partial class Member { } } </code></pre> <p>Then we delete the <code>Partials</code> to put it in the same namespace as the Entities defined in the Data Model</p> <pre><code>namespace SampleNamespacing.Models { public partial class Member { } } </code></pre> <p>But now we have a ReSharper warning</p> <p><img src="/images/visual-studio-namespacing-2.png" alt="" /></p> <p>Now we don&rsquo;t have a nice green file :(</p> <p><img src="/images/visual-studio-namespacing-3.png" alt="" /></p> <h2>The Solution!</h2> <p>This is so simple >&lt;</p> <p>Right click the folder and go to Properties:</p> <p><img src="/images/visual-studio-namespacing-4.png" alt="" /></p> <p>BAM! Right there, <code>Namespace Provider</code>! Set that thing to <code>False</code> and we get:</p> <p><img src="/images/visual-studio-namespacing-5.png" alt="" /></p> <p>No more warnings!</p> <h2>Wheres this feature come from?</h2> <p>Turns out this is a ReSharper setting! This setting is stored in the <code>*project*.csproj.DotSettings</code> file. So if you&rsquo;re using team settings then this setting would be picked up by everyone on the team.</p> NancyFX - Revisiting Content Negotiation & APIs (Part 1) 2013-04-22T00:00:00-07:00 http://www.philliphaydon.com/2013/04/nancyfx-revisiting-content-negotiation-and-apis-part-1/ <p>Original Post: <a href="/2012/11/nancy-and-content-negotiation">NancyFX and Content Negotiation</a></p> <p>I thought I would revisit this topic since I don&rsquo;t believe I did it enough justice last time around, and I believe it really is important when creating an API that is going to be consumed not only by the public or client, but <strong>by you also</strong>!</p> <p>When the browser asks for <code>text/html</code> its negotiating with the server. So really your website is an API, your <code>Views</code> are just an additional type of content that your API serves up when requested.</p> <h2>Example</h2> <p>Lets say you&rsquo;re building Twitter, the initial page shows a list of tweets, so the browser makes a call to <code>/tweets</code> and the server responds with a list of tweets rendered with using HTML.</p> <p>Once the page has loaded, the client uses JavaScript to load new tweets, so it calls <code>/tweets</code> again, this time it returns a <code>json</code> result, and the client-side templating engine then renders and appends those to the top of the existing list, keeping the client up to date with the latest tweets.</p> <p>What&rsquo;s nice is no new data needed to be written on the server!</p> <!--excerpt--> <p><span class="note"><strong>Note:</strong> I&rsquo;m not going to discuss RESTful API&rsquo;s, that would just create too many arguments.</span></p> <h2>Need code please</h2> <p>Right so lets see this in action for real. When I demonstrated this in my previous post, I showed a somewhat complicated Negotiate, this time I&rsquo;m going to show a super simple scenario.</p> <p>We have a <code>ProductsModule</code>, it can <code>Get</code> a single product, or it can <code>Get</code> a list of products.</p> <pre><code>public class ProductsModule : NancyModule { public ProductsModule(IProductRepository productRepository) :base("products") { Get["/{id}"] = _ =&gt; { var product = productRepository.Get((int)_.id); return product; }; Get["/"] = _ =&gt; { var products = productRepository.List(); return products; }; } } </code></pre> <p>Using a Chrome Plugin called Postman which can be found on the <a href="https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?utm_source=chrome-ntp-launcher">Chrome Web Store</a>.</p> <p><img src="/images/nancyfx-conneg-updated-1.png" alt="" /></p> <p>We can invoke some calls to get some data. We specify the <code>URL</code>, the <code>VERB</code>, and add some Headers. In this case we will add a single header. <code>Accept</code> where we specify that we want <code>application/xml</code>.</p> <p><img src="/images/nancyfx-conneg-updated-2.png" alt="" /></p> <p>When we invoke this, we get an XML result of our products:</p> <p><img src="/images/nancyfx-conneg-updated-3.png" alt="" /></p> <p>When we do the same call but we specify the <code>Accept</code> header with <code>application/json</code> we get a JSON result.</p> <p><img src="/images/nancyfx-conneg-updated-4.png" alt="" /></p> <p>Nice right? So far we haven&rsquo;t written any code other than returning some data to a endpoint we specified. Lets take a look at the first route, its a Get By Id route, and all we&rsquo;re returning is a single Product.</p> <p><img src="/images/nancyfx-conneg-updated-5.png" alt="" /></p> <p>Now if we specify the Accept as something the browser would ask for, <code>text/html</code> we would expect rendered HTML.</p> <p><img src="/images/nancyfx-conneg-updated-6.png" alt="" /></p> <p>Bam we get an error, but this is only because the view doesn&rsquo;t exist yet. By default NancyFX looks for a view of the same name of the type returned.</p> <p>Since we returned a &lsquo;product&rsquo;, the view name that Nancy will look for is <code>typeof(Product).Name</code> or <code>Product</code>. So if we create a new product view to display some data:</p> <pre><code>&lt;!DOCTYPE html&gt; &lt;html lang="en" xmlns="http://www.w3.org/1999/xhtml"&gt; &lt;head&gt; &lt;meta charset="utf-8" /&gt; &lt;title&gt;&lt;/title&gt; &lt;/head&gt; &lt;body&gt; &lt;div&gt; Id: @Model.Id &lt;br /&gt; Name: @Model.Name &lt;br /&gt; Price: $@Model.Price &lt;/div&gt; &lt;/body&gt; &lt;/html&gt; </code></pre> <p>Super super simple, now when we call the same route again we get:</p> <p><img src="/images/nancyfx-conneg-updated-7.png" alt="" /></p> <p>Now we have a Single API that returns JSON, XML, or HTML.</p> <h2>Fiddly Issues</h2> <p>Here&rsquo;s where things get fiddly, if we want to return the collection with a view, NancyFX will attempt to convert the <code>List&lt;Product&gt;</code> to it&rsquo;s name, and look for the view. This ends up looking for a view by the name of <code>List`1</code>, which you may think will fail, but funnily enough you can actually create a view with the backquote.</p> <p>So lets create a new file called <code>List`1.sshtml</code> and populate it with some basic HTML:</p> <pre><code>&lt;!DOCTYPE html&gt; &lt;html lang="en" xmlns="http://www.w3.org/1999/xhtml"&gt; &lt;head&gt; &lt;meta charset="utf-8" /&gt; &lt;title&gt;&lt;/title&gt; &lt;/head&gt; &lt;body&gt; @Each &lt;div&gt; Id: @Current.Id &lt;br /&gt; Name: @Current.Name &lt;br /&gt; Price: $@Current.Price &lt;/div&gt; &lt;hr&gt; @EndEach &lt;/body&gt; &lt;/html&gt; </code></pre> <p><span class="note"><strong>Note:</strong> in case you&rsquo;re wondering, this isn&rsquo;t Razor, this is Nancy&rsquo;s Super Simple View Engine :)</span></p> <p>Now if we run up the site again and hit <code>/products</code> we get:</p> <p><img src="/images/nancyfx-conneg-updated-8.png" alt="" /></p> <h2>Recap</h2> <p>So far we have created a single endpoint with very little code that can respond with JSON/XML/HTML. Next I&rsquo;m going to show how <code>Negotiate</code> gives you more flexibility.</p> NancyFX - Implementing your own routing! 2013-04-09T00:00:00-07:00 http://www.philliphaydon.com/2013/04/nancyfx-implementing-your-own-routing/ <p>With the up and coming release of 0.17 of NancyFX, the routing has been completely rewritten, and now it&rsquo;s super easy to implement your own routing. So I&rsquo;m going to show you how.</p> <h2>How it works</h2> <p>The routing works by defining a route:</p> <p><code>Get["/products/{id}"]</code></p> <p>The route is then broken up into segments:</p> <ol> <li><code>products</code></li> <li><code>{id}</code></li> </ol> <p>Each segment is checked against a Node Condition in the <code>TrieNodeFactory</code> like so</p> <pre><code>if (segment.StartsWith("(") &amp;&amp; segment.EndsWith(")")) { return new RegExNode(parent, segment, this); } </code></pre> <p>When a request comes in, the segment is compared to the node for a match and returns true/false + the captured parameter.</p> <p>These are a bunch of conditions for checking different nodes, currently Nancy supports out of the box the following nodes.</p> <h2>Existing Nodes</h2> <p>This is brief description of the existing nodes that currently exist in 0.17.</p> <h3>CaptureNode</h3> <p>This node captures <code>{foo}</code>, or basically any value defined in the segment.</p> <!--excerpt--> <h3>CaptureNodeWithDefaultValue</h3> <p>Similar to <code>CaptureNode</code>, <code>{foo?defaultValue}</code>, allows you to capture any value, with a default value should the value not exist.</p> <h3>GreedyCaptureNode</h3> <p>This is like the be-all-end-all node <code>{greedy*}</code>. It will capture anything in the current segment and onward. Although other segments are still checked. I would think it&rsquo;s rare to ever need this node.</p> <h3>LiteralNode</h3> <p>If nothing else is captured in any other node, then likely hood it&rsquo;s a literal value, this will just capture the segment as is, non-capturing, its just a match or non-match.</p> <h3>OptionalCaptureNode</h3> <p>This is like the <code>CaptureNode</code> and <code>CaptureNodeWithDefaultValue</code>, but it just makes the segment as optional. It can or cannot exist, if it exists it&rsquo;s captured.</p> <h3>RegExNode</h3> <p>Wooo Regular Expression support! <code>(?&lt;foo&gt;\d{2,4})</code> is a named capture that will find an numeric value between 2-4 digits long, in the segment.</p> <h3>GreedyRegExCaptureNode</h3> <p>The <code>GreedyRegExCaptureNode</code> is a little more complicated, it&rsquo;s a mix between the <code>RegExNode</code> and <code>GreedyCaptureNode</code>, and supports any number of segments in a regular expression match. i.e <code>^(?:(?&lt;id&gt;videos/\d{1,10})(?:/{0,1}(?&lt;slug&gt;.*)))$</code> will match <code>videos/123</code> or <code>videos/123/some-slug-url</code>.</p> <h3>RootNode</h3> <p>This node simply dictates that this is the very start of the route segments, the very root. Effectively its <code>/</code></p> <h2>Implementing your own Node</h2> <p>So we&rsquo;re going to create a route constraint. Our node will look like <code>[foo:even]</code>, we&rsquo;re saying that the segment will be captured, only if the value is an even number, anything else and it wont match.</p> <p>So we create a class and inherit <code>TrieNode</code></p> <pre><code>public class CapturedOddEvenNode : TrieNode { public CapturedOddEvenNode(TrieNode parent, string segment, ITrieNodeFactory nodeFactory) : base(parent, segment, nodeFactory) { } public override SegmentMatch Match(string segment) { throw new NotImplementedException(); } public override int Score { get { throw new NotImplementedException(); } } } </code></pre> <p>The first thing we want to do is prepare the segment, so in the ctor we are going to trim the <code>[]</code> values off the start/end of the segment and, then split the remaining value by <code>:</code> as the name on the left, and the condition on the right.</p> <pre><code>private string segmentName; private bool shouldBeEven; public CapturedOddEvenNode(TrieNode parent, string segment, ITrieNodeFactory nodeFactory) : base(parent, segment, nodeFactory) { this.ExtractParameterName(); } private void ExtractParameterName() { var innerSegment = this.RouteDefinitionSegment.Trim('[', ']'); var segmentSplit = innerSegment.Split(':'); this.segmentName = segmentSplit[0]; this.shouldBeEven = segmentSplit[1] == "even"; } </code></pre> <p>Next we need to implement the match. Here we want to check the value and condition:</p> <ol> <li>The value is not a number = no match</li> <li>The value is an odd number and the condition is it should be odd = match</li> <li>The value is an even number and the condition is it should be even = match</li> <li>Else the condition is not met so its a no match</li> </ol> <!----> <pre><code>public override SegmentMatch Match(string segment) { int numericValue; if (!int.TryParse(segment, NumberStyles.Integer, CultureInfo.InvariantCulture, out numericValue)) { return SegmentMatch.NoMatch; } if ((numericValue%2 == 0 &amp;&amp; shouldBeEven) || (numericValue%2 != 0 &amp;&amp; !shouldBeEven)) { var match = new SegmentMatch(true); match.CapturedParameters.Add(segmentName, numericValue); return match; } return SegmentMatch.NoMatch; } </code></pre> <p>Lastly we need to implement the Score. The score is used in the scenario when two routes have two matches, the summed total of the score for all segments becomes the weight deciding which route wins. Highest score of the two or more matches wins.</p> <p>We will set it to 100.</p> <pre><code>public override int Score { get { return 100; } } </code></pre> <p>Our final Node looks like so:</p> <pre><code>public class CapturedOddEvenNode : TrieNode { private string segmentName; private bool shouldBeEven; public CapturedOddEvenNode(TrieNode parent, string segment, ITrieNodeFactory nodeFactory) : base(parent, segment, nodeFactory) { this.ExtractParameterName(); } private void ExtractParameterName() { var innerSegment = this.RouteDefinitionSegment.Trim('[', ']'); var segmentSplit = innerSegment.Split(':'); this.segmentName = segmentSplit[0]; this.shouldBeEven = segmentSplit[1] == "even"; } public override SegmentMatch Match(string segment) { int numericValue; if (!int.TryParse(segment, NumberStyles.Integer, CultureInfo.InvariantCulture, out numericValue)) { return SegmentMatch.NoMatch; } if ((numericValue%2 == 0 &amp;&amp; shouldBeEven) || (numericValue%2 != 0 &amp;&amp; !shouldBeEven)) { var match = new SegmentMatch(true); match.CapturedParameters.Add(segmentName, numericValue); return match; } return SegmentMatch.NoMatch; } public override int Score { get { return 100; } } } </code></pre> <h2>Implementing your own factory</h2> <p>You&rsquo;re required to implement your own factory to call the new Node, this is super easy because we can just inherit the existing one.</p> <p>Create a new Factory called <code>CustomTrieNodeFactory</code> and implement <code>TrieNodeFactory</code></p> <pre><code>public class CustomTrieNodeFactory : TrieNodeFactory { public override TrieNode GetNodeForSegment(TrieNode parent, string segment) { if (parent == null) { return new RootNode(this); } if (segment.StartsWith("[") &amp;&amp; segment.EndsWith("]") &amp;&amp; segment.Contains(":")) { return new CapturedOddEvenNode(parent, segment, this); } return base.GetNodeForSegment(parent, segment); } } </code></pre> <p>You can see that the first condition is that I check that the parent is null, that&rsquo;s because the first segment is always the root node, all segments after that are out implementation. The condition is checked in the base call, but we want to check before we run out code.</p> <pre><code>if (parent == null) { return new RootNode(this); } </code></pre> <p>So by checking its null, we return a RootNode, then the call comes in the second time, it will have a parent node, and then check to see if the segment starts/ends with our criteria.</p> <h2>Wiring up the new factory</h2> <p>Lastly we need to wire up the factory in the bootstrapper, we can do this by overriding the <code>NancyInternalConfiguration</code> property and overriding the <code>TrieNodeFactory</code> property with our custom type like so:</p> <pre><code>protected override NancyInternalConfiguration InternalConfiguration { get { return NancyInternalConfiguration.WithOverrides(config =&gt; { config.TrieNodeFactory = typeof (CustomTrieNodeFactory); }); } } </code></pre> <p>Bam, that&rsquo;s it!</p> <h2>Does it work?</h2> <p>So if we create a new Module called <code>TestModule</code> and implement two routes:</p> <pre><code>Get["/test/[oddNumbersRawr:odd]"] = _ =&gt; { return "I love odd numbers! Like: " + _.oddNumbersRawr; }; </code></pre> <p>Running up the project and entering a with an odd number</p> <p><img src="/images/nancyfx-new-routing-1.png" alt="" /></p> <p>Pretty sweet!</p> <p>But if we enter the URL with an even number</p> <p><img src="/images/nancyfx-new-routing-2.png" alt="" /></p> <p>BAM page not found, because it didn&rsquo;t match the condition!</p> <p>That&rsquo;s really all there is to it. You can create any type of custom routing you like.</p> Raygun.io - a few features that I love 2013-04-08T00:00:00-07:00 http://www.philliphaydon.com/2013/04/raygun-io-a-few-features-that-i-love/ <p>I&rsquo;ve been using Raygun.io for a couple of months now and seen a whole heap of new features added.</p> <h3>Email Spam</h3> <p>If you had multiple apps you would get spammed with 1 summary email each day for each app, now you get an aggregation of all apps which is much nicer.</p> <p>If you receive an email for an exception, and that exception keeps occurring, it will email you a little while later saying that you&rsquo;re still receiving the exception, the rate at which its occurring, and if it&rsquo;s happening more or less.</p> <p>These changes are great! Still the same valuable information, but more smartly distributed to the user.</p> <h3>Commenting</h3> <p>I had an error, that occurred a lot&hellip;</p> <p><img src="/images/raygun-features-javascript-1.png" alt="" /></p> <p>So after fixing it, which took a little bit of effort to figure out, I commented on it!</p> <!--excerpt--> <p><img src="/images/raygun-features-javascript-2.png" alt="" /></p> <p>This is awesome! This is really powerful if the exception reoccurs, and becomes even more powerful if they decide to implement <a href="http://raygun.io/thinktank/suggestion/1012">this suggestion</a>.</p> <h3>The fact I get exceptions, when they happen!</h3> <p>I submitted my app to the Windows App Store, and it got declined, multiple times&hellip; But it allowed me to identity a bug in Microsoft Advertising SDK.</p> <p><img src="/images/raygun-features-javascript-3.png" alt="" /></p> <p>So it turns out there are random scenarios where the Advert Control, doesn&rsquo;t work and causes the app to crash hard. The dump that Microsoft supplies is absolute rubbish, it&rsquo;s massively time consuming and often doesn&rsquo;t give you enough information.</p> <p>With Raygun I was able to capture the errors as they occur and know where they were occurring. In the end I ended up removing the SDK from my app and submitting a ticket with MS to hopefully fix it.</p> <h3>Conclusion</h3> <p>I don&rsquo;t think I&rsquo;ve ever cared about exceptions in my applications in the past 8-9 years as much as I do now. Raygun just makes it so much easier to deal with that I care about whats happening in my application now.</p> <p>I&rsquo;m a little blown away that I care about something other than myself. :P</p> What I would like to see from Microsoft regarding OSS 2013-04-02T00:00:00-07:00 http://www.philliphaydon.com/2013/04/what-i-would-like-to-see-from-microsoft-regarding-oss/ <p>I had an awesome conversation on Monday with Glenn Block about Microsoft in regards to OSS, as a result Glenn asked me to write a post about what I would like to see Microsoft do.</p> <p>To be clear, everyone has their own opinions about what Microsoft is doing with Open Source Software, whats working, whats not, that isn&rsquo;t the point of this post. This is about what I would like to see, and why.</p> <h3>Promote itself with the community, not against it</h3> <p>One of the things I think Microsoft does is promote itself against the community, it has opened sourced MVC and WebAPI, but people outside the community don&rsquo;t know about the alternatives.</p> <p>I&rsquo;m not suggesting that Microsoft actively promotes frameworks like FubuMVC, NancyFX, ServiceStack etc as their own, or in such a way that it overshadows their own stuff. What I would like to see is Microsoft promoting itself along side other frameworks. A lot of the guys who create these other frameworks are advisories for MVC/WebAPI, they help make Microsoft frameworks better, and there&rsquo;s all the people who contribute, and in my personal opinion Microsoft doesn&rsquo;t really give anything back to the community through its main channels.</p> <!--excerpt--> <p>People in the community help the community, we all know this stuff exists, but a lot of us are stuck in jobs where we cannot use it because it&rsquo;s not &ldquo;Microsoft&rdquo;, I think if Microsoft helped promote itself with the community, people outside the community who hear of these things through the main channels would be more willing to integrate non-Microsoft technologies in their existing Microsoft solutions.</p> <h3>Ideas</h3> <p>I&rsquo;ve often thought it would be awesome for Microsoft to accept articles on <a href="http://www.asp.net">http://www.asp.net</a> that weren&rsquo;t related to MVC / WebAPI / Web Forms, etc. I would love to see articles to do with other web technologies. In terms of web technologies, this is the go to place for a lot of companies.</p> <h3>A little less emphasis on Microsoft technologies</h3> <p>I have to admit, Microsoft has pretty much redeemed themselves on this one, when MVC 3 and 4 came out they heavily pushed their own Templates in Visual Studio which forces a LOT of technologies. EntityFramework, WebAPI, etc etc.</p> <p>This to me has a negative effect on the community because these are all pushed via Nuget, ever increasing the number of downloads and making it seem these technologies are more popular and a better choice than alternatives.</p> <p>Microsoft has since created a Truely empty Web Application project which I&rsquo;m grateful for, but even their Empty MVC 4 project still contains WebAPI configuration.</p> <p>What I would like to see is Microsoft make creating templates MUCH easier for people, it would be great if owners of differ projects could much more easily create and maintain templates rather than throwing in the towel due to difficulty, or neglecting them because they are hard to maintain.</p> <h3>Your Ideas</h3> <p>I would love for anyone else reading this to add their own ideas on how they think Microsoft can help the Open Source Community. Either on Hacker News (linked below) or in the comments below. Or even blog your own ideas and let me know!</p> <p><a href="https://news.ycombinator.com/item?id=5479043">Hacker News Comments</a></p> My must have (short) list of programs/extensions etc... 2013-04-02T00:00:00-07:00 http://www.philliphaydon.com/2013/04/my-must-have-short-list-programs-extensions-etc/ <p>It&rsquo;s been 1 year since I posted my <a href="http://www.philliphaydon.com/2012/03/my-must-have-short-list-programs-and-extensions-etc/">list</a> , well.. 1 year has come and gone, and I missed posting this on the same date. None the less its April now and here&rsquo;s my post.</p> <h3>Visual Studio 2012</h3> <p>I&rsquo;m still a .NET Dev but ah&hellip; god it&rsquo;s painful going back to VS 2010&hellip; The new Black Theme makes this so much easier to use while sitting in the dark.</p> <h3>Still using</h3> <ul> <li><a href="http://www.jetbrains.com/resharper/">ReSharper</a></li> <li><a href="http://www.mindscapehq.com/products/web-workbench">Mindscape Web Workbench</a></li> <li><a href="http://www.bugaidsoftware.com/">BugAid</a></li> <li><a href="http://wiki.sharpdevelop.net/ilspy.ashx">ILSpy</a></li> <li><a href="http://www.sublimetext.com/2">SublimeText 2</a></li> </ul> <h3>Raygun.io</h3> <p><a href="http://raygun.io">http://raygun.io</a></p> <p>This Software as a Service for Error Handling has replaced my use of ELMAH. It&rsquo;s simply amazing. Been tracking errors in my applications more closely with this.</p> <!--excerpt--> <h3>Metro Studio 2</h3> <p><a href="http://www.syncfusion.com/downloads/metrostudio">http://www.syncfusion.com/downloads/metrostudio</a></p> <p>This is a free program which is rather handy, it allows you to create icons for use in XAML. Been very handy while creating my Windows Store App.</p> <h3>MarkdownPad 2</h3> <p><a href="http://markdownpad.com/">http://markdownpad.com/</a></p> <p>Since moving my blog to GitHub Pages, and writing everything in Markdown, this program is awesome. Great for being able to preview the parsed content before committing it.</p> <h3>RavenDB</h3> <p><a href="http://ravendb.net/">http://ravendb.net/</a></p> <p>RavenDB is now on V2 and I really wish I could use this in the workplace, it makes life so much easier and I believe using it has made me a better developer.</p> <h3>NancyFX</h3> <p><a href="http://www.nancyfx.org">http://www.nancyfx.org</a> / <em>project I currently contribute to</em></p> <p>NancyFX is a micro web framework, well not so sure it&rsquo;s <code>micro</code> anymore, but it&rsquo;s definitely smaller than MVC/WebForms. This is another framework I really wish I could use in the workplace. Makes working with the web a dream.</p> <h3>WorldDomination.Web.Authentication</h3> <p><a href="https://github.com/PureKrome/WorldDomination.Web.Authentication/">https://github.com/PureKrom&hellip;.Web.Authentication/</a> / <em>project I currently contribute to</em></p> <p>This project I created with Justin Adler, is an attempt to make OAuth easier to implement, by taking away all the <code>magic</code> and making the <code>magic</code> straight forward and easy to understand. I think we&rsquo;ve done a pretty good job and David Fowler has given us great input to make even better. It&rsquo;s currently being used by JabbR</p> <h3>JabbR</h3> <p><a href="https://jabbr.net">https://jabbr.net</a></p> <p>This is a chat-room created by David Fowler, built on SignalR, NancyFX, and WD.Web.Authentication. It&rsquo;s a great place to get help from other .NET developers and help others. Quite a few OSS projects like Service Stack, Nuget, NancyFX, etc all have rooms there, so it&rsquo;s great to get direct contact with the project authors.</p> <h3>MightyMoose / NCrunch</h3> <p><a href="http://www.continuoustests.com/">http://www.continuoustests.com/</a> / <a href="http://www.ncrunch.net/">http://www.ncrunch.net/</a></p> <p>I&rsquo;m still torn between these. Like em both&hellip;</p> <hr /> <p>And that&rsquo;s it, I haven&rsquo;t really changed much over the last year.</p> Everyone should get the opportunity to learn to program, but school is a waste of time 2013-03-04T00:00:00-08:00 http://www.philliphaydon.com/2013/03/everyone-should-get-the-opportunity-to-learn-to-program-but-school-is-a-waste-of-time/ <p>I just got done reading a <a href="http://blog.filipekberg.se/2013/03/04/everyone-should-learn-programming/">blog post</a> by <a href="https://twitter.com/fekberg">@fekberg</a> titled &ldquo;Everyone Should Learn Programming&rdquo;</p> <p>This idea that everyone should learn to program seems to be a growing trend. But I disagree.</p> <p>I don&rsquo;t think <code>everyone</code> should learn to program, I think everyone should get the opportunity to learn to program. Schooling in general is a waste of time because it caters to this idea that life evolves around English, Math, Art, Science and General Knowledge. But real life doesn&rsquo;t, and these things don&rsquo;t help children figure out what they are good at or enjoy.</p> <p>There&rsquo;s an awesome TED video by Sir Ken Robinson titled &ldquo;Do Schools Kill Creativity&rdquo;</p> <p><a href="http://www.youtube.com/watch?v=iG9CE55wbtY">http://www.youtube.com/watch?v=iG9CE55wbtY</a></p> <object width="480" height="360"><param name="movie" value="https://www.youtube.com/v/iG9CE55wbtY?hl=en_US&amp;version=3&amp;rel=0"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="https://www.youtube.com/v/iG9CE55wbtY?hl=en_US&amp;version=3&amp;rel=0" type="application/x-shockwave-flash" width="480" height="360" allowscriptaccess="always" allowfullscreen="true"></embed></object> <p><strong>It&rsquo;s worth watching, awesome talk and very funny</strong></p> <!--excerpt--> <p>We spend so much time teaching kids they are wrong, teaching them that they are failures because they fail subjects they aren&rsquo;t interested in, while not allowing them to do the things they are interested in.</p> <h2>A little about me</h2> <p>I got told I had <a href="http://en.wikipedia.org/wiki/Attention_deficit_disorder">ADD</a> and was put on drugs, and guess what, those drugs don&rsquo;t do ANYTHING. It made me act no differently at school, but the doctors had no problem selling them to my parents. Yet thinking about my schooling, the times I messed around and annoyed others, was when I was stuck in classes learning stuff that I was bored of.</p> <p>I was forced to learn History, despite the fact I love History and I watch documentaries ALL the time, learning about New Zealand history and common events is boring, I couldn&rsquo;t care less, I distinctly remember asking my teacher if we got to learn Egyption history, and being told it was not part of the curriculum.</p> <p>I don&rsquo;t remember anything about &lsquo;Social Studies&rsquo;, another boring subject I was forced to take. I hated english class because my opinion was &ldquo;I can speak English, why do I need to take an English class?&rdquo;.</p> <p>The only subjects I ever passed in school was Math, Science, and Technical Drawing (until they changed the subject to &ldquo;Drawing&rdquo;)</p> <p>My time at school was SO bad, my english teacher told my parents that there was no hope for me and I was going to be a bum.</p> <p>The best thing that happened to me though, was my Dad bought me a Commadore 64, with 3 games, and some BASIC 2 manuals. After playing the games, I learnt to program, I finished most of the book teaching me how to build a question/answer games and other super basic things, and taking what I learnt I built a Hang Man game with ascii graphics. I was 8 years old.</p> <p>I&rsquo;m about to turn 27, and despite the fact that I failed year 12 two years in a row and dropped out, and never went to university&hellip; I love my life, my job, and I amaze myself with how far I&rsquo;ve come, all because my DAD gave me the opportunity to learn to program.</p> <h2>My opinion</h2> <p>So I&rsquo;ve ranted on a little bit&hellip; what is my opinion?</p> <p>I think the entire schooling idea needs to be scrapped, it&rsquo;s not relevant by todays standards, and it needs to be re-invented to give kids the opportunity to learn not only all the things they need to learn in life, but allow them to focus on the things they are good at, and the things they enjoy.</p> <p>We need to STOP testing kids and telling them they aren&rsquo;t intelligent by grading them against other kids. Just because someone can memorize a book doesn&rsquo;t make them more intelligent than the kid next to them who struggled to read the book. Just because one kid is good at math and another is not, doesn&rsquo;t mean he should fail school.</p> <p>We need to develop education that allows kids to learn to the best of their ability and not force every kid to learn the same way.</p> <p>We hinder the progression of kids by grouping them by age rather than ability. We hinder them by making them learn the same way.</p> <p>We need to stop blaming kids and coming up with excuses because they don&rsquo;t learn the same way the rest of the kids do.</p> <p>We need to teach kids to think and learn, and stop indoctrinating education on them.</p> <p><strong>Edit</strong> I posted this on Hacker News, lots of good comments on there, for and against. Enjoyed reading them.</p> <p><a href="http://news.ycombinator.com/item?id=5318224">http://news.ycombinator.com/item?id=5318224</a></p> Windows Store App with Caliburn.Micro - Binding Converters 2013-02-26T00:00:00-08:00 http://www.philliphaydon.com/2013/02/windows-store-app-with-caliburn-micro-binding-converters/ <p>In my last post about <a href="http://www.philliphaydon.com/2013/01/windows-store-app-with-caliburn-micro-basic-binding">Basic Binding</a> we added the ability to Hide/Show a control using Viability property of the control to make it <code>Visible</code> or <code>Collapsed</code></p> <p>However the View Model shouldn&rsquo;t have any real knowledge of how the view works, meaning it shouldn&rsquo;t actually dictate the visibility using the controls properties.</p> <p><span class="note"><strong>Note:</strong> I left this out of the original post because I wanted to keep it &lsquo;Basic&rsquo; without confusing binding with converters and such, making the topic more complicated</span></p> <p>If in the future you changed from say <code>TextBlock</code> to a 3rd party control called <code>BananaTextBlock</code> and that 3rd party decided that they were not going to use the built in Viability enum, and instead decided to create their own naming convention, and enum etc. You would be forced to change your ViewModel, which isn&rsquo;t good.</p> <p>That&rsquo;s where Value Converters come in handy.</p> <!--excerpt--> <h2>Creating your own Converter</h2> <p>Value Converters are easy to implement, simply create a new class and inherit the <code>IValueConverter</code> interface. There are two methods you need to implement, the <code>Convert</code>, this is where you convert your object to the target type.</p> <p>i.e if your View Model uses a <code>Boolean</code>, you would accept the <code>Boolean</code> type and convert it to a <code>Visibility</code> type.</p> <p>The second method is ConvertBack, where it takes the control type and converts it back to the ViewModel type.</p> <pre><code>public sealed class BooleanToVisibilityConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, string language) { if (!(value is bool)) throw new ArgumentException("value is not type of boolean"); return (bool)value ? Visibility.Visible : Visibility.Collapsed; } public object ConvertBack(object value, Type targetType, object parameter, string language) { if (!(value is Visibility)) throw new ArgumentException("value is not type of Visibility"); return (Visibility)value == Visibility.Visible; } } </code></pre> <h2>Registering your Value Converter</h2> <p>You can do this in a couple of different places, it&rsquo;s similar to registering any other Resource.</p> <ul> <li>Page.Resources</li> <li>Application.Resources</li> <li>separate Resource file.</li> </ul> <p>I&rsquo;m only going to show it at Page.Resources</p> <p>In the root Page node of your view, add the namespace to your converts</p> <pre><code>xmlns:sp="using:SampleProject.Converters" </code></pre> <p>In your View, add a element called <code>Page.Resources</code> and then using the alias for the namespace just added <code>sp</code> reference the converter we just created.</p> <pre><code>&lt;Page.Resources&gt; &lt;sp:BooleanToVisibilityConverter x:Key="TrueConveter" /&gt; &lt;/Page.Resources&gt; </code></pre> <p>The <code>Key</code> is the name we will use when referencing the converter.</p> <h2>Updating the ViewModel from Visibility to Boolean</h2> <p>The original post used the Visibility enum, but we need to update this to be a boolean</p> <pre><code>public bool TextBlockVisibility { get { return _textBlockVisibility; } set { if (value == _textBlockVisibility) return; _textBlockVisibility = value; NotifyOfPropertyChange(); } } </code></pre> <p>The button we used to change the value is also updated</p> <pre><code>private void UpdateText() { TextBlockVisibility = !TextBlockVisibility; } </code></pre> <p>This will just invert the existing value each time it&rsquo;s clicked, like before.</p> <h2>Using the converter</h2> <p>Now we need to update the <code>TextBlock</code> from the original post</p> <pre><code>&lt;TextBlock FontSize="28" Text="{Binding Message}" Visibility="{Binding TextBlockVisibility}" /&gt; </code></pre> <p>To use the converter, in the binding we simply want to add a comma at the end and specify a Converter</p> <pre><code>&lt;TextBlock FontSize="28" Text="{Binding Message}" Visibility="{Binding TextBlockVisibility, Converter={StaticResource TrueConveter}}" /&gt; </code></pre> <p>Now when we run the app, and click the button, it should hide/show, and our ViewModel now no longer needs to know how to change the visibility of the control.</p> Windows Store App with Caliburn.Micro - Getting Started (Updated) 2013-02-20T00:00:00-08:00 http://www.philliphaydon.com/2013/02/windows-store-app-with-caliburn-micro-getting-started-updated/ <p><span class="note"><strong>Note:</strong> This is an update post for <a href="/2012/12/windows-store-app-with-caliburn-micro-getting-started/">Windows Store App with Caliburn.Micro &ndash; Getting Started</a></span></p> <p>Back in December I blogged about <a href="/2012/12/windows-store-app-with-caliburn-micro-getting-started/">getting started</a> with Caliburn.Micro, not long after I created the post a <a href="http://devlicio.us/blogs/rob_eisenberg/archive/2013/01/20/caliburn-micro-v1-4-1-released.aspx">new version</a> (v1.4.1) was released.</p> <p>The changes in this release break my previous blog post so I&rsquo;m updating here.</p> <p><span class="note"><strong>Note:</strong> The original post still applies, the change is only to the setup of the App</span></p> <h2>App Setup</h2> <p>In the previous post when we configured the container, all we needed to do was Register the WinRT Services.</p> <!--excerpt--> <pre><code>protected override void Configure() { container = new WinRTContainer(); container.RegisterWinRTServices(); } </code></pre> <p>However, the default container no longer auto creates concrete types, which causes View Models to not auto create. To fix this we do one of two things.</p> <h2>Manually Register Types</h2> <p>In the Configure method, we can manually register the View Model like so</p> <pre><code>protected override void Configure() { container = new WinRTContainer(); container.RegisterWinRTServices(); container.PerRequest&lt;MainViewModel&gt;(); } </code></pre> <p>Running the app, the View Model should now be created when you navigate to the View. The downside to this approach is that you need to do this for every view model which can be tedious.</p> <h2>Automate the Registration</h2> <p><span class="note"><strong>Note:</strong> This approach came from the samples.</span></p> <p>Instead of manually registering, we can automate it by over-riding the <code>GetInstance</code> method and manually registering the type if it doesn&rsquo;t exist.</p> <pre><code>private static bool IsConcrete(Type service) { var serviceInfo = service.GetTypeInfo(); return !serviceInfo.IsAbstract &amp;&amp; !serviceInfo.IsInterface; } protected override object GetInstance(Type service, string key) { var obj = container.GetInstance(service, key); // mimic previous behaviour of WinRT SimpleContainer if (obj == null &amp;&amp; IsConcrete(service)) { container.RegisterPerRequest(service, key, service); obj = container.GetInstance(service, key); } return obj; } </code></pre> <p>In this example we attempt to get the instance, if it doesn&rsquo;t exist, but it&rsquo;s a concrete type, then we register it and then Get/Return it.</p> <p>And that&rsquo;s it :)</p> Windows Store App - Adding Advertising 2013-02-14T00:00:00-08:00 http://www.philliphaydon.com/2013/02/windows-store-app-adding-advertising/ <p>I searched for hours trying to figure this out and I think the information is a little scarce or not obvious.</p> <p>Basically I wanted to add some advertising to my app, I&rsquo;m trying to cover multiple different area&rsquo;s in order to learn what&rsquo;s involved, and I thought I had it all down, only to work out that the advert&rsquo;s that were displaying were test adverts and not the real thing.</p> <p>Now don&rsquo;t get me wrong, when you actually do find the correct URL (by searching Advertising rather than Ad) the MSDN link does have all the information, I didn&rsquo;t find this out until my friend actually sent it to me&hellip;</p> <p><a href="http://msdn.microsoft.com/en-us/library/advertising-windows-sdk(v=msads.10).aspx">http://msdn.microsoft.com/en-us/library/advertising-windows-sdk(v=msads.10).aspx</a></p> <p>There&rsquo;s two main things you need to do (besides installing the correct SDK, I had the Beta first time around)</p> <ol> <li>Implement the advert into your app</li> <li>Setup an advertising account</li> </ol> <p>The first part is easy&hellip; (well the 2nd part is too&hellip; but I didn&rsquo;t realise that at first)</p> <!--excerpt--> <h2>Implementing your advert</h2> <p>Head on over to MSDN to download the <a href="http://go.microsoft.com/?linkid=9815330">Microsoft Advertising SDK</a> and install it.</p> <p>After installing, open up your solution and add a reference to the <code>Microsoft Advertising SDK for Windows 8 (Xaml)</code> assembly.</p> <p><img src="/images/win-app-ad-1.png" alt="" /></p> <p>Now you can use the Tools to drag/drop the advert control to your Xaml file.</p> <pre><code>&lt;ui:AdControl Name="Advert" Grid.Row="1" Width="728" Height="90" Margin="30,441,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" AdUnitId="10042998" ApplicationId="d25517cb-12d4-4699-8bdc-52040c712cab" /&gt; </code></pre> <p>The two things that are important are the <code>AdUnitId</code> and <code>ApplicationId</code>, the ApplicationId should get populated automatically using the test value. (the value shown in the code above) if not, you can manually assign it.</p> <p>To test your advert you need to add a <code>AdUnitId</code> specific to the dimensions you want to show, and for the type of advert you want to test.</p> <table> <tbody> <tr> <th> pubCenter Ad Unit Size (Width x Height) </th> <th> Experience </th> <th> AdUnitId </th> </tr> <tr> <td> 160 x 600 </td> <td> Windows 8 Image Ad with click to Full Screen Image </td> <td> 10043136 </td> </tr> <tr> <td> 160 x 600 </td> <td> Windows 8 Video Ad with click to Full Screen Video </td> <td> 10043135 </td> </tr> <tr> <td> 160 x 600 </td> <td> Windows 8 Image Ad </td> <td> 10043134 </td> </tr> </tbody> </table> <p>You can find a full list of test modes on <a href="http://msdn.microsoft.com/en-us/library/advertising-windows-test-mode-values(v=msads.10">MSDN &ndash; Test Mode Values</a>.aspx)</p> <p>Find the Height/Width you want, ensure your Ad control is set to the same Height/Width, and assign the corresponding <code>AdUnitId</code> to the control.</p> <p>Now when you run your app you should get something like</p> <p><img src="/images/win-app-ad-2.png" alt="" /></p> <p>The next thing you need to do is add some error handling. To do this you just add the event to the control directly like <code>ErrorOccurred="AdvertErrorOccurred"</code></p> <pre><code>void AdvertErrorOccurred(object sender, Microsoft.Advertising.WinRT.UI.AdErrorEventArgs e) { Advert.Visibility = Visibility.Collapsed; } </code></pre> <p>You may want to do something more, maybe try loading a different sized advert. I&rsquo;ve chosen to just hide the control instead.</p> <h2>Setup an advertising account</h2> <p>Head on over to <a href="https://pubcenter.microsoft.com/">https://pubcenter.microsoft.com/</a> and login with your Windows Live account (or signup)</p> <p>First you will need to head on over to the Accounts</p> <p><img src="/images/win-app-ad-3.png" alt="" /></p> <p>Once you have created an account (you don&rsquo;t need to add a payout right away, you can do that in the future when you&rsquo;ve generated some revenue), you need to head on over to Setup.</p> <p><img src="/images/win-app-ad-4.png" alt="" /></p> <p>You need to Register your application, and then you need to create an AdUnit. This stuff is really straight forward so should be easy peasy.</p> <p>Once you have registered your app (which gives you the <code>ApplicationId</code>) and created an AdUnit (which gives you the <code>AdUnitId</code>) you can replace the values in your app, and publish your app with advertising in it :D</p> <p>Although this information is available on the net, I initially had trouble finding it, so hopefully this helps anyone else out with confusion.</p> X-Http-Method-Override with NancyFX 2013-02-11T00:00:00-08:00 http://www.philliphaydon.com/2013/02/x-http-method-override-with-nancyfx/ <p>Forms in HTML only allow you to use the method&rsquo;s POST and GET, I&rsquo;m not sure if this would be classified as a limitation or not, but it does introduce a slight problem when you want to create a nice API taking advantage of verbs such as PUT and DELETE, when you can only POST and GET.</p> <p>This means if you want to delete something you have to use a different URL, like:</p> <p><code>/products/123/delete</code></p> <p>Then define a route like</p> <pre><code>Post["/products/{id}/delete"] = _ =&gt; { ... Do Something... }; </code></pre> <p>This isn&rsquo;t exactly ideal, what we would prefer to have is a more semantic route.</p> <ul> <li><code>GET</code> &ndash;> gets an object</li> <li><code>DELETE</code> &ndash;> deletes an object</li> <li><code>PUT</code> &ndash;> modifies an object</li> <li><code>PATCH</code> &ndash;> modifies part of an object</li> <li><code>POST</code> &ndash;> creates an object</li> </ul> <p><span class="note"><strong>Note:</strong> I&rsquo;m no expert on this stuff so the VERBs above may not be correct wording.</span></p> <p>This would allow us to define the same route like so</p> <pre><code>Delete["/products/{id}"] = _ =&gt; { ... Do Something... }; </code></pre> <!--excerpt--> <p>Since HTML forms only allow GET/POST, the web framework needs to do a little bit of trickery in order to send a request to the correct route/verb. In this case we want to use a POST but have it go to a DELETE route.</p> <p>MVC offers the ability to use the <code>HttpMethodOverride</code> helper to add a hidden input field to a form</p> <pre><code>@Html.HttpMethodOverride(HttpVerbs.Delete) </code></pre> <p>This will generate a hidden field like so</p> <pre><code>&lt;input name="X-HTTP-Method-Override" type="hidden" value="DELETE" /&gt; </code></pre> <p>NancyFX also allows you to override the Method, but the field is actually named <code>_method</code></p> <pre><code>&lt;input type="hidden" name="_method" value="DELETE"/&gt; </code></pre> <p><span class="note"><strong>Note:</strong> I&rsquo;m not actually sure <em>why</em> the NancyFX team decided to name it <code>_method</code> rather than <code>X-HTTP-Method-Override</code>, though from reading it seems if you&rsquo;re posting a form it should be <code>_method</code>, but if you&rsquo;re sending it via headers it should be <code>X-HTTP-Method-Override</code> (turns out they followed Sinatra)</span></p> <p>Give a super basic scenario, I defined a module</p> <pre><code>public ProductsModule() : base("products") { Get["/"] = _ =&gt; View["index", Products]; Delete["/{id}"] = _ =&gt; { Products.Remove(Products.Single(x =&gt; x.Id == (int)_.id)); return View["index", Products]; }; } </code></pre> <p>Products is just a static list products. The view contains the following</p> <pre><code>&lt;ul&gt; @Each.Model &lt;li&gt; &lt;form action="/products/@Current.Id" method="POST"&gt; &lt;label&gt;@Current.Name&lt;/label&gt; &lt;input type="submit" value="Delete"/&gt; &lt;/form&gt; &lt;/li&gt; @EndEach &lt;/ul&gt; </code></pre> <p><span class="note"><strong>Note:</strong> This demo is using the Nancy Super Simple View Engine, not Razor :)</span></p> <p>This renders the page like</p> <p><img src="/images/nancy-method-override-1.png" alt="" /></p> <p>Clicking on the delete button</p> <p><img src="/images/nancy-method-override-2.png" alt="" /></p> <p>As you can see, it doesn&rsquo;t hit the Delete route, so if we update the View to contain the <code>_method</code> field</p> <pre><code>&lt;ul&gt; @Each.Model &lt;li&gt; &lt;form action="/products/@Current.Id" method="POST"&gt; &lt;input type="hidden" name="_method" value="DELETE"/&gt; &lt;label&gt;@Current.Name&lt;/label&gt; &lt;input type="submit" value="Delete"/&gt; &lt;/form&gt; &lt;/li&gt; @EndEach &lt;/ul&gt; </code></pre> <p>And now click the delete button again</p> <p><img src="/images/nancy-method-override-3.png" alt="" /></p> <p>We can see that it hits the correct route.</p> <p><img src="/images/nancy-method-override-4.png" alt="" /></p> <p>And the item (Product 4) has been removed from the list. So that&rsquo;s it, super simple to override the Method verb in NancyFX :)</p> <p><span class="note"><strong>Note:</strong> At the time of writing this, version 0.15.3 only supports <code>_method</code> on form posts, but the next version will support both <code>X-HTTP-Method-Override</code> and <code>_method</code> on both Headers and Forms.</span></p> OAuth with ASP.NET MVC and WorldDomination.Web.Authentication 2013-02-05T00:00:00-08:00 http://www.philliphaydon.com/2013/02/oauth-with-asp-net-mvc-and-world-domination-authentication/ <p>This post is a follow on from my previous post <a href="/2013/01/oauth-with-nancyfx-and-world-domination-authentication/">OAuth with NancyFX and WorldDomination.Web.Authentication</a> except this demonstrates how you can use WorldDomination.Web.Authentication with ASP.NET MVC, writing only minimal code in the process.</p> <p>To save you jumping to the other post, I&rsquo;ll quote myself:</p> <blockquote><p>One of the biggest pains of building websites, in my opinion, is implementing OAuth providers, it&rsquo;s often fiddly, doesn&rsquo;t work, and frameworks that are created to try make things easier, don&rsquo;t seem to make it easier.</p> <p>So <a href="https://github.com/PureKrome">PureKrome</a> and myself decided to create <a href="http://www.nuget.org/packages/WorldDomination.Web.Authentication/">WorldDomination: Web Authentication</a></p> <p>The idea behind this framework is to keep it super simple to implement OAuth into your website, without the bloat. The core framework ONLY deals with Google, Twitter, and Facebook authentication. It doesn&rsquo;t try to create a fancy UI for you, it doesn&rsquo;t require you to write lots and lots of code. You simply give it some info, it redirects, it comes back and gives you the authentication info.</p></blockquote> <p>So without further adieu&hellip;</p> <h3>Installing</h3> <p>Installing the library for MVC requires installing the MVC specific library.</p> <blockquote><p>PM> Install-Package WorldDomination.Web.Authentication.Mvc</p></blockquote> <p>This will install:</p> <ul> <li>WorldDomination.Web.Authentication.Mvc</li> <li>WorldDomination.Web.Authentication</li> <li>RestSharp</li> </ul> <!--excerpt--> <p>The first package is the ASP.NET MVC provider, this wires up all the routes and handles the redirect and callback.</p> <p>The second package is the actual implementation, this has no dependency on <code>NancyContext</code> or <code>System.Web</code></p> <p>The last package is required by <code>WorldDomination.Web.Authentication</code> to process the callback and deserialize the response.</p> <h3>Configuring</h3> <p>Now that it&rsquo;s installed, we need to configure it, this is done one of two ways, by adding the information to the <code>web.config</code>, or by registering the information in the <code>Global.asax</code></p> <p>I&rsquo;m going to show the <code>web.config</code> way, but you can <a href="https://github.com/PureKrome/WorldDomination.Web.Authentication/wiki">visit the github wiki</a> for <code>WorldDomination.Web.Authentication</code> on information to configure via the Global.asax.</p> <p>In the <code>web.config</code> add a config section like so</p> <pre><code>&lt;section name="authenticationProviders" type="WorldDomination.Web.Authentication.Config.ProviderConfiguration, WorldDomination.Web.Authentication" /&gt; </code></pre> <p>Now add the <code>authenticationProviders</code> element.</p> <pre><code>&lt;authenticationProviders&gt; &lt;providers&gt; &lt;add name="Facebook" key="470874...41" secret="02bb584...332fe2" /&gt; &lt;add name="Google" key="58714009...ent.com" secret="npk...ooxCEY" /&gt; &lt;add name="Twitter" key="Rb7qNNP...znFTbF6Q" secret="pP...7hu9c" /&gt; &lt;/providers&gt; &lt;/authenticationProviders&gt; </code></pre> <p><span class="note"><strong>Note:</strong> These are the key/secret you get when you register your application with the providers.</span></p> <p>You can get the key/secret registering your apps:</p> <ul> <li>Facebook: http://developers.facebook.com/docs/howtos/login/server-side-login/</li> <li>Twitter: https://dev.twitter.com/</li> <li>Google: https://code.google.com/apis/console/?pli=1#access</li> </ul> <p><span class="note"**Note:** Please refer to the 'Adding some buttons' section on the URLs for use when registering.</span></p> <h3>Registering the routes</h3> <p>Unlike Nancy, we need to tell Mvc to register the routes, if you don&rsquo;t mind using the built in routes you can simply call the registration, passing in the route table, and you will get the default routes described in the rest of this blog post.</p> <pre><code>WorldDominationRouteConfig.RegisterRoutes(RouteTable.Routes); </code></pre> <p><span class="note"**Note:** This must be registered BEFORE your own routes, otherwise your default route will override the WorldDomination specific routes and then you will end up with issues such as the controller doesn't exist.</span></p> <p>The routes registered are two specific ones:</p> <pre><code>routes.MapRoute( name: "WorldDominationAutomatedMvc-Redirect", url: "authentication/redirect/{providerkey}/{additionaldata}", defaults: new { controller = "WorldDominationAuthentication", action = "RedirectToProvider", additionaldata = UrlParameter.Optional } ); routes.MapRoute( name: "WorldDominationAutomatedMvc-AuthenticateCallback", url: "authentication/authenticatecallback", defaults: new { controller = "WorldDominationAuthentication", action = "AuthenticateCallback" } ); </code></pre> <p>Alternatively if you want to specify your own routes, you can copy the route registration above and define your own paths.</p> <h3>Implementing your callback</h3> <p>Now you need to implement a callback, this callback is what YOU want to do with the result from a successful (or failed) authentication, you need to implement this because we don&rsquo;t know what you have planned, if you want to create a session, set a cookie, use form authentication, what ever, that&rsquo;s up to you.</p> <p>To do this you can create a new class and implement the interface <code>IAuthenticationCallbackProvider</code></p> <pre><code>public class SampleCallbackProvider : IAuthenticationCallbackProvider { public ActionResult Process(HttpContextBase context, AuthenticateCallbackData model) { return new ViewResult { ViewName = "AuthenticateCallback", ViewData = new ViewDataDictionary(model) }; } } </code></pre> <p>This example will simply respond with the view <code>AuthenticateCallback</code> and pass it the model with the data returned from the provider. Ideally you would check to see if the user is new, or if you need to add him to your database, or authenticate him with your system.</p> <p>You can take a look at the implementation used by JabbR <a href="https://github.com/davidfowl/JabbR/blob/master/JabbR/Nancy/JabbRAuthenticationCallbackProvider.cs">here</a>, which I&rsquo;ve mirrored as a <a href="https://gist.github.com/4674109">gist here</a> in-case it is changed or moved and the link becomes dead.</p> <p>Although the JabbR implementation is for NancyFX, it will give you an idea of what you can achieve. The main difference is the MVC version will pass you the HttpContext of the current controller, while the NancyFX one passes you the NancyModule. The implementation would be pretty much identical.</p> <h3>Adding some buttons</h3> <p>Last of all, you need to add some buttons to the screen. This is where you have to link to some specific URLs.</p> <p><span class="note"><strong>Note:</strong> These links will be configurable in the future, but for now they are hard-coded.</span></p> <p>The two URLs used by the system are:</p> <ul> <li>Redirect: /authentication/redirect/<em>provider key</em></li> <li>Callback: /authentication/authenticatecallback?providerkey=<em>provider key</em></li> </ul> <p>Examples: The links you would add to your page would be similar to:</p> <pre><code>&lt;a href="/authentication/redirect/Twitter"&gt;&lt;img src="/Content/twitter_32.png" /&gt;&lt;/a&gt; &lt;a href="/authentication/redirect/Facebook"&gt;&lt;img src="/Content/facebook_32.png" /&gt;&lt;/a&gt; &lt;a href="/authentication/redirect/Google"&gt;&lt;img src="/Content/google_32.png" /&gt;&lt;/a&gt; </code></pre> <p>These links are just normal hyperlinks, giving you absolute freedom and flexibility to style them any way you want. Because we have absolutely NO involvement in the generation of the links, we cannot get in the way.</p> <p>All you need to do is ensure that the links provided to us look like the above.</p> <p>Your callback urls would end up looking like:</p> <ul> <li>/authentication/authenticatecallback?providerkey=twitter</li> <li>/authentication/authenticatecallback?providerkey=facebook</li> <li>/authentication/authenticatecallback?providerkey=google</li> </ul> <p><span class="note"><strong>Note:</strong> The urls are forced to be lowercase because Google is case sensitive, so when registering your app with google please make sure the url is registered all lowercase.</span></p> <p>And you&rsquo;re done!</p> <p>Now you can run your app:</p> <p><img src="/images/jabbr-authentication-sample-1.png" alt="" /></p> <p>We click on Google:</p> <p><img src="/images/jabbr-authentication-sample-2.png" alt="" /></p> <p>And we get redirected back to the website after allowing the authentication with Google:</p> <p><img src="/images/jabbr-authentication-sample-3.png" alt="" /></p> <p>That&rsquo;s all there is to it.</p> <p>The sample can be found on github here:</p> <ul> <li><a href="https://github.com/PureKrome/WorldDomination.Web.Authentication/tree/master/Samples/MvcAutomatedSample">https://github.com/PureKrome/WorldDomination.Web.Authentication/tree/master/Samples/MvcAutomatedSample</a></li> </ul> <p>You can find the source code on github:</p> <ul> <li><a href="https://github.com/PureKrome/WorldDomination.Web.Authentication">https://github.com/PureKrome/WorldDomination.Web.Authentication</a></li> </ul> <p>And the Nuget packages</p> <ul> <li><a href="http://www.nuget.org/packages/WorldDomination.Web.Authentication/">http://www.nuget.org/packages/WorldDomination.Web.Authentication/</a></li> <li><a href="http://www.nuget.org/packages/WorldDomination.Web.Authentication.Mvc/">http://www.nuget.org/packages/WorldDomination.Web.Authentication.Mvc/</a></li> </ul> OAuth with NancyFX and WorldDomination.Web.Authentication 2013-01-31T00:00:00-08:00 http://www.philliphaydon.com/2013/01/oauth-with-nancyfx-and-world-domination-authentication/ <p>One of the biggest pains of building websites, in my opinion, is implementing OAuth providers, it&rsquo;s often fiddly, doesn&rsquo;t work, and frameworks that are created to try make things easier, don&rsquo;t seem to make it easier.</p> <p>So <a href="https://github.com/PureKrome">PureKrome</a> and myself decided to create <a href="http://www.nuget.org/packages/WorldDomination.Web.Authentication/">WorldDomination: Web Authentication</a></p> <p>The idea behind this framework is to keep it super simple to implement OAuth into your website, without the bloat. The core framework ONLY deals with Google, Twitter, and Facebook authentication. It doesn&rsquo;t try to create a fancy UI for you, it doesn&rsquo;t require you to write lots and lots of code. You simply give it some info, it redirects, it comes back and gives you the authentication info.</p> <p>Just recently the guys contributing to JabbR decided to use the library, and with feedback we added some really awesome support for NancyFX which I will show.</p> <h3>Installing</h3> <p>Installing the libary for Nancy requires installing the Nancy specific library.</p> <blockquote><p>PM> Install-Package Nancy.Authentication.WorldDomination</p></blockquote> <p>This will install:</p> <ul> <li>Nancy.Authentication.WorldDomination</li> <li>WorldDomination.Web.Authentication</li> <li>RestSharp</li> </ul> <!--excerpt--> <p>The first package is the Nancy provider, this wires up all the routes and handles the redirect and callback.</p> <p>The second package is the actual implementation, this has no dependency on <code>NancyContext</code> or <code>System.Web</code></p> <p>The last package is required by <code>WorldDomination.Web.Authentication</code> to process the callback and deserialize the response.</p> <h3>Configuring</h3> <p>Now that it&rsquo;s installed, we need to configure it, this is done one of two ways, by adding the information to the <code>web.config</code>, or by registering the information in the <code>Bootstrapper</code></p> <p>I&rsquo;m going to show the <code>web.config</code> way, but you can visit the github wiki for <code>WorldDomination.Web.Authentication</code> on information to configure via the bootstrapper.</p> <p>In the <code>web.config</code> add a config section like so</p> <pre><code>&lt;section name="authenticationProviders" type="WorldDomination.Web.Authentication.Config.ProviderConfiguration, WorldDomination.Web.Authentication" /&gt; </code></pre> <p>Now add the <code>authenticationProviders</code> element.</p> <pre><code>&lt;authenticationProviders&gt; &lt;providers&gt; &lt;add name="Facebook" key="470874...41" secret="02bb584...332fe2" /&gt; &lt;add name="Google" key="58714009...ent.com" secret="npk...ooxCEY" /&gt; &lt;add name="Twitter" key="Rb7qNNP...znFTbF6Q" secret="pP...7hu9c" /&gt; &lt;/providers&gt; &lt;/authenticationProviders&gt; </code></pre> <p><span class="note"><strong>Note:</strong> These are the key/secret you get when you register your application with the providers.</span></p> <p>You can get the key/secret registering your apps:</p> <ul> <li>Facebook: http://developers.facebook.com/docs/howtos/login/server-side-login/</li> <li>Twitter: https://dev.twitter.com/</li> <li>Google: https://code.google.com/apis/console/?pli=1#access</li> </ul> <p><span class="note"**Note:** Please refer to the 'Adding some buttons' section on the URLs for use when registering.</span></p> <h3>Implementing your callback</h3> <p>Now you need to implement a callback, this callback is what YOU want to do with the result from a successful (or failed) authentication, you need to implement this because we don&rsquo;t know what you have planned, if you want to create a session, set a cookie, use form authentication, what ever, that&rsquo;s up to you.</p> <p>To do this you can create a new class and implement the interface <code>IAuthenticationCallbackProvider</code></p> <pre><code>public class Test : IAuthenticationCallbackProvider { public dynamic Process(NancyModule nancyModule, AuthenticateCallbackData model) { return nancyModule.Negotiate.WithView("AuthenticateCallback").WithModel(model); } } </code></pre> <p>This example will simply respond with the view <code>AuthenticateCallback</code> and pass it the model with the data returned from the provider. Ideally you would check to see if the user is new, or if you need to add him to your database, or authenticate him with your system.</p> <p>You can take a look at the implementation used by JabbR <a href="https://github.com/davidfowl/JabbR/blob/master/JabbR/Nancy/JabbRAuthenticationCallbackProvider.cs">here</a>, which I&rsquo;ve mirrored as a <a href="https://gist.github.com/4674109">gist here</a> incase it is changed or moved and the link becomes dead.</p> <p>If you&rsquo;re using Nancy with the default TinyIoC container, you don&rsquo;t need to register anything, it will automatically be picked up by <code>Nancy.Authentication.WorldDomination</code> and called.</p> <h3>Adding some buttons</h3> <p>Last of all, you need to add some buttons to the screen. This is where you have to link to some specific URLs.</p> <p><span class="note"><strong>Note:</strong> These links will be configurable in the future, but for now they are hard-coded.</span></p> <p>The two URLs used by the system are:</p> <ul> <li>Redirect: /authentication/redirect/<em>provider key</em></li> <li>Callback: /authentication/authenticatecallback?providerkey=<em>provider key</em></li> </ul> <p>Examples: The links you would add to your page would be similar to:</p> <pre><code>&lt;a href="/authentication/redirect/Twitter"&gt;&lt;img src="/Content/twitter_32.png" /&gt;&lt;/a&gt; &lt;a href="/authentication/redirect/Facebook"&gt;&lt;img src="/Content/facebook_32.png" /&gt;&lt;/a&gt; &lt;a href="/authentication/redirect/Google"&gt;&lt;img src="/Content/google_32.png" /&gt;&lt;/a&gt; </code></pre> <p>These links are just normal hyperlinks, giving you absolute freedom and flexibility to style them any way you want. Because we have absolutely NO involvement in the generation of the links, we cannot get in the way.</p> <p>All you need to do is ensure that the links provided to us look like the above.</p> <p>Your callback urls would end up looking like:</p> <ul> <li>/authentication/authenticatecallback?providerkey=twitter</li> <li>/authentication/authenticatecallback?providerkey=facebook</li> <li>/authentication/authenticatecallback?providerkey=google</li> </ul> <p><span class="note"><strong>Note:</strong> The urls are forced to be lowercase because Google is case sensitive, so when registering your app with google please make sure the url is registered all lowercase.</span></p> <p>And you&rsquo;re done!</p> <p>Now you can run your app:</p> <p><img src="/images/jabbr-authentication-sample-1.png" alt="" /></p> <p>We click on Google:</p> <p><img src="/images/jabbr-authentication-sample-2.png" alt="" /></p> <p>And we get redirected back to the website after allowing the authentication with Google:</p> <p><img src="/images/jabbr-authentication-sample-3.png" alt="" /></p> <p>That&rsquo;s all there is to it.</p> <p>The sample can be found on github here:</p> <ul> <li><a href="https://github.com/PureKrome/WorldDomination.Web.Authentication/tree/master/Samples/WorldDomination.Web.Authentication.Test.NancyFX2">https://github.com/PureKrome/WorldDomination.Web.Authentication/tree/master/Samples/WorldDomination.Web.Authentication.Test.NancyFX2</a></li> </ul> <p>You can find the source code on github:</p> <ul> <li><a href="https://github.com/PureKrome/WorldDomination.Web.Authentication">https://github.com/PureKrome/WorldDomination.Web.Authentication</a></li> </ul> <p>And the Nuget packages</p> <ul> <li><a href="http://www.nuget.org/packages/WorldDomination.Web.Authentication/">http://www.nuget.org/packages/WorldDomination.Web.Authentication/</a></li> <li><a href="http://www.nuget.org/packages/Nancy.Authentication.WorldDomination/">http://www.nuget.org/packages/Nancy.Authentication.WorldDomination/</a></li> </ul> Introducing Raygun.io and Nancy.Raygun 2013-01-29T00:00:00-08:00 http://www.philliphaydon.com/2013/01/introducing-raygun-and-nancy-raygun/ <p>So not long ago I <a href="/2012/10/keep-an-eye-on-raygun-to-zap-all-your-errors-away/">posted</a> about an up and coming service from <a href="http://www.mindscapehq.com">http://www.mindscapehq.com</a> called <a href="http://www.raygun.io">Raygun</a>, well last week they went into beta, and I was invited, so since early last week I&rsquo;ve been giving their system the run around and provided a little bit of feedback.</p> <p>I say a little bit, because besides being a super early beta tester, and a super early product that will grow over time, the beta is quite polished. There was only a few minor issues which they corrected within a day or less.</p> <p><img src="/images/raygun-beta-robby-1.png" alt="" /></p> <p>Raygun is super easy to setup and implement into your application, in-fact it&rsquo;s really nothing more than creating an app, install the nuget package, and set the key, and away you go.</p> <p>There&rsquo;s a simple guide over <a href="http://www.pieterg.com/2013/1/raygunio-has-launched">http://www.pieterg.com/2013/1/raygunio-has-launched</a>, so I won&rsquo;t bore you with the same content.</p> <h2>Nancy.Raygun</h2> <p>Currently the <a href="https://www.nuget.org/packages/Mindscape.Raygun4Net/">offical Nuget package</a> has a dependency on System.Web which isn&rsquo;t very nice for Nancy, so I&rsquo;ve created <a href="https://www.nuget.org/packages/Nancy.Raygun/">Nancy.Raygun</a></p> <p>It has no dependency on <code>System.Web</code>, and uses the <code>NancyContext</code> rather than <code>HttpContext.Current</code>, it also implements <code>IApplicationStartup</code> so that it automatically wires itself up for handling errors for you.</p> <p>Nancy.Raygun is on <a href="https://github.com/phillip-haydon/Nancy.Raygun">Github</a>, installing the nuget package will add the web.config for you so all you need to do is add the key and away you go.</p> <h2>Why Raygun?</h2> <p>I&rsquo;ve had a few people ask me why I would use Raygun over ELMAH, or AppFail.</p> <!--excerpt--> <p>ELMAH means I have to manage all the exceptions myself, I have to specify where I log it, navigate a clunky unstyled website, besides being an awesome alternative to something like log4net or nlog, it really is out-dated by today&rsquo;s standards.</p> <p>I have no personal experience with AppFail, and their service is similar, but the main difference is I know Mindscape, they are an awesome team that produce an awesome set of tools like LightSpeed, Web Workbench, and even went out of their way to add a control to their Metro Elements for me. I know what I&rsquo;m getting is an awesome and will only get more awesome as time goes on.</p> <p>So right now, I&rsquo;ve ripped out ELMAH from all my projects and replaced it with Raygun, and I&rsquo;m not looking back at all.</p> Introducing Sandra.SimpleValidation - Validation reinvented... again 2013-01-25T00:00:00-08:00 http://www.philliphaydon.com/2013/01/introducing-sandra-simplevalidator-validation-reinvented-again/ <p>Yup, I decided to reinvent the wheel, don&rsquo;t hate on me :)</p> <p>So I grew a little fustrated, theres quite a few serverside validation libraries around, but I feel they do too much, are hard to test, yada yada yada&hellip;</p> <p>So I came up with Sandra.SimpleValidation</p> <p>The idea is that it&rsquo;s dead simple, it requires 0 up front configuration, it doesn&rsquo;t allow you to inject stuff into the validators, validators are newed up once and only once, there&rsquo;s no client-side validation.</p> <p>I don&rsquo;t believe validation should allow you to do things like inject a repository and query the database, those begin to become Business Rules and should be handled seperately. All it does is validate a model you give it.</p> <p>So what do you need to do?</p> <blockquote><p>PM> Install-Package Sandra.SimpleValidator</p></blockquote> <p>First up, install the package. It requires 4.0 or above, it could probably work on 3.5 but who uses that anymore?</p> <!--excerpt--> <p>Once installed, you can create a validator</p> <pre><code>public class UserValidator : ValidateThis&lt;User&gt; { public UserValidator() { For(x =&gt; x.Username) .Ensure(new Required()); For(x =&gt; x.Email) .Ensure(new Required()) .Ensure(new Email()); For(x =&gt; x.Locale) .Ensure(new Required()); } } </code></pre> <p>If you don&rsquo;t like the default messages you can change those by chaining the rule like so</p> <pre><code>public class UserValidator : ValidateThis&lt;User&gt; { public UserValidator() { For(x =&gt; x.Username) .Ensure(new Required().WithMessage("Username is required"); ... } } </code></pre> <p>Now you can inject (or create an instance of) the <code>ValidationService</code>.</p> <p>Using Nancy with the default <code>TinyIoC</code> container, you can just include this in the module constructor. If you&rsquo;re using MVC you may need to register it depending on the container you&rsquo;re using. In any case it can be a singleton since it only needs to be created once.</p> <pre><code>public class HomeModule : NancyModule { public HomeModule(ValidationService validate) { Get["/"] = _ =&gt; { var user = this.Bind&lt;User&gt;(); var validationResult = validate.This(user); if (validationResult.IsInvalid) { //Handle errors with //validationResult.Messages return "Validation has fails :("; } return "Validation was successful :)"; }; } } </code></pre> <p>Once you&rsquo;ve injected the service, you simply call <code>This(...)</code> passing in the object you want to validate. With the result you can then call <code>IsValid</code> or <code>IsInvalid</code> and handle the errors.</p> <p>What&rsquo;s nice about the validator class is that because it&rsquo;s so simple, it&rsquo;s simple to test. Given the example above, we can write a unit test like so.</p> <pre><code>[Fact] public void Given_Valid_Model_Should_Return_IsValid_As_True() { var validator = new UserValidator(); var model = new User { Username = "HelloWorld", Email = "test@banana.com", Locale = "en-AU" }; var result = validator.Validate(model); Assert.True(result.IsValid); } </code></pre> <p>That&rsquo;s all there is to it. Currently as of writing this it only supports <code>Required</code>, <code>MinimumLength</code>, <code>MaximumLength</code>, <code>Between</code>, and <code>Email</code> rules. Since that&rsquo;s all I require for my current project. If you want to create your own simply implement <code>IRule</code> and new them up in the <code>Ensure</code> method of the validators.</p> <p>In the future I hope to get Nancy intergration so the validation can be invoked on <code>this.Bind&lt;T&gt;()</code>, but for now you can find the github repo, and nuget</p> <p><a href="https://github.com/phillip-haydon/Sandra.SimpleValidator">https://github.com/phillip-haydon/Sandra.SimpleValidator</a> <a href="https://www.nuget.org/packages/Sandra.SimpleValidator">https://www.nuget.org/packages/Sandra.SimpleValidator</a></p> Windows Store App with Caliburn.Micro - Basic Databinding 2013-01-17T00:00:00-08:00 http://www.philliphaydon.com/2013/01/windows-store-app-with-caliburn-micro-basic-binding/ <p>Continuing on with the SampleProject for a Windows Store App, we will look at binding, this is where we will finally make use of the ViewModel.</p> <p>In the previous example we output the text &lsquo;Hello World&rsquo; to the screen, but rather than put it on the screen directly we can load it when we load the view.</p> <p>First we need to create a ViewModel, Caliburn works on a naming convention so if your view is named <code>MainView</code>, your view model needs to be naned <code>MainViewModel</code>.</p> <p><img src="/images/windows-store-binding-1.png" alt="" /></p> <p>In our class we want to inherit from <code>Screen</code>, this is a Caliburn class that is used to represent a single screen, your application may have many screens but for now we are only dealing with a single screen.</p> <pre><code>using Caliburn.Micro; namespace SampleProject.ViewModels { public class MainViewModel : Screen { } } </code></pre> <!--excerpt--> <p>Screen doesn&rsquo;t require us to implement anything, but it does handle a few things for us, it implements <code>INotifyPropertyChangedEx</code>, which inherits from <code>INotifyPropertyChanged</code>, which is great because this is exactly what we need!</p> <p>Next we need to add a new property, but this can&rsquo;t be an autoproperty, we need a backing field so we can invoke <code>NotifyOfPropertyChange</code></p> <pre><code>private string _message; public string Message { get { return _message; } set { if (value == _message) return; _message = value; NotifyOfPropertyChange(); } } </code></pre> <p>This is basically what Resharper generates for us, if we create an autoproperty, we can convert it to a property with backing field that calls <code>NotifyOfPropertyChange</code></p> <p><img src="/images/windows-store-binding-2.png" alt="" /></p> <p>Now we need to set our message, we are going to do this when the ViewModel is initialized.</p> <pre><code>protected override void OnInitialize() { base.OnInitialize(); Message = "Saying: Hello World! :)"; } </code></pre> <p>Last of all we need to wire up the <code>TextBlock</code> control to the property, there&rsquo;s a few different ways you can do this, but generally you want to use the <code>{Binding *property*}</code> syntax.</p> <p>We can update our button to add the binding to the Text Field.</p> <pre><code>&lt;TextBlock Text="{Binding Message}" FontSize="28"/&gt; </code></pre> <p>Now when we run our app we get the message written in the OnInitialize.</p> <p><img src="/images/windows-store-binding-3.png" alt="" /></p> <p>If we want to update the text, when we set the <code>Message</code> property, the <code>NotifyOfPropertyChange</code> will be fired and the screen will update with the new text. To show you I&rsquo;ve added a button to the screen which invokes a method on the ViewModel.</p> <pre><code>private void UpdateText() { Message = "This text was updated"; } </code></pre> <p><span class="note"><strong>Note:</strong> Don&rsquo;t worry about how this button event is wired up, I&rsquo;ll get to that in future posts.</span></p> <p>When we view the screen we get the default text.</p> <p><img src="/images/windows-store-binding-4.png" alt="" /></p> <p>And when we hit the button, the text is updated.</p> <p><img src="/images/windows-store-binding-5.png" alt="" /></p> <p>Bindings can be added to pretty much any property you want, for example if we updated the button to change the visibility of the text we can add a new property to the ViewModel.</p> <pre><code>private Visibility _textBlockVisibility; public Visibility TextBlockVisibility { get { return _textBlockVisibility; } set { if (value == _textBlockVisibility) return; _textBlockVisibility = value; NotifyOfPropertyChange(); } } </code></pre> <p>Then update the button to alternate the visibility.</p> <pre><code>private void UpdateText() { var isVisible = TextBlockVisibility == Visibility.Visible; TextBlockVisibility = isVisible ? Visibility.Collapsed : Visibility.Visible; } </code></pre> <p>And finally add the binding to the TextBlock.</p> <pre><code>&lt;TextBlock FontSize="28" Text="{Binding Message}" Visibility="{Binding TextBlockVisibility}" /&gt; </code></pre> <p>Now when we view the page we get the default message.</p> <p><img src="/images/windows-store-binding-4.png" alt="" /></p> <p>If we hit the button, the message disappears&hellip;</p> <p><img src="/images/windows-store-binding-6.png" alt="" /></p> <p>Next I hope to look into a collection of data.</p> IT-Communities like Hacker News are full of assholes 2013-01-14T00:00:00-08:00 http://www.philliphaydon.com/2013/01/it-communities-like-hacker-news-are-full-of-assholes/ <p>I only found out about hacker news maybe&hellip; 6 months ago? This place is like 4chan for the IT-Community, and it&rsquo;s not the only place. The entire internet is full of assholes.</p> <p>Filip Ekberg wrote an opinionated <a href="http://blog.filipekberg.se/2013/01/11/c-is-the-past-the-present-and-the-future/">blog post</a> a few days ago, about how he thinks C# is the past, present and future. After <a href="http://news.ycombinator.com/item?id=5042055">self promotion</a> on Hacker News, I&rsquo;m sure a lot of people do, such as <a href="http://news.ycombinator.com/submitted?id=philliphaydon">myself</a>. He got an out pour of comments.</p> <blockquote><p>&ldquo;I am a Software Engineer working with various techniques such as C#, WPF, WCF, ASP.NET MVC, ASP.NET and much more&rdquo;<br> &ldquo;I spend most of my days working with the latest technologies from Microsoft.&rdquo;<br> &ldquo;In the darkest alley-ways we still have the people not wanting to touch C# with a pitch-fork because it&rsquo;s behind Microsoft&rdquo;<br> In my opinion he lacks enough neutrality to make that statements(how he know MS tech is so great if he is totally ignorant of other options?).<br> Instead of telling people to learn only Microsoft tech he could take his own advise and learn non Microsoft tech too. The world is much bigger than a single company.<br> In my work as a software engineer I had to use what was good for my company, not what was good for Microsoft, Apple, or any religion(GNU or whatever).<br> I had to use Java, C#, objective C, python, (and lisp and c and c++). We will never be in the hands of a single company ever.</p></blockquote> <!--excerpt--> <blockquote><p>He clearly works for MS and probably on the team that works on C#, which is why I find it odd that he touts Mono as a feature. If MS was serious about .NET everywhere, they&rsquo;d sponsor Mono/Xamarin, or offer native .NET support for OSX and Linux instead of using the Mono community&rsquo;s hard work to toot their own horn.<br> C# is a great language and has evolved beautifully, but many people will still continue to avoid it because it&rsquo;s owned by MS and stuck on Windows (without the help of Mono). The next Google, Facebook or Twitter won&rsquo;t be written with C#.</p></blockquote> <!-- --> <blockquote><p>I would like to try it out but I&rsquo;m not on Windows obviously, and I won&rsquo;t work to become a second class citizen (&ldquo;What do you use? Mono? That&rsquo;s not supported&rdquo;).<br> Also, most of tooling seems to be proprietary, Windows-only too.<br> So I&rsquo;d stick to JVM.</p></blockquote> <!-- --> <blockquote><p>He&rsquo;s a junior MVP, of course it has to look like an ad :)</p></blockquote> <p>These are just some of the comments that appeared on Hacker News.</p> <p>The IT-Community is a joke, that we as a collective community spanning 100&rsquo;s or 1000&rsquo;s or more, platforms, languages, frameworks etc, have to resort to personal attacks, and the same old generic bullshit arguments despite how far anything progresses.</p> <p>I don&rsquo;t think I&rsquo;m immune to all this, as a .NET Developer I rant against Microsoft for the stupid things I think they do, I don&rsquo;t like ASP.NET MVC after playing with other frameworks that the .NET Community has some up with, and I&rsquo;m always ranting about how shit Entity Framework is, but I&rsquo;m not personally attacking someone or singling out an entire framework just because it was developed by a single company.</p> <p>Everything has it&rsquo;s pros and cons, but a con isn&rsquo;t &ldquo;OH it&rsquo;s developed by Apple&rdquo; or &ldquo;Oh it&rsquo;s created by Microsoft&rdquo;, a con isn&rsquo;t &ldquo;It&rsquo;s a clone of Java&rdquo; that&rsquo;s all just your ignorance bleeding through.</p> <p>Yes C# is created by Microsoft, does that make C# bad? No. Does it mean you shouldn&rsquo;t learn it? No.</p> <p>People need to stop being so negative towards others in the community, if someone has an opinion like Filip, and you disagree, come up with a constructive argument about why you disagree. You may teach Filip and the community something! Hell, someone might respond to you and you may learn something in return!</p> <p>The good in the community is when we learn from each others ideas and discussions, whether it&rsquo;s Microsoft creating LINQ and everyone mimics it in other languages the best they can, or the Ruby community coming up with Sinatra and it being the inspiration for NancyFX in the .NET community.</p> <p>Stop being an asshole just because you can be anonymous on the internet.</p> Using publish to deploy Azure Cloud Service 2013-01-10T00:00:00-08:00 http://www.philliphaydon.com/2013/01/using-publish-to-deploy-azure-cloud-service/ <p>In my previous <a href="/2013/01/creating-an-azure-cloud-service">post</a> I created an Azure Cloud Service from scratch and deployed it, however I manually logged into Azure Portal and uploaded the packages.</p> <p><a href="http://twitter.com/cloudnick">@cloudnick</a> commented saying that I could that you can use publish directly from Visual Studio. So!</p> <h2>Publishing from Visual Studio directly to Azure</h2> <p>Using the exact same setup as yesterday, rightclick the MyWorker project and select Publish.</p> <p><img src="/images/azure-service-update-1.png" alt="" /></p> <p>Select <code>Sign in to download crentials</code></p> <p><img src="/images/azure-service-update-2.png" alt="" /></p> <p>This will take you to a webpage where you can sign into your Windows Live account that has your Azure Subscriptions, with some instructions. The file will download automatically.</p> <!--excerpt--> <p><img src="/images/azure-service-update-3.png" alt="" /></p> <p>Now go back to Visual Studio and import the file.</p> <p><img src="/images/azure-service-update-4.png" alt="" /></p> <p>This will open a new screen with some options, it will pre-select any existing cloud service you have, or you can create a new one by dropping down the menu and selecting &lsquo;Create New&hellip;&rsquo; if you don&rsquo;t already have one created you can create a new one.</p> <p>I&rsquo;m going to select the existing one.</p> <p><img src="/images/azure-service-update-5.png" alt="" /></p> <p>View the summary to save the profile, that way you can re-use it for future deployments. If you press save and want to rename it, you can drop the menu down and select Manage, then you can modify the name.</p> <p><img src="/images/azure-service-update-6.png" alt="" /></p> <p>If all is successful, Visual Studio will open up a Windows Azure Acvitity Log which will show you the deployment process.</p> <p><img src="/images/azure-service-update-7.png" alt="" /></p> <p>This process takes a little while, I guess it depends on your internet connection, I&rsquo;m on a pretty fast connection but I&rsquo;m in Singapore, so latency is quite a bit to the US.</p> <p>Infact it took a about 3 minutes to deploy, for most of that time it looked like.</p> <p><img src="/images/azure-service-update-8.png" alt="" /></p> <p>But don&rsquo;t worry, if you leave it long enough, eventually it will end up like.</p> <p><img src="/images/azure-service-update-9.png" alt="" /></p> <p>And that&rsquo;s it, now checking RavenHQ again.</p> <p><img src="/images/azure-service-update-10.png" alt="" /></p> <p>So to avoid ever even having to login to Azure Portal, you can Create and Publish a Cloud Service all from within Visual Studio.</p> Azure - Creating an Azure Cloud Service 2013-01-08T00:00:00-08:00 http://www.philliphaydon.com/2013/01/creating-an-azure-cloud-service/ <p>I&rsquo;ve been investigating setting up a Worker Role to do something similar to a Windows Service and it seems that the Worker Role is best suited for this purpose.</p> <p>You might create a Worker Role to Poll a Message Queue, or process some data in a database, or scrape some data and persist it, etc. I&rsquo;m going to throw some data in <a href="http://www.ravenhq.com">http://www.ravenhq.com</a> every minute, for this blog post, nothing exciting, but demonstrates how to create a WorkerRole and get it up and running on Azure.</p> <p>I suspect that you could use NancyFX Self-Hosting here and host a basic Nancy website, that would be cool :)</p> <h2>Building the Service (Worker / Role)</h2> <p>If you haven&rsquo;t already you will need to install the Azure SDK, so head on over to <a href="http://www.windowsazure.com/en-us/develop/net/">http://www.windowsazure.com/en-us/develop/net/</a> and click &ldquo;Install SDK&rdquo; which will give you the option for 2012 or 2010. I picked 2012 because I don&rsquo;t know what 2010 is, I stopped living in the past.</p> <p>The installer actually uses Web Platform Installer, not sure if there&rsquo;s any other way to install it.</p> <!--excerpt--> <p>Once installed you can create a brand new project in Visual Studio.</p> <p><img src="/images/azure-worker-1.png" alt="" /></p> <p>After hitting OK you&rsquo;re presented with a new screen to pick your Cloud Service.</p> <p><img src="/images/azure-worker-2.png" alt="" /></p> <p>I&rsquo;m not sure what that &lsquo;Visual Basic&rsquo; thing is, and I don&rsquo;t know F# so from the Visual C# list, pick Worker Role and throw that to the right hand side, then right click it and rename it (or click the little pen icon)</p> <p>Once you press ok your project is created and ready:</p> <p><img src="/images/azure-worker-3.png" alt="" /></p> <p>The <code>MyFirstWorker</code> is the Azure configuration stuff, I&rsquo;ll get to that when we deploy. For now we will work in <code>MyFirstRole</code></p> <p>The project comes with a WorkerRole file which stubs out the code we need</p> <pre><code>namespace MyFirstRole { public class WorkerRole : RoleEntryPoint { public override void Run() { // This is a sample worker implementation. Replace with your logic. Trace.WriteLine("MyFirstRole entry point called", "Information"); while (true) { Thread.Sleep(10000); Trace.WriteLine("Working", "Information"); } } public override bool OnStart() { // Set the maximum number of concurrent connections ServicePointManager.DefaultConnectionLimit = 12; // For information on handling configuration changes // see the MSDN topic at http://go.microsoft.com/fwlink/?LinkId=166357. return base.OnStart(); } } } </code></pre> <p><code>OnStart</code> returns bool, and from my understanding the worker role hasn&rsquo;t started until it has returned true. This allows you to run any initialization tasks, and while you&rsquo;re setting up it will tell the Worker or Load Balancer that it&rsquo;s busy, until you&rsquo;re done and have returned true.</p> <p>So I&rsquo;m going to configure the RavenDB Document Store at this point.</p> <p>I&rsquo;m using RavenHQ, so this sort of needs prior knowledge of RavenDB / HQ to setup, but if you swapped this code for any other task the rest of the post should still apply.</p> <pre><code>public override bool OnStart() { // Set the maximum number of concurrent connections ServicePointManager.DefaultConnectionLimit = 12; _documentStore = (new DocumentStore { ApiKey = "*api key removed*", Url = "https://aeo.ravenhq.com/databases/philliphaydon-TestDatabase", DefaultDatabase = "philliphaydon-TestDatabase" }).Initialize(); return base.OnStart(); } </code></pre> <p>There is also an <code>OnStop</code> method that you can override which gives you 30 seconds to clean up and persist any state etc. If you don&rsquo;t manage to clean up in 30 seconds, you&rsquo;re stuffed, it will terminate and you&rsquo;ve lost anything you wanted to do&hellip; But 30 seconds is a LONG time&hellip;</p> <p>The second method is <code>Run</code> is the task the role is going to run, it contains a while loop with the condition true to make it an infinite loop. This is really important because if you exit out of the loop, your role will terminate. Then it wouldn&rsquo;t really be a background service that is always running!</p> <p>I&rsquo;m not going to abstract anything out I&rsquo;m going to write my code directly in the while loop for the purpose of this post :)</p> <pre><code>public override void Run() { // This is a sample worker implementation. Replace with your logic. Trace.WriteLine("MyFirstRole entry point called", "Information"); var count = 0; while (true) { try { using (var session = _documentStore.OpenSession()) { session.Store(new Banana { Colour = "Yellow " + count }); session.SaveChanges(); } } catch (Exception ex) { //TODO: Implement www.raygun.io } finally { count++; } Thread.Sleep(60000); Trace.WriteLine("Working", "Information"); } } </code></pre> <p>At this point if we hit F5 we can debug the role and make sure it&rsquo;s doing what we want to do.</p> <p>A Windows Azure Emulator is started in your system tray, much like working with websites:</p> <p><img src="/images/azure-worker-4.png" alt="" /></p> <p>So right click and select &lsquo;Show Compute Emulator UI&rsquo;</p> <p><img src="/images/azure-worker-5.png" alt="" /></p> <p>And you will be presented with a nice UI that shows your services running.</p> <p><img src="/images/azure-worker-6.png" alt="" /></p> <p>As you can see it&rsquo;s pumping out &ldquo;Working&rdquo; into the console and if I swap over to RavenHQ Management Studio:</p> <p><img src="/images/azure-worker-7.png" alt="" /></p> <p>I have some banana&rsquo;s being persisted.</p> <p>GREAT. Now lets get this up and running on Azure!</p> <h2>Deployment Package</h2> <p>First up, we need to create a package, right click the project &lsquo;MyFirstWorker&rsquo; and select &lsquo;Package&rsquo;, this will give you the an option to package up a configuration, we will select Cloud since we are going to be putting it on Azure now.</p> <p><img src="/images/azure-worker-8.png" alt="" /></p> <p>This results in two files being created.</p> <p><img src="/images/azure-worker-9.png" alt="" /></p> <p>The Package itself, and a cloud configuration file. These will be needed when we upload it to Azure next.</p> <h2>Deployement on Azure</h2> <p><span class="note"><strong>Note:</strong> I&rsquo;ve created a new blog post on how to <a href="/2013/1/using-publish-to-deploy-azure-cloud-service">Publish from Visual Studio</a> for those who don&rsquo;t want to deploy from Azure Portal.</span></p> <p>Now we need to create the Cloud Service and upload the package. Head on over to the Azure portal, and sign up if you haven&rsquo;t already. Click on Cloud Services:</p> <p><img src="/images/azure-worker-10.png" alt="" /></p> <p>Then create a new cloud service, This will pop-up a small work-flow at the bottom of the page:</p> <p><img src="/images/azure-worker-11.png" alt="" /></p> <p><img src="/images/azure-worker-12.png" alt="" /></p> <p>After you&rsquo;ve pressed Create at the bottom, a status will popup.</p> <p><img src="/images/azure-worker-13.png" alt="" /></p> <p>Now you can go back to the Cloud Services tab and your new service will be visible.</p> <p><img src="/images/azure-worker-14.png" alt="" /></p> <p>Click the first cell to navigate to the service, and select Upload a new production deployment (or staging, I&rsquo;m doing production)</p> <p><img src="/images/azure-worker-15.png" alt="" /></p> <p>Now you can upload the package.</p> <p><img src="/images/azure-worker-16.png" alt="" /></p> <p>I selected the option <code>Deploy even if one or more roles contain a single instance.</code> since we don&rsquo;t need to worry about scaling. If it&rsquo;s a critical service you may want to deploy more than 1 instance to increase your availability.</p> <p>Now your service is deployed.</p> <p>Before deploying I reset my RavenDB database to have no data, so I wrote the rest of this blog post and it&rsquo;s been able 7 minutes&hellip;</p> <p><img src="/images/azure-worker-17.png" alt="" /></p> <p>And we have 7 documents :)</p> <p>That&rsquo;s it, easy peasy setting up a Azure Cloud Service from scratch to production.</p> Windows Store App - Tiled Background using Mindscape Metro Elements 2013-01-03T00:00:00-08:00 http://www.philliphaydon.com/2013/01/windows-store-app-tiled-background/ <p>Apparently WinRT XAML lacks the ability to tile a background image, and surfing the net seems to come to the conclusion that the only way is to just create a large tiled image in photoshop&hellip;</p> <p>I want to pick a Tile image from <a href="http://subtlepatterns.com/">http://subtlepatterns.com/</a> and just use it, but I <em>can&rsquo;t</em>. So I tried photoshop&hellip; (creating a benehoth of an image that is) I tried that, and it&hellip; crashed the Simulator, over and over&hellip; So I flagged it, instead I decided to put in a feature request over at Mindscape for their Metro Elements:</p> <p><a href="http://www.mindscapehq.com/thinktank/suggestion/505262">http://www.mindscapehq.com/thinktank/suggestion/505262</a></p> <p>I asked them to include a TiledBackground, and they delivered!</p> <p>Currently in the nightly build is the makings of a TiledBackground element.</p> <p>(To get access to the Nightly builds you will need to purchase a license for Metro Elements, which is well worth it, so go buy a license!)</p> <p>After installing the Metro Elements, in your app you want to add a reference to Metro Elements:</p> <p><img src="/images/windows-app-tiled-bg-1.png" alt="" /></p> <p>Now in the page attributes you need to include an alias for the MetroElements:</p> <!--excerpt--> <pre><code>xmlns:ms="using:Mindscape.MetroElements" </code></pre> <p>Then you can add the TileBackground element:</p> <pre><code>&lt;ms:TileBackground ImageSource="/Assets/debut_dark.png" /&gt; </code></pre> <p>And that&rsquo;s all there is to it! How simple is that?</p> <p>Now when you run the app, you should end up with the Hello World looking like:</p> <p><img src="/images/windows-app-tiled-bg-2.png" alt="" /></p> <p>It may be a little hard to see on the screen shot, but we now have a tiled background. The background used here is this image:</p> <p><img src="/images/windows-app-tiled-bg-3.png" alt="" /></p> <p><span class="note"><strong>Note:</strong> Currently the tiled-background is not viewable in the designer, it can only be viewed when debugging. This may be fixed in the future, but it&rsquo;s a minor issue.</span></p> <p>Thanks a lot to the Mindscape team for implementing this feature so quickly. I love you guys!</p> Microsoft Surface... So awesome, with issues... 2013-01-02T00:00:00-08:00 http://www.philliphaydon.com/2013/01/microsoft-surface-so-awesome-with-issues/ <p>Shortly after the Microsoft Surface was released I got my hands on one, which wasn&rsquo;t exactly easy since they aren&rsquo;t available in Singapore yet. I had to pay $240 extra to get mine shipped from Hong Kong via <a href="http://www.expansys.com.sg">http://www.expansys.com.sg</a> and then an extra $70 for import tax&hellip;</p> <p>But it was 110% worth it. I use the thing ALL the damn time, and dispite it being limited in functionality due to Windows RT, I don&rsquo;t regret the purchase at all.</p> <p>There&rsquo;s HEAPS of good reviews on the internet about it so I&rsquo;m not going to bore you with how amazingly awesome the thing is.</p> <p>What I want to discuss is 3 issues I have.</p> <h2>Surface Charger</h2> <p><img src="/images/surface-issues-1.png" alt="" /></p> <p>The Surface Charger has a Magnetic Power Plug, similar to the old L-shaped MagSafe</p> <p><img src="/images/surface-issues-2.png" alt="" /></p> <!--excerpt--> <p>The problem is, just like the old L-shaped MagSafe, it&rsquo;s a PILE OF SHIT. It&rsquo;s the most fiddly thing to try and connect up, and this isn&rsquo;t helped by the fact the Surface has a tappered edge so you need to angle it right for it to snap in.</p> <p>Unlike the keyboard cover which snaps on and positions itself, the charger tries to snap itself out of the hole, then you end up wriggling it around to try get it in.</p> <p>With the amazing build quality, how they cheaped out on the charger, I have no idea.</p> <p>This leads me onto #2</p> <h2>Windows Store &ndash; Unavailable to certain regions.</h2> <p>Ok so I completely understand that MS doesn&rsquo;t want to ship Surfaces to some countries like Singapore. So on their website I can&rsquo;t purchase a Surface&hellip;</p> <p>But they could atleast allow me to ship a new charger to Singapore. I can&rsquo;t walk into a store, I can&rsquo;t ship one here. I have to use a 3rd party to order it from the MS website, have it shipped to a US address and forwarded to my address.</p> <p>Just ship it to me directly. It&rsquo;s 2013 and we still can&rsquo;t ship stuff anywhere.</p> <p>Last up is my biggest peeve.</p> <h2>Microsoft restricting drivers&hellip;</h2> <p>Over Christmas I went to Penang in Malaysia, this country is so 3rd world it&rsquo;s the first time I&rsquo;ve ever stayed in a hotel that did not have wifi.</p> <p>The hotel room DID have ethernet however, but the Surface lacks a LAN port. So in order to setup the internet so I could surf the net while my friends sleep. (I don&rsquo;t sleep much) I decided to buy a USB to LAN adapter.</p> <p><img src="/images/surface-issues-3.png" alt="" /></p> <p>I own both of these, the first one (black) is an Asus USB Lan Adapter, it came with my Asus UX31 Laptop, the 2nd one is some weird brand called VZTEC.</p> <p>The thing you can&rsquo;t tell about both these is they are IDENTICAL. When you plug the devices in:</p> <p><img src="/images/surface-issues-4.png" alt="" /></p> <p><img src="/images/surface-issues-5.png" alt="" /></p> <p>The first image is using the White, random brand adapter. The second image is using the Asus one, both have the exact same chipset. So the drivers can be used for both. From googling it seems there&rsquo;s a lot of USB to LAN Adapters that sport this chipset.</p> <p>However, if you plug these into Windows 8 (Not Windows RT) windows will automatically find and install the drivers for you. If you attempt to do the same on Windows RT, it fails to install and you are unable to use it.</p> <p>Apparently these drivers are removed from ASIX&rsquo;s website at the request of Microsoft.</p> <p>This REALLY pisses me off, seriously what the fuck is Microsoft thinking, asking for drivers to be REMOVED so principles don&rsquo;t work on Windows Surface / Windows RT?</p> <p>One has to wonder what the hell goes on in Redmond, Microsoft constantly makes really stupid choices. Look at their fragmentated Windows Live ID, lack of support for multiple Live accounts on devices like Windows 8 / Windows Phone which prevent you from signing out of Metro Skype or messaging contacts that exist on different Windows Live account.</p> <p>I&rsquo;m so sick of Microsoft doing stupid things like this, soooo here&rsquo;s the drivers for <a href="/stuffz/AX88772B_772A_772_WinRT_Driver_v3.16.0.1807.zip">AX88772B / 772A / 772 for Windows RT</a></p> <p><a href="/stuffz/AX88772B_772A_772_WinRT_Driver_v3.16.0.1807.zip">Right Click and Save</a></p> <p>To use the drivers, unzip the above file onto your desktop or somewhere.</p> <p>Plugin the adapter, and go into Device Manager, find the device shown in the pictures above. (will have a weird icon since it&rsquo;s not working) go into properties / drivers and then manually browse to the driver folder.</p> <p>This will install the Windows RT driver and the adapter will now be usable.</p> <hr /> <p>This concludes my rant with Microsoft Surface.</p> <p>It truely is an amazing product. Just wish Microsoft would stop doing such silly things.</p> Configuring multiple Forms Authentication sections with NancyFX 2012-12-20T00:00:00-08:00 http://www.philliphaydon.com/2012/12/configuring-multiple-forms-authentication-sections-with-nancyfx/ <p>So Phil Jones posted on twitter recently his desire to have multiple Forms Auth&rsquo;s for different area&rsquo;s in a website.</p> <p>The most common scenario is having an Administration and Member with completely separated logins.</p> <p><img src="/images/image35.png" /></p> <p>This is actually really easy in NancyFX. Expanding on my previous post:</p> <p><a href="/2012/12/forms-authentication-with-nancyfx/">http://www.philliphaydon.com/2012/12/forms-authentication-with-nancyfx/</a></p> <p>I&rsquo;m going to include a new area and a couple of new modules:</p> <p><img src="/images/image36.png" /></p> <p>I&rsquo;ve added a folder called &lsquo;Admin&rsquo; this is to act as an Area as described in my post about Nancy &amp; Areas.</p> <!--excerpt--> <p>There are now two Secure modules, both these are really &lsquo;dumb&rsquo; modules that, for the purpose of this sample, do nothing more than manage the authentication for the Main/Admin areas.</p> <h3>SecureAdminModule</h3> <pre><code>public class SecureAdminModule : NancyModule { public SecureAdminModule() : this(string.Empty) { } public SecureAdminModule(string path) : base("admin/" + path.TrimStart('/')) { this.RequiresAuthentication(); this.RequiresClaims(new[] { "Admin" }); } } </code></pre> <p><span class="note"><strong>Note:</strong> The Admin module passes in &lsquo;admin&rsquo; for the module path, this means all module routes will be within the admin path.</span></p> <h3>SecureMemberModule</h3> <pre><code>public class SecureMemberModule : NancyModule { public SecureMemberModule() : this(string.Empty) { } public SecureMemberModule(string modulePath) : base(modulePath) { this.RequiresAuthentication(); this.RequiresClaims(new[] {"Member"}); } } </code></pre> <p><span class="note"><strong>Note:</strong> Both Modules call RequiresAuthentication. This is not actually required since RequiresClaims actually calls RequiresAuthentication.</span></p> <p><a href="https://github.com/NancyFx/Nancy/blob/master/src/Nancy/Security/ModuleSecurity.cs#L27">https://github.com/NancyFx/Nancy/blob/master/src/Nancy/Security/ModuleSecurity.cs#L27</a></p> <p>Both modules call RequiresClaims passing in a specific parameter. Admin or Member. This means when we login we can add the specific claim to each user so that they can only access certain portions of the website.</p> <p>Now that these modules are implemented, we can use these in our modules that we create. So lets add two modules to both area&rsquo;s that will require authentication.</p> <p><img src="/images/image37.png" /></p> <p>Here&rsquo;s two new Modules, both named OrderModule. One is used for the members to view their orders and order details. And one for the admin to see pending orders and such so he can process them. Basic ecommerce type scenario.</p> <p>Now if we view each of these pages in a browser:</p> <p><img src="/images/image38.png" /></p> <p><img src="/images/image39.png" /></p> <p>You can see both pages end up at the same login maybe we want to have a different login page for admin. So I&rsquo;ll create a new login, setup just the same as one from the previous post. But now I need to configure them both.</p> <p>This is where Nancy Bootstrapper comes in handy.</p> <p>First up &ndash; In the ConfigureRequestContainer method, we need to include a second class implementing IUserMapper:</p> <pre><code>protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context) { base.ConfigureRequestContainer(container, context); container.Register&lt;IUserMapper, MemberDBUserMapper&gt;("Member"); container.Register&lt;IUserMapper, AdminDBUserMapper&gt;("Admin"); } </code></pre> <p>I&rsquo;ve included a new class called AdminDBUserMapper, and renamed the old one to avoid confusion. These classes are what authenticate the user in your system, and map it to an object that NancyFX can handle. In this case an IUserIdentity.</p> <p>Also, when both classes are registered, I gave them specific names. These are Keyed so that when we want to authenticate an Admin, we can resolve the Admin Mapper.</p> <pre><code>public class MemberDBUserMapper : IUserMapper { public IDocumentStore DocumentStore { get; set; } public MemberDBUserMapper(IDocumentStore documentStore) { DocumentStore = documentStore; } public IUserIdentity GetUserFromIdentifier(Guid identifier, NancyContext context) { using (var session = DocumentStore.OpenSession()) { var member = session.Query&lt;Member&gt;().SingleOrDefault(x =&gt; x.Identifier == identifier); if (member == null) return null; return new AuthenticatedUser { UserName = member.Username, Claims = new[] { "Member" } }; } } } </code></pre> <p>The MemberDBUserMapper is the same as the previous post, it pulls the user from RavenDB, and it add&rsquo;s a single claim. &lsquo;Member&rsquo; this it the claim we used in the SecureMemberModule.</p> <pre><code>public class AdminDBUserMapper : IUserMapper { public IDocumentStore DocumentStore { get; set; } public static readonly ConcurrentDictionary&lt;Guid, dynamic&gt; Admins = new ConcurrentDictionary&lt;Guid, dynamic&gt;(); static AdminDBUserMapper() { Admins.GetOrAdd(Guid.NewGuid(), new { Username = "admin", Password = "test" }); Admins.GetOrAdd(Guid.NewGuid(), new { Username = "admin2", Password = "test" }); Admins.GetOrAdd(Guid.NewGuid(), new { Username = "admin3", Password = "test" }); } public AdminDBUserMapper(IDocumentStore documentStore) { DocumentStore = documentStore; } public IUserIdentity GetUserFromIdentifier(Guid identifier, NancyContext context) { if (!Admins.ContainsKey(identifier)) return null; var member = Admins[identifier]; if (member == null) return null; return new AuthenticatedUser { UserName = member.Username, Claims = new[] { "Admin" } }; } } </code></pre> <p>The AdminDBUserMapper is slightly different, rather than pulling from RavenDB, it uses a static in-memory collection of admins/passwords.</p> <p><span class="note"><strong>Note:</strong> I&rsquo;m not suggesting you do something like this in your system, it&rsquo;s purely for demoing that there are two different ways of getting Users. In a more realistic scenario the Admin would be pulled from RavenDB from a different collection, or from a different Database table when using SQL Server or the likes of.</span></p> <p>Now that we have our mapping implemented, we can configure when these are called. In the previous post I implemented the Bootstrapper method: RequestStartup</p> <p>This time we will extend it with a little bit of if/else logic.</p> <pre><code>protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context) { base.RequestStartup(container, pipelines, context); if (context.Request.Url.Path.StartsWith("/admin")) { var formsAuthConfiguration = new FormsAuthenticationConfiguration { RedirectUrl = "~/admin/login", UserMapper = container.Resolve&lt;IUserMapper&gt;("Admin"), }; FormsAuthentication.Enable(pipelines, formsAuthConfiguration); } else { var formsAuthConfiguration = new FormsAuthenticationConfiguration { RedirectUrl = "~/login", UserMapper = container.Resolve&lt;IUserMapper&gt;("Member"), }; FormsAuthentication.Enable(pipelines, formsAuthConfiguration); } } </code></pre> <p>This method is called for each request, so for each request we will do a quick check to see what the path is, and then wire up the FormsAuthentication for the request.</p> <p>If the path happens to start with /admin, then we want the user to be sent to the admin login page, if it&rsquo;s anywhere else, we want it to go to the normal login page.</p> <p>Now if we visit the same two pages again:</p> <p><img src="/images/image40.png" /></p> <p>The normal orders page goes to the normal login page.</p> <p><img src="/images/image41.png" /></p> <p>But the Admin order page goes to the Admin login page!</p> <h2>Login as normal user</h2> <p>If we login to the normal website, and we try visit the secure page:</p> <p><img src="/images/image42.png" /></p> <p>Great! But if we visit the Admin page:</p> <p><img src="/images/image43.png" /></p> <p>BAM Right back to the login page, access DENIED! Exactly what we wanted.</p> <h2>Login as Admin</h2> <p>Now after logging out and logging back in as an Admin. Visit the Admin page:</p> <p><img src="/images/image44.png" /></p> <p>WOOOHOO! We have Orders! Now if we try the normal page:</p> <p><img src="/images/image45.png" /></p> <p>DENIED!</p> <p>And there you have it. With a little bit of extra configuration you can setup custom Forms Authentication for different area&rsquo;s of your website.</p> Windows Store App and Remote Debugging on a Surface RT 2012-12-18T00:00:00-08:00 http://www.philliphaydon.com/2012/12/windows-store-app-and-remote-debugging-on-a-surface-rt/ <p>In order to run your app from Visual Studio on your remote device, in my case I want to run it on my Surface&hellip; but you can do this with any remote device such as another desktop, a laptop, a tablet running Windows Pro or RT etc, all you really need to do is install the Remote Debugging tools.</p> <p><a href="http://www.microsoft.com/visualstudio/eng/downloads#remote-tools">http://www.microsoft.com/visualstudio/eng/downloads#remote-tools</a></p> <p>For the Surface you just need to download and install:</p> <p><a href="http://www.microsoft.com/visualstudio/eng/downloads#remote-tools"><img src="/images/image17.png" /></a></p> <p>Once this is installed you will get a little icon on your Start Screen:</p> <p><a href="/images/image7.png"><img src="/images/image7.png" /></a></p> <p>You can see the Green Arrow:</p> <!--excerpt--> <p><img src="/images/image18.png" /></p> <p>When you run this for the first time it will ask you to configure some stuff, mainly for the firewall:</p> <p><img src="/images/image19.png" /></p> <p>You only need to do this once. Once this is done you will get the following screen:</p> <p><img src="/images/image20.png" /></p> <p>Now you&rsquo;re all ready for some awesome remote debugging!</p> <p>In Visual Studio you need to select &lsquo;Remote Machine&rsquo; in the debug list:</p> <p><img src="/images/image21.png" /></p> <p>This opens up a remote debug connection:</p> <p><img src="/images/image22.png" /></p> <p>Enter in the IP for the Surface. (You can get this by calling &lsquo;ipconfig&rsquo; in command line) After pressing select the window will close, and you will be ready!</p> <p>Now you just need to debug the app. Using the same app from the previous post I&rsquo;ve put a break point on the MainView constructor:</p> <p><img src="/images/image23.png" /></p> <p>When I begin debugging makes a request to the device and authenticates:</p> <p><img src="/images/image24.png" /></p> <p><span class="note"><strong>Note:</strong> If you&rsquo;re debugging on a device that is logged in with a different user, then Visual Studio will prompt you for credentials. Because I&rsquo;m using the same LiveID on both my Desktop and Surface, it doesn&rsquo;t prompt me to login.</strong></p> <p>Once connected, it will install the app just like it does on your desktop, and then automatically runs and debugs the app:</p> <p><img src="/images/image25.png" /></p> <p>And as you can see:</p> <p><img src="/images/image26.png" /></p> <p>My shinny Surface screen running the Hello World sample from the previous post.</p> <p>Debugging allows you to step through code just the same as doing it locally :)</p> <p>Hopefully this helps anyone who has had difficulty or confusion debugging on remote devices.</p> Forms Authentication with NancyFX 2012-12-18T00:00:00-08:00 http://www.philliphaydon.com/2012/12/forms-authentication-with-nancyfx/ <p>There&rsquo;s already quite a bit of documentation on the Nancy wiki about forms authentication, but I wanted to write about it anyway.</p> <p><span class="note"><strong>Note:</strong> This is written with Nancy 0.14.1 &ndash; this may be subject to change in future versions.</span></p> <p>Nancy supports a module for forms authentication, it works some-what similar to the way forms auth works in ASP.NET, except it&rsquo;s abstracted away and is not part of the core Nancy engine, which is great. It means that if you don&rsquo;t like the way forms authentication works, you can rip it out and write your own from scratch, or download the project and modify it to your hearts content.</p> <p><a href="http://nuget.org/packages/Nancy.Authentication.Forms">http://nuget.org/packages/Nancy.Authentication.Forms</a></p> <p><a href="https://github.com/NancyFx/Nancy/tree/master/src/Nancy.Authentication.Forms">https://github.com/NancyFx/Nancy/tree/master/src/Nancy.Authentication.Forms</a></p> <p>If you take a look at the GitHub project, you can see that the implementation is actually really small. So should you want to poke around, there&rsquo;s not much to look at.</p> <!--excerpt--> <h3>Packages</h3> <p>First up we need to install the packages, Nancy, Nancy.Hosting.Aspnet, and Nancy.Authentication.Forms</p> <pre><code>PM&gt; install-package Nancy Successfully installed "Nancy 0.14.1". Successfully added "Nancy 0.14.1" to Nancy.FormsAuth. PM&gt; install-package Nancy.Authentication.Forms Attempting to resolve dependency "Nancy (= 0.14.1)". Successfully installed "Nancy.Authentication.Forms 0.14.1". Successfully added "Nancy.Authentication.Forms 0.14.1" to Nancy.FormsAuth. PM&gt; install-package Nancy.Hosting.Aspnet Attempting to resolve dependency "Nancy (= 0.14.1)". Successfully installed "Nancy.Hosting.Aspnet 0.14.1". Successfully added "Nancy.Hosting.Aspnet 0.14.1" to Nancy.FormsAuth. </code></pre> <h3>Configuring Forms Auth</h3> <pre><code>public class Bootstrapper : DefaultNancyBootstrapper { protected override void ConfigureRequestContainer(TinyIoCContainer container, NancyContext context) { base.ConfigureRequestContainer(container, context); container.Register&lt;IUserMapper, DatabaseUser&gt;(); } protected override void RequestStartup(TinyIoCContainer container, IPipelines pipelines, NancyContext context) { base.RequestStartup(container, pipelines, context); var formsAuthConfiguration = new FormsAuthenticationConfiguration { RedirectUrl = "~/login", UserMapper = container.Resolve&lt;IUserMapper&gt;(), }; FormsAuthentication.Enable(pipelines, formsAuthConfiguration); } } </code></pre> <p>This is all I&rsquo;ve done to the bootstrapper. The first method ConfigureRequestContainer registers a class for IUserMapper. Currently it&rsquo;s in red because it doesn&rsquo;t exist yet, we need to create it :)</p> <p>The second method configures the Forms Authentication plugin. All we need to define is the redirect URL for unauthenticated requests. That means if the user attempts to go to a page that requires authentication, they will be redirected here instead. Using the IoC container we resolve the registered IUserMapper class which is what is used to retrieve the user from the Database (or where ever you persist your users)</p> <h3>Creating a class implementing IUserMapper</h3> <pre><code>public class DatabaseUser : IUserMapper { public IUserIdentity GetUserFromIdentifier(Guid identifier, NancyContext context) { throw new NotImplementedException(); } } </code></pre> <p>The IUserMapper interface only requires you to implement 1 method. This method is used to authenticate the user on each request and return some basic data of the user.</p> <p>So we need to create a user to return that implements IUserIdentity.</p> <pre><code>public class AuthenticatedUser : IUserIdentity { public string UserName { get; set; } public IEnumerable&lt;string&gt; Claims { get; set; } } </code></pre> <p>That&rsquo;s all we need for the user. Now we need to implement the DatabaseUser class.</p> <p>The method GetUserFromIdentifier takes a Guid. This is what&rsquo;s used to identify the user, it&rsquo;s a Guid because it&rsquo;s a good idea to not use an identifier that is easily guessable.</p> <p>It does mean that your persisted user needs to have an identifier that&rsquo;s a Guid. This doesn&rsquo;t mean the PrimaryKey needs to be a Guid, you can leave it as an INT or what ever your database currently uses. But add a new field to the table or document etc.</p> <pre><code>public class DatabaseUser : IUserMapper { public IDocumentStore DocumentStore { get; set; } public DatabaseUser(IDocumentStore documentStore) { DocumentStore = documentStore; } public IUserIdentity GetUserFromIdentifier(Guid identifier, NancyContext context) { using (var session = DocumentStore.OpenSession()) { var member = session.Query&lt;Member&gt;().SingleOrDefault(x =&gt; x.Identifier == identifier); if (member == null) return null; return new UserIdentity { UserName = member.DisplayName, Claims = new [] { "NewUser", "CanComment" } }; } } } </code></pre> <p>This example is using RavenDB for data access, it&rsquo;s pulling the Member based on an Identifier property, but same applies to any persistence you use, SQL Server, MongoDB, etc.</p> <p>Now we have configured everything, now we just need to Login, and visit a page we can&rsquo;t access. Lets create two modules:</p> <h3>HomeModule</h3> <pre><code>public class HomeModule : NancyModule { public HomeModule() { Get["/"] = _ =&gt; { return "Hello World"; }; Get["/login"] = _ =&gt; { return View["login.html"]; }; } } </code></pre> <h3>SecureModule</h3> <pre><code>public class SecureModule : NancyModule { public SecureModule() { this.RequiresAuthentication(); Get["/secure"] = _ =&gt; { return "I'm secure!"; }; } } </code></pre> <p>The two Modules are really simple, for the purpose of demoing :) as you can see the Secure module calls RequiresAuthentication, this calls the extension method defined in the Nancy&rsquo;s security, this as a result, calls the the Forms Authentication plugin.</p> <p><a href="https://github.com/NancyFx/Nancy/blob/master/src/Nancy/Security/ModuleSecurity.cs">https://github.com/NancyFx/Nancy/blob/master/src/Nancy/Security/ModuleSecurity.cs</a></p> <p>Now when we visit the webpage /secure we end up at the login page.</p> <p><img src="/images/image31.png" /></p> <p>Now we need to implement the login. So on the HomeModule I&rsquo;ll add a POST handler.</p> <pre><code>Post["/login"] = _ =&gt; { var loginParams = this.Bind&lt;LoginParams&gt;(); Member member; using (var session = store.OpenSession()) { member = session.Query&lt;Member&gt;().SingleOrDefault(x =&gt; x.Username == loginParams.Username); if (member != null &amp;&amp; member.Password != loginParams.Password) { return "username and/or password was incorrect"; } } return this.LoginAndRedirect(member.Identifier, fallbackRedirectUrl: "/"); }; </code></pre> <p>Once we verify that the user has successfully logged in, we call LoginAndRedirect extension method, passing in the Identifier. This makes a cookie which is sent back on each request to authenticate.</p> <p>Now that&rsquo;s implemented, we can login and visit the Secure page:</p> <p><img src="/images/image32.png" /></p> <p>So when we hit the secure module, and put a break point on the DatabaseUser:</p> <p><img src="/images/image33.png" /></p> <p>As you can see Nancy has invoked it, passing in the identifier which is then used to find the user in the database and return it.</p> <p>This also populates the CurrentUser on the context:</p> <p><img src="/images/image34.png" /></p> <p>To log a user out again, all you need to do is call the Logout() extension method inside your own module and you&rsquo;re done :)</p> <p>That&rsquo;s the basic use of Forms Authentication using Nancy.</p> <p>One thing people get concerned about is the DatabaseUser class querying the database on every request. For 99% of the scenarios you ever face this is perfectly fine, this is a select by Id, and should be fast even if you have a few million records in the table.</p> <p>If your table is slow to query then you have much bigger issues to worry about, and you should be fixing those issues!</p> <p>Next post I&rsquo;m going to explain how you can run two Forms Authentications for two different sections of the website. i.e Normal users and Admin users. I&rsquo;ll also explain how this identifier is beneficial to make it so users can only be logged on in 1 location at a time.</p> Windows Store App with Caliburn.Micro - Getting Started 2012-12-14T00:00:00-08:00 http://www.philliphaydon.com/2012/12/windows-store-app-with-caliburn-micro-getting-started/ <p>So I&rsquo;ve been learning Windows 8 development recently, specifically with C#/XAML, and Caliburn.Micro for the MVVM goodness. This is all brand new stuff for me, never done any WPF, Silverlight or Windows Phone dev. So I figured it&rsquo;s a good chance to blog what I&rsquo;m learning.</p> <p>In this post I want to show you how to get up and running.</p> <p>I started by reading the blog posts over at Mindscape.</p> <p><a href="http://www.mindscapehq.com/blog/index.php/2012/01/12/caliburn-micro-part-1-getting-started/">http://www.mindscapehq.com/blog/index.php/2012/01/12/caliburn-micro-part-1-getting-started/</a></p> <p>(great series by <a href="https://twitter.com/QuantumNgtmare">@Jason</a>, list of links at bottom of this post)</p> <p>The downside is they were very WPF centric, and a few things getting started have changed. There&rsquo;s no bootstrapper for example.</p> <p>So, here&rsquo;s my blog series.</p> <!--excerpt--> <h2>Before getting started</h2> <p>The most important thing to note about building Windows Store App&rsquo;s is that you can&rsquo;t just reference any old assembly, it has to be either developed for Windows Store, or be created as a portable library. This is because WinRT (Windows Runtime) doesn&rsquo;t contain all the same namespaces as the .NET framework.</p> <h2>Getting Started</h2> <p>Create a new Blank App (XAML)</p> <p><img src="/images/windows-store-start-1.png" /></p> <p>Next you&rsquo;re going to need to install Caliburn.Micro, I use Nuget for this, but you can download the package and reference it manually from codeplex.</p> <p><img src="/images/windows-store-start-2.png" /></p> <p>Your solution should look something like this:</p> <p><img src="/images/windows-store-start-3.png" /></p> <p>The first thing we can do is delete the MainPage.xaml, and add a couple of folder, Views and ViewModels. You can also add your own Styles file too. While you&rsquo;re at it, add a MainView.xaml and MainViewModel.cs to their respected folders.</p> <p><img src="/images/windows-store-start-4.png" /></p> <p>Let&rsquo;s start writing/fixing code!</p> <p><strong>App.xaml</strong></p> <p>This file is the entry point to your application. It&rsquo;s the very first file that is executed, it&rsquo;s best to leave the file name as is, but if you wish to change it. Then you need to open your Package.appxmanifest file and modify the entry point.</p> <p><img src="/images/windows-store-start-5.png" /></p> <p>For now, don&rsquo;t worry about changing this, I&rsquo;ll try cover this in future posts.</p> <p>First thing we want to do is open up the XAML file, not the code file. We can strip back the comments and include our custom styles resource.</p> <p>Next we want to add in a namespace attribute:</p> <pre><code>xmlns:caliburn="using:Caliburn.Micro" </code></pre> <p>This is like adding custom controls to a web.config file or declaring the custom controls in your page, then accessing them via the prefix you define.</p> <p>This allows us to modify the root Element and make it a Caliburn Application.</p> <p>What you should end up with is the following:</p> <pre><code>&lt;caliburn:CaliburnApplication x:Class="SampleProject.App" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:SampleProject" xmlns:caliburn="using:Caliburn.Micro"&gt; &lt;Application.Resources&gt; &lt;ResourceDictionary&gt; &lt;ResourceDictionary.MergedDictionaries&gt; &lt;ResourceDictionary Source="Common/StandardStyles.xaml"/&gt; &lt;ResourceDictionary Source="Common/CustomStyles.xaml"/&gt; &lt;/ResourceDictionary.MergedDictionaries&gt; &lt;/ResourceDictionary&gt; &lt;/Application.Resources&gt; &lt;/caliburn:CaliburnApplication&gt; </code></pre> <p>The next thing you want to do is open up the code file for the App.xaml file. By default this has a LOT of stuff in it, that we don&rsquo;t need at all.</p> <p>Below is the recommendation sample from Caliburn.Micro documentation, it does quite a bit including having a basic IoC container for WinRT, and handles View or ViewModel first approach.</p> <p><span class="note"><strong>Note:</strong> Caliburn.Micro 1.4.1 has a breaking change, please read the <a href="/2013/02/windows-store-app-with-caliburn-micro-getting-started-updated/">updated post</a> for info on updating the code below to be compatiable with v1.4.1</span></p> <pre><code>using System; using System.Collections.Generic; using Caliburn.Micro; using SampleProject.Views; using Windows.ApplicationModel.Activation; using Windows.UI.Xaml.Controls; namespace SampleProject { sealed partial class App { private WinRTContainer container; public App() { InitializeComponent(); } protected override void Configure() { container = new WinRTContainer(); container.RegisterWinRTServices(); } protected override object GetInstance(Type service, string key) { return container.GetInstance(service, key); } protected override IEnumerable&lt;object&gt; GetAllInstances(Type service) { return container.GetAllInstances(service); } protected override void BuildUp(object instance) { container.BuildUp(instance); } protected override void PrepareViewFirst(Frame rootFrame) { container.RegisterNavigationService(rootFrame); } protected override void OnLaunched(LaunchActivatedEventArgs args) { DisplayRootView&lt;MainView&gt;(); } } } </code></pre> <p>The very last method &lsquo;OnLaunched&rsquo; has the class to our Main View, this tells the application that the first thing we will see will be the MainView.</p> <p>Next lets look at the ViewModel.</p> <h3>MainViewModel.cs</h3> <p>In this file, strip everything back and inherit &lsquo;Screen&rsquo;</p> <p>Although this file will be loaded, it&rsquo;s not going to do anything just yet. At least not for this sample.</p> <h3>MainView.xaml</h3> <p>Now lets look at the view, open up the xaml file. This file should have been created with as a Blank page, once open, add a TextBlock with the text Hello World.</p> <pre><code>&lt;Page x:Class="SampleProject.Views.MainView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="using:SampleProject.Views" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"&gt; &lt;Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}"&gt; &lt;TextBlock Text="Hello World" /&gt; &lt;/Grid&gt; &lt;/Page&gt; </code></pre> <p>We don&rsquo;t need to modify the code file for this.</p> <p>Now we should be able to run app. There is 3 possible ways to run:</p> <ol> <li><h4>Local Machine</h4> <p>Using a Local Machine means the application will be loaded into your Start Screen and automatically be run.</p></li> <li><h4>Simulator</h4> <p>The simulator will open up a simulation app which resembles a tablet, this gives a bunch of options to simulate different gestures such as using touch and pinch etc.</p></li> <li><h4>Remote Machine</h4> <p>The remote machine option requires the Remote SDK to be installed and running on a remote machine. This is handy for testing on an actual device. I&rsquo;ll cover this next week when I explain how to setup remote debugging.</p></li> </ol> <p>I suggest selecting Simulator and pressing F5. Assuming you&rsquo;ve followed along you should get this:</p> <p><img src="/images/windows-store-start-6.png" /></p> <p><span class="note"><strong>Note:</strong> I increased the font size for the purpose of taking a screen grab :)</span></p> <p>And that&rsquo;s it, so far all we&rsquo;ve done is configure Caliburn and tell it to load a view, we aren&rsquo;t really utilizing it yet but we will in the future!</p> <hr /> <p>As mentioned here&rsquo;s Jason&rsquo;s post over at Mindscape:</p> <ul> <li><a href="http://www.mindscapehq.com/blog/index.php/2012/01/12/caliburn-micro-part-1-getting-started/">Caliburn Micro Part 1: Getting Started</a></li> <li><a href="http://www.mindscapehq.com/blog/index.php/2012/01/16/caliburn-micro-part-2-data-binding-and-events/">Caliburn Micro Part 2: Data Binding and Events</a></li> <li><a href="http://www.mindscapehq.com/blog/index.php/2012/01/24/caliburn-micro-part-3-more-about-events-and-parameters/">Caliburn Micro Part 3: More About Events and Parameters</a></li> <li><a href="http://www.mindscapehq.com/blog/index.php/2012/02/01/caliburn-micro-part-4-the-event-aggregator/">Caliburn Micro Part 4: The Event Aggregator</a></li> <li><a href="http://www.mindscapehq.com/blog/index.php/2012/03/13/caliburn-micro-part-5-the-window-manager/">Caliburn Micro Part 5: The Window Manager</a></li> </ul> Using Partial Renders with Nancy rather than Render Actions like MVC 2012-11-30T00:00:00-08:00 http://www.philliphaydon.com/2012/11/using-partial-renders-with-nancy-rather-than-render-actions-like-mvc/ <p>Today on twitter, <a href="http://blog.orangelightning.co.uk/">Phil Jones</a> (<a href="http://twitter.com/philjones88">@philjones88</a>) asked how you would do RenderAction (ASP.NET MVC extension)</p> <p>I personally don&rsquo;t like RenderAction in MVC, that&rsquo;s not to say it&rsquo;s bad, I just think it hides away important implementation of a page render. I think RenderAction is a bad abstraction. But this is my personal opinion. So don&rsquo;t hate me for it :)</p> <p>Rather than using RenderAction I prefer to use Partial views.</p> <p>Lets look at a youtube site for an example:</p> <p><img src="/images/partial-renders-nancy-1.png" /></p> <p>On the left hand side is main content, while on the right hand side is related videos. In ASP.NET MVC we might use something like:</p> <pre><code>@Html.RenderAction("Related", "Videos"); </code></pre> <p>Or something similar, I forget the syntax :)</p> <!--excerpt--> <p>This would use the Query String to get the Video Id and pull all related videos and display them.</p> <p>In Nancy if I was building the same page, I would push down a dynamic model:</p> <pre><code>@inherits Nancy.ViewEngines.Razor.NancyRazorViewBase&lt;dynamic&gt; </code></pre> <p>Then in the Module, query for the video + the recommended data:</p> <pre><code>public class VideosModule : RavenModule { public VideosModule(IDocumentStore documentStore) : base(documentStore) { Get["/videos/{id}"] = _ =&gt; { Model.Videos = DocumentSession.Load&lt;Video&gt;(_.id); Model.Recommended = DocumentSession.Query&lt;Video, Videos_Recommended&gt;().Where(x =&gt; x.VideoId == _.id); return View["display-video", Model]; }; } } </code></pre> <p>Model is implemented as an ExpandoObject on the RavenModule:</p> <pre><code>public abstract class RavenModule : NancyModule { protected dynamic Model = new ExpandoObject(); </code></pre> <p>Now on my display-video view, I add:</p> <pre><code>@Html.Partial("recommended", Model.Recommended) </code></pre> <p>This &lsquo;recommended&rsquo; view is the same as the &lsquo;display-video&rsquo; view, in that it uses dynamic also.</p> <p>That&rsquo;s all there is to it.</p> <p>In regards to information displayed on the Master Page (or master layout, what ever you want to call it) Because the &lsquo;Model&rsquo; is defined on the base module, you can implement properties for menu, footer, member details, etc. And still use Partials to render those also.</p> <p>I&rsquo;ll add a Git Repo for this project in the near future.</p> NancyFX and Content Negotiation 2012-11-08T00:00:00-08:00 http://www.philliphaydon.com/2012/11/nancy-and-content-negotiation/ <p>This has to be one of the most awesome features of Nancy, Content Negotiation. Recently added in 0.12, it gives you the ability to implement a single route that responds with different versions of the same document, without having to mess up your code with duplicate methods or conditional statements.</p> <p>When doing this in ASP.NET MVC I would have to check the content type and decide how I want to respond to the request.</p> <p>This ended up making duplicate methods, one which would be used by a normal GET request, while the 2nd would be for an AJAX request. Or if it was similar, use conditional logic in the single method to decide how the action should respond&hellip;</p> <p>Nancy on the other hand supports Content Negotiation out of the box.</p> <pre><code>Get["/negotiated"] = parameters =&gt; { return Negotiate .WithModel(new RatPack {FirstName = "Nancy "}) .WithMediaRangeModel("text/html", new RatPack {FirstName = "Nancy fancy pants"}) .WithView("negotiatedview") .WithHeader("X-Custom", "SomeValue"); }; </code></pre> <p><span class="note"><strong>Note:</strong> Sample taken from Nancy GitHub Repo</span></p> <h2>What is content negotiation?</h2> <p>In short, it&rsquo;s the ability to serve different versions of a document to the same URI.</p> <!--excerpt--> <p>To read more you can visit <a href="http://en.wikipedia.org/wiki/Content_negotiation">Wikipedia</a> or <a href="http://www.soapatterns.org/content_negotiation.php">SOA Patterns</a>&hellip; or&hellip; <a href="http://www.bing.com/">Google</a></p> <h2>Why should I care?</h2> <p>Well lets assume we&rsquo;re building a website and we have a shopping cart, we get to the checkout page and there&rsquo;s a button to delete the item from your cart.</p> <p>You want to give a really nice user experience by not posting back the entire page. You would rather just tell the server to delete the item from the cart, and do a quick update on the screen, and avoid the whole page reloading.</p> <p>However what if the page is taking a long time to load, and as a result, the JavaScript hasn&rsquo;t been executed and wired up all the events to the buttons to delete items from your cart, you still want to be able to post the entire page and maintain the usability of the page.</p> <p>The same scenario occurs if the user has (unlikely) turned JavaScript off.</p> <h2>Implementation</h2> <p>So using the example above, deleting an item from a cart and updating the page, using JavaScript verses a full postback of the page, using the exact same route.</p> <p>Let&rsquo;s create a really basic module:</p> <pre><code>public class HomeModule : NancyModule { public class Product { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } } public static IList&lt;Product&gt; Products = new List&lt;Product&gt;() { new Product {Id = 1, Name = "Surface", Price = 499}, new Product {Id = 2, Name = "iPad", Price = 899}, new Product {Id = 3, Name = "Nexus 10", Price = 599}, new Product {Id = 4, Name = "Think Pad", Price = 499}, new Product {Id = 5, Name = "Yoga", Price = 699}, }; public dynamic Model = new ExpandoObject(); public HomeModule() { Model.Deleted = false; Get["/"] = _ =&gt; { Model.Products = Products; return View["index", Model]; }; } } </code></pre> <p>I&rsquo;ve nested a Product class in there, and created a static list of products for demo.</p> <p>We need a View to go with this to display the Products:</p> <pre><code>&lt;h2&gt;Products&lt;/h2&gt; &lt;p&gt;Posted back using: &lt;span class="status"&gt;@if ((bool)Model.Deleted) { @Html.Raw("Full Postback"); }&lt;/span&gt;&lt;/p&gt; &lt;table&gt; &lt;thead&gt; &lt;tr&gt; &lt;th style="width: 50px;"&gt;Id&lt;/th&gt; &lt;th style="width: 90px;"&gt;Name&lt;/th&gt; &lt;th style="width: 50px;"&gt;Price&lt;/th&gt; &lt;th style="width: 150px;"&gt;&amp;nbsp;&lt;/th&gt; &lt;th style="width: 160px;"&gt;&amp;nbsp;&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; @foreach (var product in Model.Products) { &lt;tr&gt; &lt;td&gt;@product.Id&lt;/td&gt; &lt;td&gt;@product.Name&lt;/td&gt; &lt;td&gt;@product.Price.ToString("c")&lt;/td&gt; &lt;td&gt;&lt;a href="/delete/@product.Id"&gt;Delete With JavaScript&lt;/a&gt;&lt;/td&gt; &lt;td&gt;&lt;a href="/delete/@product.Id"&gt;Delete Without JavaScript&lt;/a&gt;&lt;/td&gt; &lt;/tr&gt; } &lt;/table&gt; </code></pre> <p>This rendered will display the following:</p> <p><img src="/images/nancy-conneg-1.png" /></p> <p>So when we press the &lsquo;Delete Without JavaScript&rsquo; button we want it to remove the item, so we can add a new route:</p> <pre><code>Get[@"/delete/{id}"] = _ =&gt; { var id = (int) _.id; var item = Products.Single(x =&gt; x.Id == id); Products.Remove(item); Model.Products = Products; Model.Deleted = true; return View["index", Model]; }; </code></pre> <p>Now if we press the button:</p> <p><img src="/images/nancy-conneg-2.png" /></p> <p>We can see the URL has updated, and the 3rd item was deleted from the list. It also updated the text to day it used a full postpack. We can see that a full postback has occurred since the URL changed.</p> <p>Now we want to make the &lsquo;Delete With JavaScript&rsquo; button work.</p> <p>So we can add some JavaScript:</p> <pre><code>&lt;script src="/Scripts/jquery-1.8.2.min.js"&gt;&lt;/script&gt; &lt;script&gt; (function ($) { $(document).on("click", 'a:contains(Delete With JavaScript)', function (e) { e.preventDefault(); var that = $(this), tr = that.closest('tr'); $.ajax({ url: this.href, type: 'GET', dataType: 'JSON', contentType: 'application/json; charset=utf-8' }).success(function (data) { if (data.Deleted === true) { tr.remove(); $('.status').text("Using JavaScript"); } }); }); })(jQuery); &lt;/script&gt; </code></pre> <p>So this just looks for an anchor tag with the text &lsquo;Delete With JavaScript&rsquo; since we don&rsquo;t want to stop the other buttons from working.</p> <p>Now we need to update the Route to handle content negotiation.</p> <pre><code>Get[@"/delete/{id}"] = _ =&gt; { var id = (int) _.id; var item = Products.Single(x =&gt; x.Id == id); Products.Remove(item); Model.Products = Products; Model.Deleted = true; return Negotiate .WithModel((object) Model) .WithMediaRangeModel("application/json", new { Model.Deleted }) .WithView("index"); }; </code></pre> <p>The implementation is identical to before, the only difference is we replaced &lsquo;View&rsquo; with &lsquo;Negotiate&rsquo;.</p> <p><span class="note"><strong>Note:</strong> The Model being returned is Dynamic, this allows me to just add the properties to it without having to define a static class. As a result I have to cast the Model to an object when passing it into the method &lsquo;WithModel&rsquo;, if I was using a static class I wouldn&rsquo;t need to do this.</span></p> <p>If the type if different, in this case the request was for application/json, then we pass back only the data we need, rather than everything.</p> <p>Now if we run the same page again but we click on &lsquo;Delete With JavaScript&rsquo;</p> <p><img src="/images/nancy-conneg-3.png" /></p> <p>This time when we delete item 4, the URL hasn&rsquo;t changed, but it&rsquo;s removed the item and said it was done using the JavaScript.</p> <p>Now when we click either link, both scenarios are handled by the one route.</p> <h2>Also&hellip;</h2> <p>This isn&rsquo;t limited to just this use case, if you&rsquo;re building an API and you want the route to respond with XML or JSON, or maybe even your own content type, this is an awesome feature that you can use to handle these scenarios so your consumers can get what they want, in the format they want, with no effort from you.</p> <p>Content Negotiation &ndash; Is Awesome.</p> <p>The demo for this project can be found <a href="https://github.com/phillip-haydon/NancyConnegDemo">here on github</a>.</p> Sinatra Book Review 2012-11-03T00:00:00-07:00 http://www.philliphaydon.com/2012/11/sinatra-book-review/ <p>For a while I&rsquo;ve been wanting to pick-up Ruby, but not rails, every man and his dog is doing rails and everything I read I feel like it tries to do too much, much in the same way I feel ASP.NET MVC get&rsquo;s in the way too much by trying to do too much for me. I think I&rsquo;ve written &lsquo;too much&rsquo; too much. :)</p> <p>So I&rsquo;m learning Ruby + Sinatra.</p> <p>Currently I&rsquo;m reading <a href="http://www.amazon.com/Programming-Ruby-1-9-Pragmatic-Programmers/dp/1934356085/">Programming Ruby 1.9</a> but I just went on holiday, and figured a smaller book was a better idea to take with me.</p> <p>Enter <a href="http://www.amazon.com/Sinatra-Up-Running-Alan-Harris/dp/1449304230">Sinatra Up and Running</a></p> <p>This book, written by <a href="https://twitter.com/anachronistic">Alan Harris</a> &amp; <a href="https://twitter.com/konstantinhaase">Konstantin Haase</a>, is brilliant. Clocking in at 103 pages (less than the 122 Amazon states), this book is everything you need to get your feet off the ground with Sinatra and get building applications.</p> <!--excerpt--> <p>It tells you about Sinatra, the fundamentals, what&rsquo;s happening behind the scenes for you, and then building your own application. At no point does the book divert away to dribble and get boring, it keeps itself simple and concise.</p> <p>It doesn&rsquo;t go too in depth that the book is confusing, and it&rsquo;s not too basic that an advanced rubist would get bored.</p> <p>If you&rsquo;re considering learning Sinatra I highly recommend picking up this book.</p> Keep an eye on Raygun to zap all your errors away. 2012-10-24T00:00:00-07:00 http://www.philliphaydon.com/2012/10/keep-an-eye-on-raygun-to-zap-all-your-errors-away/ <p>Mindscape, creator of the awesome <a href="http://www.mindscapehq.com/products/web-workbench">Web Workbench</a> tool for visual studio as well as other awesome products, made an <a href="https://twitter.com/MindscapeHQ/status/260851721230761985">announcement</a> today on twitter of a new up coming product they are working on.</p> <p><a href="http://raygun.io/?ref=1QWEy">Raygun</a></p> <p>Little is currently known about this since trying to find out more from Mindscape is like squeezing blood from a stone, but what I do know is it&rsquo;s a online error tracking and reporting service, that will allow you to track errors that occur on both the serverside <em>and</em> the clientside.</p> <p>This looks awesome and quite possible be a great <a href="http://raygun.io/?ref=1QWEy">Elmah Replacement</a> for my projects, since it will have the ability to track clientside issues that usually go unnoticed.</p> <p>Not only that but the community will be able to contribute their own plugins and extensions to the service!</p> <p>Apparently Alpha invites will start going out in the next 2 weeks, so head on over to <a href="http://raygun.io/?ref=1QWEy">http://raygun.io/?ref=1QWEy</a> and signup!</p> Running 2 queries is fine, you don't need to ALWAYS eager load! 2012-10-06T00:00:00-07:00 http://www.philliphaydon.com/2012/10/running-2-queries-is-fine-you-dont-need-to-always-eager-load/ <p>Every now-n-then someone comes into JabbR or messages me asking about the best way to load a relationship. Often enough what the person is trying to do is Eager load some reference/relational data.</p> <p>For example, Order / Customer.</p> <p>If we want to load an Order and get the Customer information at the same time, we can eagerly fetch this information using an ORM, in RavenDB we can Include the results so that when we query them, the session already has the information and doesn&rsquo;t need to round-trip to the database.</p> <h3>You don&rsquo;t need to!</h3> <p>There really is nothing wrong with executing two separate queries in this scenario.</p> <pre><code>var order = Session.Load&lt;Order&gt;(123); var customer = Session.Load&lt;Customer&gt;(order.CustomerId); </code></pre> <p>These queries are fast to execute, and there really is nothing wrong with it! You can add some complexity in your NHibernate mappings by creating a reference so you can Eagerly fetch the reference and have 1 trip to the database etc. But this really isn&rsquo;t where eager fetching is beneficial!</p> <!--excerpt--> <h3>Your database is located off-site</h3> <p>A good reason to want to eager fetch to avoid hitting the database again, is because your database server isn&rsquo;t sitting next to your web server.</p> <p>Most website&rsquo;s are so small you have the database and website on the same server, these are small little hobby sites.</p> <p>Then you grow and you have:</p> <p><img src="/images/running-two-queries-1.png" alt="" /></p> <p>These are sitting next to each other. Latency is low, you&rsquo;ve probably got gigabit connection between the two, and sending 2 queries is very fast.</p> <p>However if you&rsquo;re using something like RavenHQ where the database isn&rsquo;t right next to each other:</p> <p><img src="/images/running-two-queries-2.png" alt="" /></p> <p>Now we have to deal with hops and latency and all sorts of issues, being able to issue 1 query and get 2 results back is now beneficial!</p> <h3>The problem with not eager fetching</h3> <p>If you&rsquo;re not careful, then you can end up in scenarios where you have SelectN+1. For example if I was listing ALL orders, and fetching the Customer for each Order I displayed to the screen.</p> <p>This could end up issuing LOTS of queries.</p> <p>Being able to say:</p> <pre><code>var result = Session.Query&lt;Order&gt;().Fetch(x =&gt; x.Customer).Eager; </code></pre> <p>Means when we can issue 1 query, and avoid ending up in a SelectN+1 scenario that might severely hurt performance.</p> <p>RavenDB allows you to include results, but it does one thing most (if not all) ORMs don&rsquo;t allow you to do. <code>Load&lt;T&gt;</code> has an overload which takes an array of Ids.</p> <p>This allows you to do something like:</p> <pre><code>var orders = Session.Query&lt;Order&gt;().ToList(); var customers = Session.Load&lt;Customer&gt;(orders.Select(x =&gt; x.CustomerId).ToArray()); </code></pre> <p>Now you can compose your results together on the screen.</p> <h3>Note:</h3> <p>I&rsquo;m not against eager loading, all I&rsquo;m saying is you don&rsquo;t ALWAYS have to eager load, there are times when it&rsquo;s far more beneficial to eager load than others.</p> Raven.DynamicSession for RavenDB 2012-10-02T00:00:00-07:00 http://www.philliphaydon.com/2012/10/raven-dynamicsession-for-ravendb/ <p><em>Just a word of warning before you read this. I currently don&rsquo;t recommend using this project. MAYBE in the future you could use it, but for now I think it&rsquo;s just a cool proof of concept or something handy for rapid prototyping.</em></p> <p>Last week I had a discussion with <a href="https://twitter.com/@PrabirShrestha">@PrabirShrestha</a> in <a href="https://jabbr.net/">JabbR</a> about APIs for MongoDB to achieve something along the lines of:</p> <pre><code>db.posts.insert({title: ''first''}, function(err, doc){}) </code></pre> <p>Example from: <a href="http://alexeypetrushin.github.com/mongo-lite/docs/index.html">http://alexeypetrushin.github.com/mongo-lite/docs/index.html</a></p> <p>Or</p> <pre><code>_db.Users.Insert(Name: "Steve", Age: 50); </code></pre> <p>Example from: <a href="http://simplefx.org/simpledata/docs/pages/Modify/AddingData.html">http://simplefx.org/simpledata/docs/pages/Modify/AddingData.html</a></p> <p>Looking at the syntax and thinking about C#&rsquo;s DynamicObject I decided to see what I could come up with. I spent the better part of the next 2-3 hours messing around in Visual Studio, chatting and coming back to it, and came up with this gist.</p> <p><a href="https://gist.github.com/3798206">https://gist.github.com/3798206</a></p> <!--excerpt--> <p>I basically came up with a really rough working prototype. Currently it doesn&rsquo;t do much, but what it allows you to do is wrap RavenDB&rsquo;s IDocumentSession in what I&rsquo;ve called &lsquo;DynamicSession&rsquo; inside this class is a nested class called Chainer, which is/will be responsible for all the method/property chaining that occurs to make the API completely dynamic.</p> <p>Rather than creating a normal session, you create OpenDynamicSession. All it really does is save you the hassle of having to write two using statements.</p> <pre><code>public static class DynamicSessionExtension { public static DynamicSession OpenDynamicSession(this IDocumentStore store) { return new DynamicSession(store.OpenSession()); } } </code></pre> <p>It just opens the normal RavenDB session and passes it in.</p> <pre><code>using (dynamic session = store.OpenDynamicSession()) { session.Bananas.insert(new { Colour = "Yellow", Bunch = 14 }, 1); session.SaveChanges(); } </code></pre> <p>This code snippet allows you to call a dynamic property, &lsquo;Bananas&rsquo;, this refers to the collection. (Word of warning, RavenDB is case sensitive, I don&rsquo;t know what to do in this scenario)</p> <p>Then the next part is the command, which takes in an anonymous type as the first parameter, and an id as the second parameter. I haven&rsquo;t figured out how to let RavenDB generate the Id yet, not sure if it&rsquo;s possible but will see :)</p> <pre><code>using (dynamic session = documentStore.OpenDynamicSession()) { dynamic post1 = session.Posts.load(123); Console.WriteLine(post1.Name); } </code></pre> <p>In this scenario. I&rsquo;m just calling Load which returns a dynamic type, which you can call all the properties you want off.</p> <p>I&rsquo;ve created no POCOs :)</p> <p>So far the two obstacles I&rsquo;ve had to overcome have been:</p> <h2>Collection Names</h2> <p>RavenDB uses meta data to put the document into a collection. When inserting, RavenDB doesn&rsquo;t know what the collection is since there&rsquo;s no class name to infer it from. To get around this I worked out that when you have an object from RavenDB, you can access the meta data. This is done like so:</p> <pre><code>var metadata = Session.Advanced.GetMetadataFor(objectToStore); </code></pre> <p>This allows me to use the collection named accessed previously to assign it to the RavenDB Entity Name:</p> <pre><code>metadata["Raven-Entity-Name"] = CollectionName; </code></pre> <p>This allows all the documents to be grouped together and be placed under the correct collection.</p> <p>As I mentioned before RavenDB is case sensitive, so if you insert:</p> <p><code>session.Posts</code> then <code>session.posts</code>, these will be stored in two different collections (this is a feature of RavenDB I personally don&rsquo;t like, yes I LOVE RavenDB, but even it has things I don&rsquo;t like, nothing is perfect)</p> <p>Meta data brings me to the 2nd issue&hellip;</p> <h2>CLR Type</h2> <p>RavenDB persists the CLR Type in the meta data, this is so when it uses Newtonsoft.Json it can use that data to create the object you want, and return it.</p> <p>The problem with inserting anonymous types, is there is no real CLR Type information to persist, so what you end up with is all your entities being persisted as:</p> <blockquote><p>&ldquo;Raven-Clr-Type&rdquo;: &ldquo;&lt;>f__AnonymousType11[[System.String, mscorlib]], Raven.DynamicSession.TestConsole&rdquo;</p></blockquote> <p>This prevents us from doing:</p> <pre><code>using (var session = store.OpenSession()) { result = session.Load&lt;Post&gt;("posts/123"); } </code></pre> <p>Since RavenDB is unable to convert the type. This happens to be another rather annoying thing I find in RavenDB. When using Index&rsquo;s you can get away with casting them using As<T> or calling AsProjection<T> when the type differs in terms of properties. But when accessing a specific document via the Id, you can&rsquo;t return your own specified type, regardless if the properties match.</p> <p>I got around this by using a convention, first of all I persist MY OWN information to the meta data :)</p> <pre><code>metadata[DynamicClrTypePlaceHolder] = CollectionName; </code></pre> <p>Which persists to the document like so:</p> <blockquote><p>&ldquo;Raven.DynamicSession.DynamicClrTypePlaceHolder&rdquo;: &ldquo;People&rdquo;</p></blockquote> <p>Then I setup the store with a convention.</p> <pre><code>store.Conventions.FindClrType = (id, doc, metadata) =&gt; { var clrType = metadata.Value&lt;string&gt;(DynamicSession.DynamicClrTypePlaceHolder); if (clrType.Equals(clrPlaceHolder, StringComparison.OrdinalIgnoreCase)) return type.FullName; return metadata.Value&lt;string&gt;(Constants.RavenClrType); }; </code></pre> <p>This checks to see if it matches and then returns the type I define rather than what RavenDB has set.</p> <p>Here&rsquo;s a working test: <a href="https://github.com/phillip-haydon/Raven.DynamicSession/blob/master/src/Raven.DynamicSession.Tests/QueryGetFixture.cs">https://github.com/phillip-haydon/Raven.DynamicSession/blob/master/src/Raven.DynamicSession.Tests/QueryGetFixture.cs</a></p> <p>At the moment this convention is hard-coded to handle one type but I plan on expanding it out and putting it into some configuration you can setup once.</p> <p>This project can be found on GitHub:</p> <p><a href="https://github.com/phillip-haydon/Raven.DynamicSession">https://github.com/phillip-haydon/Raven.DynamicSession</a></p> <p>I plan to continue expanding on it and trying to cover all the basics of RavenDB, some of it&rsquo;s not easy and the hacks I have to put in place to handle POCOs makes me feel that this can never be used in the real world.</p> <p>But as a prototype I think it&rsquo;s pretty cool!</p> <p>Interested in hearing anyone&rsquo;s feedback. It&rsquo;s still changing, I&rsquo;ve spent maybe 4 hours total playing around with this. So there hasn&rsquo;t been a LOT of work involved. I did have some help from StackOverflow, around wanting to know if it&rsquo;s possible to chain dynamic methods, but turns out you need to create new objects with information and chain those.</p> <p><a href="http://stackoverflow.com/questions/12634250/possible-to-get-chained-value-of-dynamicobject">http://stackoverflow.com/questions/12634250/possible-to-get-chained-value-of-dynamicobject</a></p> NancyFX and Areas 2012-09-29T00:00:00-07:00 http://www.philliphaydon.com/2012/09/nancy-and-areas/ <p>A while back <a href="https://twitter.com/ayende">@ayende</a> wrote a <a href="http://ayende.com/blog/156609/reviewing-dinner-party-ndash-nerd-dinner-ported-to-ravendb-on-ravenhq">blog post</a> about <a href="https://github.com/NancyFx/DinnerParty">DinnerParty</a> in which he mentioned <a href="http://nancyfx.org/">NancyFX</a>, a lightweight web framework. <a href="https://twitter.com/jchannon">@jchannon</a> recently wrote about a <a href="http://blog.jonathanchannon.com/2012/09/21/nancyfx-ravendb-nerddinner-and-me/">blog post about NancyFX RavenDB and himself</a>.</p> <p>So I&rsquo;ve spent the better part of the last few months learning it, and needless to say, it&rsquo;s awesome. So I got asked a question, how would I handle &lsquo;Areas&rsquo; with Nancy, like we would with ASP.NET MVC?</p> <p>Well it&rsquo;s pretty simple, all it really consists of is&hellip; a module containing a root path.</p> <p>Lets begin with the following folder structure defining a &lsquo;HomeModule&rsquo; for both the Root Website, and the Admin section.</p> <p><img src="/images/nancy-areas-1.png" /></p> <p>Both these HomeModule classes are identical, with the small exception that the Admin one specifies a Root Path.</p> <!--excerpt--> <h3>Root > HomeModule</h3> <pre><code>namespace NancyAreasDemo.Modules { public class HomeModule : NancyModule { public HomeModule() { Get["/"] = _ =&gt; { return "Website Home"; }; } } } </code></pre> <h3>Root > Admin > HomeModule</h3> <pre><code>namespace NancyAreasDemo.Modules.Admin { public class HomeModule : NancyModule { public HomeModule() : base("admin") { Get["/"] = _ =&gt; { return "Admin Home"; }; } } } </code></pre> <p>When we run this in a browser now we can get both the Main Website and the Admin section:</p> <p><img src="/images/nancy-areas-2.png" /></p> <p>Now let&rsquo;s add some Views.</p> <p><img src="/images/nancy-areas-3.png" /></p> <p>So for the Area &lsquo;Admin&rsquo; has it&rsquo;s own folder under the Views folder, with it&rsquo;s own &lsquo;Home&rsquo; folder matching the Module name.</p> <p>This is very similar to using Area&rsquo;s in ASP.NET MVC.</p> <p>Now we need to add some ViewLocationConventions:</p> <pre><code>protected override void ConfigureConventions(NancyConventions nancyConventions) { nancyConventions.ViewLocationConventions.Insert(0, (viewName, model, context) =&gt; { if (string.IsNullOrWhiteSpace(context.ModulePath)) return null; return string.Concat("views/", context.ModulePath, "/", context.ModuleName, "/", viewName); }); base.ConfigureConventions(nancyConventions); } </code></pre> <p>This is configured in the Bootstrapper (<a href="https://github.com/NancyFx/Nancy/wiki/Bootstrapper">read Nancy Bootstrapper docs here</a>) (<a href="https://github.com/NancyFx/Nancy/wiki/View-location-conventions">read the Nancy View Location Convention docs here</a>)</p> <p><span class="note"><strong>Note:</strong> Hoping to get this convention included into Nancy :) if <a href="https://twitter.com/thecodejunkie">@TheCodeJunkie</a> will accept the PR</strong></p> <p><span class="note"><strong>Note 2:</strong> The PR was accepted into 0.13, but you can still create your own conventions.</strong></p> <p>This convention basically tells Nancy to look firstly, for the View in:</p> <p>views/<strong><em>module path</em></strong>/<strong><em>module name</em></strong>/<strong><em>view name</em></strong></p> <p>If you don&rsquo;t use this convention then you will need to remove the &lsquo;Home&rsquo; directory from the &lsquo;Admin&rsquo; folder and place all your views in there. Which isn&rsquo;t convenient when you have multiple modules in that area.</p> <p>Now in the views we can put some sample content:</p> <h3>Admin HTML Page</h3> <pre><code>&lt;!DOCTYPE html&gt; &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt; &lt;head&gt; &lt;title&gt;&lt;/title&gt; &lt;/head&gt; &lt;body&gt; This comes from Admin view. &lt;/body&gt; &lt;/html&gt; </code></pre> <h3>Root HTML Page</h3> <pre><code>&lt;!DOCTYPE html&gt; &lt;html xmlns="http://www.w3.org/1999/xhtml"&gt; &lt;head&gt; &lt;title&gt;&lt;/title&gt; &lt;/head&gt; &lt;body&gt; This comes from the root view. &lt;/body&gt; &lt;/html&gt; </code></pre> <p>Now when we run the pages:</p> <p><img src="/images/nancy-areas-4.png" /></p> <p>And that&rsquo;s it. Nice quick simple Area&rsquo;s using Nancy!</p> <p>You can view the <a href="https://github.com/phillip-haydon/NancyAreasDemo">GitHub repository</a> for the demo used to write this blog post.</p> My volume gets lowered/reduced when swapping applications (solution) 2012-09-25T00:00:00-07:00 http://www.philliphaydon.com/2012/09/my-volume-gets-lowered-reduced-when-swapping-applications-solution/ <p>I have absolutely no idea who made this retarded feature but if I met them, I would like to think I would punch them in the face for all the pain they have caused me, of making me reformat my computer thinking I had somehow stuffed up my installation of the OS.</p> <p>Windows 7 and 8 have this feature which allows an application to take priority of the speakers. Meaning if you&rsquo;re in Application A, and you&rsquo;re playing music, and you swap to Application B, then B will reduce the volume of A so that itself can have louder volume.</p> <p>This is really annoying when you want to play music, and then you load up a game, and the music is drowned out by game sounds.</p> <p>The solution? Disable that shit!</p> <p>1) Go into your Playback devices:</p> <p><img src="/images/windows-volume-1.png" /></p> <p>2) Select the device properties:</p> <p><img src="/images/windows-volume-2.png" /></p> <!--excerpt--> <p>3) Untick Exclusive Mode:</p> <p><img src="/images/windows-volume-3.png" /></p> <p>4) Repeat the same steps for Recording Devices:</p> <p><img src="/images/windows-volume-4.png" /></p> <p>Save it all, and reboot. <em>(Windows 7 seems to work without rebooting, it didn&rsquo;t take affect in Windows 8 for me until I rebooted)</em></p> <p>Bam, no more windows taking over my Audio!</p> RavenDB... What am I persisting, what am I querying? (part 3) 2012-07-19T00:00:00-07:00 http://www.philliphaydon.com/2012/07/ravendb-what-am-i-persisting-what-am-i-querying-part-3/ <p><a href="/2012/07/ravendb-what-am-i-persisting-what-am-i-querying/">Part 1</a> <br/> <a href="/2012/07/ravendb-what-am-i-persisting-what-am-i-querying-part-2/">Part 2</a></p> <p>In part 3 I want to show you how to query References.</p> <p>In the previous post I showed you three basic classes that demonstrate a Relationship between Order and OrderLine, and a Reference to User from Order using the UserId.</p> <p>I&rsquo;ve setup some really basic test data:</p> <pre><code>using (var session = store.OpenSession()) { session.Store(new User { FirstName = "Phillip", Surname = "Haydon", Username = "phillip.haydon", Password = "somepassword" }); session.Store(new User { FirstName = "Edward", Surname = "Norton", Username = "edward.norton", Password = "somepassword" }); session.Store(new Order { UserId = "users/1", DateOrdered = DateTime.Now, DateUpdated = DateTime.Now, Status = "Ordered", Lines = new List&lt;OrderLine&gt; { new OrderLine { Discount = 0m, PricePerUnit = 13.95m, Quantity = 5, SkuCode = "SN78" }, new OrderLine { Discount = 0m, PricePerUnit = 13.95m, Quantity = 5, SkuCode = "SN78" } } }); session.SaveChanges(); } </code></pre> <p>This creates two collections:</p> <!--excerpt--> <p><img src="/images/ravendb-what-am-i-persisting-part-3-1.png" alt="" /></p> <p>With our Order document looking like:</p> <pre><code>{ "UserId": "users/1", "DateOrdered": "2012-07-13T23:34:40.5542680", "DateUpdated": "2012-07-13T23:34:40.5542680", "Status": "Ordered", "Lines": [ { "PricePerUnit": 13.95, "Quantity": 5, "Discount": 0.0, "SkuCode": "SN78" }, { "PricePerUnit": 13.95, "Quantity": 5, "Discount": 0.0, "SkuCode": "SN78" } ] } </code></pre> <p>What&rsquo;s cool about RavenDB Studio is that it shows us that the UserId is a reference.</p> <p><img src="/images/ravendb-what-am-i-persisting-part-3-2.png" alt="" /></p> <p>RavenDB links the reference up for you as well so you can click it and it will navigate you directly to the document that is being referenced.</p> <p>There are three ways that we can load this data in code.</p> <ul> <li>Roundtrip to the store</li> <li>Include</li> <li>Transform</li> </ul> <h2>Roundtrip to the store</h2> <p>This method is easy peasy, and it&rsquo;s pretty similar to something you would do when working with a relational database.</p> <p>We do this by calling Load on the Order, then using the value from <code>Order.UserId</code> to load the User.</p> <pre><code>using (var session = store.OpenSession()) { var order = session.Load&lt;Order&gt;("orders/1"); var user = session.Load&lt;User&gt;(order.UserId); Console.WriteLine("Lines: " + order.Lines.Count()); Console.WriteLine("FirstName: " + user.FirstName); } </code></pre> <p>When we run this we get an output like so:</p> <p><img src="/images/ravendb-what-am-i-persisting-part-3-3.png" alt="" /></p> <p>The problem with this approach is that we have to go to RavenDB twice, shown here:</p> <p><img src="/images/ravendb-what-am-i-persisting-part-3-4.png" alt="" /></p> <p>But it achieves the desired result.</p> <h2>Include</h2> <p>The include method is very similar, the only difference is we tell RavenDB to include the User when we fetch the Order.</p> <p>This can be done like so:</p> <pre><code>using (var session = store.OpenSession()) { var order = session.Include&lt;Order&gt;(x =&gt; x.UserId) .Load&lt;Order&gt;("orders/1"); var user = session.Load&lt;User&gt;(order.UserId); Console.WriteLine("Lines: " + order.Lines.Count()); Console.WriteLine("FirstName: " + user.FirstName); } </code></pre> <p>As you can see all we have done is add the Include method to our initial query.</p> <p>When we run this we get the exact same output, the difference this time is that RavenDB will issue 1 query for data.</p> <p><img src="/images/ravendb-what-am-i-persisting-part-3-5.png" alt="" /></p> <p>So the first query for Order, includes the User. This User object is now part of the current RavenDB Session, so now when we load the User on the next line it doesn&rsquo;t need to go to RavenDB to fetch it, it already has it.</p> <h2>Transform</h2> <p>This last method is quite different to the last two, it involves writing an index and implementing TransformResults.</p> <p>First we start by defining an index, which basically just grabs the UserId in the map, then looks up the user in the transform.</p> <pre><code>public class Order_WithUser : AbstractIndexCreationTask&lt;Order&gt; { public Order_WithUser() { Map = o =&gt; from s in o select new { s.UserId }; TransformResults = (database, results) =&gt; from s in results let user = database.Load&lt;User&gt;(s.UserId) select new { s.Id, s.UserId, s.DateOrdered, s.DateUpdated, s.Status, s.Lines, User = user }; } } </code></pre> <p>Then we can query it and return it as a new model that includes the User <em>(this could also be added to the Order and not persisted but I&rsquo;ve made it a separate model for demonstration)</em></p> <pre><code>public class OrderResult { public string Id { get; set; } public string UserId { get; set; } public DateTime DateOrdered { get; set; } public DateTime DateUpdated { get; set; } public string Status { get; set; } public IEnumerable&lt;OrderLine&gt; Lines { get; set; } public User User { get; set; } } using (var session = store.OpenSession()) { var order = session.Query&lt;Order, Order_WithUser&gt;() .Where(x =&gt; x.Id == "orders/1") .AsProjection&lt;OrderResult&gt;() .SingleOrDefault(); Console.WriteLine("Lines: " + order.Lines.Count()); Console.WriteLine("FirstName: " + order.User.FirstName); } </code></pre> <p>When we run this again we get the same results, however in RavenDB we have had to query against an index, rather than just grabbing the document as is.</p> <p><img src="/images/ravendb-what-am-i-persisting-part-3-6.png" alt="" /></p> <p>That concludes part 3. Any questions, leave a comment or join the <a href="http://jabbr.net/#/rooms/RavenDB">JabbR RavenDB</a> chat room.</p> RavenDB... What am I persisting, what am I querying? (part 2) 2012-07-17T00:00:00-07:00 http://www.philliphaydon.com/2012/07/ravendb-what-am-i-persisting-what-am-i-querying-part-2/ <p><a href="/2012/07/ravendb-what-am-i-persisting-what-am-i-querying/">Part 1</a><br/> <a href="/2012/07/ravendb-what-am-i-persisting-what-am-i-querying-part-2/">Part 2</a> I want to discuss Relationships &amp; References, and the difference between the two.<br/> <a href="/2012/07/ravendb-what-am-i-persisting-what-am-i-querying-part-3/">Part 3</a></p> <p>Taking from part 1&rsquo;s example, lets add a User to the mix:</p> <pre><code>public class Order { public string Id { get; set; } public string UserId { get; set; } public string DateOrdered { get; set; } public string DateUpdated { get; set; } public string Status { get; set; } // Other properties... public IEnumerable&lt;OrderLine&gt; Lines { get; set; } } public class OrderLine { public int Quantity { get; set; } public decimal Price { get; set; } public decimal Discount { get; set; } public string SkuCode { get; set; } // Other Properties } public class User { public string Id { get; set; } public string Username { get; set; } public string Password { get; set; } public string FirstName { get; set; } public string Surname { get; set; } // Other Properties } </code></pre> <p>As you can see I&rsquo;ve added &lsquo;UserId&rsquo; to the Order, not a &lsquo;User&rsquo; just the Id part. This is because I don&rsquo;t want direct access to the User. <em>(It is possible to map a User in RavenDB, but I don&rsquo;t believe that is always a good idea. Save it for special occasions.)</em></p> <!--excerpt--> <p>If we were modelling this in a Relational Database, we would have a relationship between Order and User, add some foreign keys, and if we threw an ORM into the mix we would probably have an Order object looking like:</p> <p><img src="/images/ravendb-what-am-i-persisting-part-2-1.png" alt="" /></p> <p>Where we wire up the User object inside the Order. This in the long run lets to all sorts of problem. Then we would eager load the User when we fetch the order, maybe on the order we need to fetch the product, so on and so forth. It just gets messy and complicated.</p> <p>So rather than adding the User object to the Order, in RavenDB we would just add the UserId. But why are we doing this? Below I have modelled the Relational Database Table Structure.</p> <p><img src="/images/ravendb-what-am-i-persisting-part-2-2.png" alt="" /></p> <p>As you can see I&rsquo;ve highlighted two Foreign Keys. But I&rsquo;ve named them both differently, one is a reference and one is a relationship.</p> <h2>Reference</h2> <p>The reference has no real purpose other than to maintain referential integrity in the database. Not for our sake, but mainly because we want to keep our DBAs happy. The problem with this however, is we don&rsquo;t actually need it. An order can still exist in the system without a User. We still know who paid for it by the billing information, and we know who it was shipped to from the shipping information.</p> <p>Maybe the user wanted to specify what email or phone number to contact them. This information isn&rsquo;t information that belongs to the user. The only reason we have &lsquo;UserId&rsquo; is to so when that user logs into the application, we know which orders belong to him, the information on those orders don&rsquo;t relate to the User other. This is not a relationship, it&rsquo;s a reference. A reference to the User.</p> <h2>Relationship</h2> <p>The next one is the Relationship, and it has a real purpose beyond referential integrity. An OrderLine really can&rsquo;t exist without an Order. Without an order it has no meaning or purpose. The problem is because there are multiple Lines to a single Order, we need to persist them in their own table.</p> <p>An OrderLine might have a <em>Reference</em> to Product, but an OrderLine can exist without the Product. Since an OrderLine relates back to an Order, you don&rsquo;t have a real need to ever load an OrderLine by itself. You may edit/delete lines, but that will always be done via the Order.</p> <p>This ultimately creates a Root Aggregate, the Order becomes the Root while the Lines become the children, and an OrderLine is always loaded with an Order, but never on it&rsquo;s own.</p> <h2>User/Product Data Duplication</h2> <p>First thing you may think by having the First/Last name of the User on the Addresses, or the Addresses data copied into the Order&rsquo;s Billing/Delivery Address, is duplicating data. Same with taking a Products Price/Name/SKUCode and putting it on the OrderLine.</p> <p>This isn&rsquo;t data duplication.</p> <p>If a user changes his name, you have a Reference to the user still, but at the time he billed his order, he was John Doe, not John Snow. His address may have changed but we captured it at the point of ordering. This is information that belongs to the Order, not to the User. The fact we have the same name in both the User and Order is a mute point, because visually they are the same, but from a business perspective, they are not the same.</p> <h2>Benefit of Duplicating</h2> <p>So we are copying data now. Is this a good thing? Well lets think about it in an Order History screen.</p> <p>If a user logged in, went to their account history and viewed their previous order:</p> <h3>Using a relational database, no copying data.</h3> <p>In the scenario using a relational database, we would use the selected OrderId to load the Order, eager load the OrderLine. Fetch the User, Addresses, Product.</p> <p>Fetching all this data could be done multiple different ways, but already we are asking for a lot of data. A lot of which we aren&rsquo;t using.</p> <p>Then we have to compose a lot of that data together, or maybe we joined it and created a new object for displaying it all.</p> <h3>Using a document database, copying the data.</h3> <p>In the scenario of using a document database, we would query for the Order using the OrderId. And begin displaying all the data.</p> <p>We already knew the Product name that was captured and used at the time of purchase, but we would have the ProductId to reference it back to the Product in the system.</p> <p>We already know who it was shipped to, and who it was billed to.</p> <p>We don&rsquo;t need to find the User or the Product or the Addresses or anything like that. We have all the information for that Order.</p> <hr /> <p>In my next post I&rsquo;ll talk about loading References. This one is already long.</p> <p>Again I hope this makes sense, feel free to comment and ask questions :)</p> RavenDB... What am I persisting, what am I querying? (part 1) 2012-07-11T00:00:00-07:00 http://www.philliphaydon.com/2012/07/ravendb-what-am-i-persisting-what-am-i-querying/ <p><a href="/2012/07/ravendb-what-am-i-persisting-what-am-i-querying/">Part 1</a><br/> <a href="/2012/07/ravendb-what-am-i-persisting-what-am-i-querying-part-2/">Part 2</a><br/> <a href="/2012/07/ravendb-what-am-i-persisting-what-am-i-querying-part-3/">Part 3</a></p> <p>A couple of questions that pop&rsquo;s up a lot in the <a href="https://jabbr.net/#/rooms/RavenDB">#RavenDB</a> <a href="https://jabbr.net/">JabbR</a> chat room by people picking up RavenDB for the first time are; <em>what am I persisting?, and how do I query relationships?.</em></p> <p>When we use relational databases we often de-normalize our data into multiple tables, usually this is done to get rid of duplication of data. We do this by adding 100&rsquo;s of foreign keys to our tables relating things all over the place, we had a CountryId to our Address, a UserId to our Order, an OrderId to our OrderLine.</p> <p>There&rsquo;s many reasons why this was done, some of which Oren describes in his <a href="http://ayende.com/blog/153026/embracing-ravendb">Embracing RavenDB post.</a></p> <p>Then when we go to query those relationships we have to join data, when we have an entity with multiple relationships we end up getting into complex queries with cartesian joins, performance starts to degrade, and things just get messy.</p> <p>When working with Document Databases we throw all that out the window and we deal with Root Aggregates. These are objects that are responsible for their child objects, you don&rsquo;t load the child objects individually, they are loaded with the root or parent object.</p> <!--excerpt--> <p>The most common example I see is Blog/Posts/Comments, but I&rsquo;m going to explain an easier scenario.</p> <h2>Order/OrderLine</h2> <p>The Order/Orderline is much easier to understand since it&rsquo;s a scenario would probably always end up being the same in every system.</p> <p>It also easier to understand because when displaying an OrderLine in any system, it&rsquo;s always displayed with the Order details, and never by itself. So when we query for the Order it makes sense to always get the OrderLine at the same time.</p> <p>When working with Business Rules applied to an Order, they almost always apply to the OrderLines also, so again you&rsquo;re working with the entire Order, not a portion of it.</p> <p>When starting out it&rsquo;s hard to imagine, but the OrderLine is actually part of the Order, it&rsquo;s not a separate entity, it&rsquo;s just when we persist it in two tables since that makes more sense in a relational database, and it ends up feeling like two separate things, when in reality, it&rsquo;s still the same object.</p> <pre><code>public class Order { public string Id { get; set; } // Other properties... public IEnumerable&lt;OrderLine&gt; Lines { get; set; } } public class OrderLine { public int Quantity { get; set; } public decimal Price { get; set; } public decimal Discount { get; set; } public string SkuCode { get; set; } // Other Properties } </code></pre> <p>So when we persist this with a Relational Database these would go into two different tables. Order and OrderLine tables, joined by a foreign key.</p> <p>But now that we are thinking about the Root Aggregate, the Order, when we persist this with RavenDB we persist just the Order. When we persist &lsquo;just the order&rsquo; that means we persist the ENTIRE Order object, <em>including the OrderLines, since they are the Order</em>.</p> <p>When persisted to RavenDB we end up with a JSON document that looks similar to:</p> <pre><code>{ Id: 'orders/123', Lines: [ { Quantity: 1, Price: 12.95, Discount: null, SkuCode: 'N1C3' }, { Quantity: 3, Price: 6.23, Discount: null, SkuCode: 'F4K21' } ] } </code></pre> <p><span class="note"><strong>Note:</strong> I purposely left out other properties for now.</span></p> <p>As you can see we are persisting the entire root object itself. We don&rsquo;t put OrderLines into a separate document or collection.</p> <p><span class="note"><strong>Note:</strong> I do realise I&rsquo;ve mentioned persisting the entire object multiple times, but it&rsquo;s something that some people find hard to wrap their head around at first. It confused me when I first started messing around with MongoDB.</span></p> <p>When we query for the Order: <code>session.Load&lt;Order&gt;("orders/123");</code> we end up fetching all the OrderLines at the same time. No joins, no separate queries, just the entire order.</p> <p>In a relational database we would have had to issue 2 separate queries, or join the tables together, like:</p> <pre><code>SELECT * FROM [Order] o LEFT JOIN [OrderLine] ol ON o.Id = Ol.OrderId </code></pre> <p>This makes querying the database more complicated than it needs to be. There are other ways around this in a relational database, you can <a href="/2012/03/ormlite-blobbing-done-with-nhibernate-and-serialized-json/">blob the OrderLines</a>. But then you lose the ability to search against OrderLines.</p> <h2>Why this example and not Post/Comments?</h2> <p>I don&rsquo;t think Post/Comments is a good example to work from, Comment&rsquo;s can be displayed with a Post, and without a Post, they can be paged, displayed on an individual page, in a &lsquo;latest comments&rsquo; column on your blog, etc.</p> <p>Some of these scenarios may justify putting Comments into their own collection.</p> <p>However, more often than not, non-popular blogs such as my own only occur a few comments, so there&rsquo;s no real reason to put them in their own collection, you can easily get away with putting them on the Post document.</p> <p>I think this comes down to personal preference and the business problem you&rsquo;re trying to solve, but for a learning exercise it makes it harder to understand. My personal preference is to store Comment&rsquo;s in a separate collection, because you click through from the post listing screen to the post and load the comment&rsquo;s, and if there are > x number of comments then I would page them and only display the latest comments, or high rated comments if they were rated voted up/down.</p> <p>I hope that clear&rsquo;s up what&rsquo;s being persisted.</p> <p><strong>In part 2 I&rsquo;m going to go over References <em>(Relationships)</em>, and in part 3 MapReduce <em>(doing all those fancy SQL queries inside RavenDB and what is happening)</em></strong></p> Multiple IISExpress Sites profiled with DotTrace 2012-06-18T00:00:00-07:00 http://www.philliphaydon.com/2012/06/multiple-iisexpress-sites-profiled-with-dottrace/ <p>Yesterday (14th of June) I had a need to run more than one website while running <a href="http://www.jetbrains.com/">JetBrain&rsquo;s</a> <a href="http://www.jetbrains.com/profiler/">DotTrace</a>, to give a bit of background, Website A needs to redirect to Website B in order to simulate a single sign on.</p> <p>Website B can&rsquo;t be accessed without using the SSO, so in order to profile Website B I need to run Website A.</p> <p>The problem is when using DotTrace, I have to select the website I wish to profile:</p> <p><img src="/images/multiple-iis-1.png" alt="" /></p> <p>The problem with that, is that when you run the profiler it only starts up one of the websites. I need it to start both.</p> <p>This would be easy to profile if the Standard Version came with Attach To Process feature. But unfortunately that only comes with Professional.</p> <p>That way, when I debug using Visual Studio I could pick the process to profile:</p> <p><img src="/images/multiple-iis-2.png" alt="" /></p> <p><em>(Information can be found by right clicking the system try and selecting &lsquo;show all applications&rsquo;)</em></p> <!--excerpt--> <p>However that isn&rsquo;t an option.</p> <p>I had a few idea&rsquo;s of trying to get it to work such as having multiple start-up projects, in VS and using the &lsquo;Profile Startup Project&rsquo; feature.</p> <h2>The Solution</h2> <p>The solution was to run IISExpress with the parameters to startup the sites. The problem with this approach is that you cannot specify an array of website&rsquo;s to start.</p> <p>IISExpress gives you the following options when you run /?</p> <p><strong>/config:config-file</strong><br/> The full path to the applicationhost.config file. The default value is the IISExpressconfigapplicationhost.config file that is located in the user"s Documents folder.</p> <p><strong>/site:site-name</strong><br/> The name of the site to launch, as described in the applicationhost.config file.</p> <p><strong>/siteid:site-id </strong><br/> The ID of the site to launch, as described in the applicationhost.config file.</p> <p><strong>/path:app-path </strong><br/> The full physical path of the application to run. You cannot combine this option with the /config and related options.</p> <p><strong>/port:port-number </strong><br/> The port to which the application will bind. The default value is 8080. You must also specify the /path option.</p> <p><strong>/clr:clr-version </strong><br/> The .NET Framework version (e.g. v2.0) to use to run the application. The default value is v4.0. You must also specify the /path option.</p> <p><strong>/systray:true|false </strong><br/> Enables or disables the system tray application. The default value is true.</p> <p><strong>/trace:trace-level </strong><br/> Valid values are &ldquo;none&rdquo;, &ldquo;n&rdquo;, &ldquo;info&rdquo;, &ldquo;i&rdquo;, &ldquo;warning&rdquo;, &ldquo;w&rdquo;, &ldquo;error&rdquo;, and &ldquo;e&rdquo;. The default value is none.</p> <p>If we look at the applicationhost.config file for the site entries we get:</p> <pre><code>&lt;sites&gt; &lt;site name="TestProjectOne" id="1"&gt; &lt;application path="/" applicationPool="Clr4IntegratedAppPool"&gt; &lt;virtualDirectory path="/" physicalPath="C:\Users\phillip\Documents\Visual Studio 2010\Projects\TestProjectOne\TestProjectOne" /&gt; &lt;/application&gt; &lt;bindings&gt; &lt;binding protocol="http" bindingInformation="*:7946:localhost" /&gt; &lt;/bindings&gt; &lt;/site&gt; &lt;site name="TestProjectTwo" id="2"&gt; &lt;application path="/" applicationPool="Clr4IntegratedAppPool"&gt; &lt;virtualDirectory path="/" physicalPath="C:\Users\phillip\Documents\Visual Studio 2010\Projects\TestProjectOne\TestProjectTwo" /&gt; &lt;/application&gt; &lt;bindings&gt; &lt;binding protocol="http" bindingInformation="*:8921:localhost" /&gt; &lt;/bindings&gt; &lt;/site&gt; &lt;siteDefaults&gt; &lt;logFile logFormat="W3C" directory="%IIS_USER_HOME%\Logs" /&gt; &lt;traceFailedRequestsLogging directory="%IIS_USER_HOME%\TraceLogFiles" enabled="true" maxLogFileSizeKB="1024" /&gt; &lt;/siteDefaults&gt; &lt;applicationDefaults applicationPool="Clr4IntegratedAppPool" /&gt; &lt;virtualDirectoryDefaults allowSubDirConfig="true" /&gt; &lt;/sites&gt; </code></pre> <p>As you can see there&rsquo;s nothing special in the website&rsquo;s. Except for one thing!</p> <p>This attribute:</p> <pre><code>applicationPool="Clr4IntegratedAppPool" </code></pre> <p>What IISExpress doesn&rsquo;t tell you is that you can start an application pool.</p> <p>Running the command <code>/AppPool:Clr4IntegratedAppPool</code> gives us:</p> <pre><code>C:\Program Files (x86)\IIS Express&gt;iisexpress.exe /AppPool:Clr4IntegratedAppPool Starting IIS Express ... Successfully registered URL "http://localhost:7946/" for site "TestProjectOne" application "/" Successfully registered URL "http://localhost:8921/" for site "TestProjectTwo" application "/" Registration completed IIS Express is running. Enter "Q" to stop IIS Express </code></pre> <p>To get this working with DotTrace, we just need to select > Profile Application</p> <p><img src="/images/multiple-iis-3.png" alt="" /></p> <p>Running this will run IISExpress and all the website&rsquo;s under the same process id:</p> <p><a href="/images/multiple-iis-4.png"><img src="/images/multiple-iis-4.png" alt="" /></a></p> <p>(click to enlarge)</p> <p>Bam, not we&rsquo;re now able to run multiple sites at once, and even profile them all at once!</p> <h2>The Catch</h2> <p>There is one gotcha with this approach, if you work on multiple sites, you end up running those up as well:</p> <pre><code>C:\Program Files (x86)\IIS Express&gt;iisexpress.exe /AppPool:Clr4IntegratedAppPool Starting IIS Express ... Successfully registered URL "http://localhost:7946/" for site "TestProjectOne" application "/" Successfully registered URL "http://localhost:8921/" for site "TestProjectTwo" application "/" Successfully registered URL "http://localhost:16207/" for site "JabbR" application "/" Registration completed IIS Express is running. Enter "Q" to stop IIS Express </code></pre> <p>This can be fixed easily, to get around this, simply open up your applicationhost.config file located in:</p> <pre><code>C:Users\\*user\*\DocumentsIIS\Expressconfig\applicationhost.config </code></pre> <p>Locate the application pools:</p> <pre><code>&lt;applicationPools&gt; &lt;add name="Clr4IntegratedAppPool" managedRuntimeVersion="v4.0" managedPipelineMode="Integrated" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" /&gt; &lt;add name="Clr4ClassicAppPool" managedRuntimeVersion="v4.0" managedPipelineMode="Classic" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" /&gt; &lt;add name="Clr2IntegratedAppPool" managedRuntimeVersion="v2.0" managedPipelineMode="Integrated" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" /&gt; &lt;add name="Clr2ClassicAppPool" managedRuntimeVersion="v2.0" managedPipelineMode="Classic" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" /&gt; &lt;add name="UnmanagedClassicAppPool" managedRuntimeVersion="" managedPipelineMode="Classic" autoStart="true" /&gt; &lt;applicationPoolDefaults managedRuntimeLoader="v4.0"&gt; &lt;processModel /&gt; &lt;/applicationPoolDefaults&gt; &lt;/applicationPools&gt; </code></pre> <p>Add a new entry:</p> <pre><code>&lt;add name="TestProjectAppPool" managedRuntimeVersion="v4.0" managedPipelineMode="Integrated" CLRConfigFile="%IIS_USER_HOME%\config\aspnet.config" autoStart="true" /&gt; </code></pre> <p>And update your website&rsquo;s to use this new application pool:</p> <pre><code>&lt;site name="TestProjectOne" id="1"&gt; &lt;application path="/" applicationPool="TestProjectAppPool"&gt; &lt;virtualDirectory path="/" physicalPath="C:\Users\phillip\Documents\Visual Studio 2010\Projects\TestProjectOne\TestProjectOne" /&gt; &lt;/application&gt; &lt;bindings&gt; &lt;binding protocol="http" bindingInformation="*:7946:localhost" /&gt; &lt;/bindings&gt; &lt;/site&gt; &lt;site name="TestProjectTwo" id="2"&gt; &lt;application path="/" applicationPool="TestProjectAppPool"&gt; &lt;virtualDirectory path="/" physicalPath="C:\Users\phillip\Documents\Visual Studio 2010\Projects\TestProjectOne\TestProjectTwo" /&gt; &lt;/application&gt; &lt;bindings&gt; &lt;binding protocol="http" bindingInformation="*:8921:localhost" /&gt; &lt;/bindings&gt; &lt;/site&gt; &lt;site name="JabbR" id="3"&gt; &lt;application path="/" applicationPool="Clr4IntegratedAppPool"&gt; &lt;virtualDirectory path="/" physicalPath="D:\Development\phillip-haydon\JabbR\JabbR" /&gt; &lt;/application&gt; &lt;bindings&gt; &lt;binding protocol="http" bindingInformation="*:16207:localhost" /&gt; &lt;/bindings&gt; &lt;/site&gt; </code></pre> <p>Now we can run our new application pool:</p> <pre><code>C:\Program Files (x86)\IIS Express&gt;iisexpress.exe /AppPool:TestProjectAppPool Starting IIS Express ... Successfully registered URL "http://localhost:7946/" for site "TestProjectOne" application "/" Successfully registered URL "http://localhost:8921/" for site "TestProjectTwo" application "/" Registration completed IIS Express is running. Enter "Q" to stop IIS Express </code></pre> <p>And now when we profile we only get the two websites we want, running.</p> <p>Even though DotTrace Standard Edition doesn&rsquo;t allow you to attach to process, you can easily debug across multiple sites, without the need of upgrading to the Pro edition.</p> <p>It would be really cool if JetBrains could add a new option to the IIS Expression Application profile screen, so that we can select the application pool to run if we want to start up multiple websites:</p> <p><img src="/images/multiple-iis-5.png" alt="" /></p> <p>That would be awesome :) and I think it would be really easy for them to implement!</p> Using NHibernate with ServiceStack 2012-06-05T00:00:00-07:00 http://www.philliphaydon.com/2012/06/using-nhibernate-with-servicestack/ <p>A few people have asked me how they can use ServiceStack with other persistence technologies like RavenDB and NHibernate, or if you really must&hellip; EntityFramework&hellip; Rather than <a href="https://github.com/ServiceStack/ServiceStack.OrmLite">ServiceStack.OrmLite</a> or <a href="https://github.com/ServiceStack/ServiceStack.Redis">ServiceStack.Redis</a> like many of the examples in SS show.</p> <p><span class="note"><strong>Note:</strong> This isn&rsquo;t about best practice on using NHibernate or ServiceStack, my services are named just to quickly get something up and running.</span></p> <p><span class="note"><strong>Note 2:</strong> This blog post may not be completely inline with the GitHub repository since I will be updating the repository to include some additional samples in the future.</span></p> <p>I&rsquo;ve created a small sample project which can be found <a href="https://github.com/phillip-haydon/ServiceStack-NHibernate-Sample">here on GitHub</a>, I plan to flesh it out a little bit from the date this is posted, but it&rsquo;s purely there as a sample.</p> <h2>No Repositories!</h2> <p>Utilizing other persistence frameworks is really easy with ServiceStack, the thing with ServiceStack Services is that they are doing something concise, it&rsquo;s a single service implementation, so there&rsquo;s really no need to use repositories for them, you gain absolutely no benefit from using repositories other than adding an additional layer of abstraction and complexity to your services.</p> <!--excerpt--> <p>That doesn&rsquo;t mean you don&rsquo;t have to use repositories, if you REALLY want to use them. You can, and I&rsquo;ll add a sample of using a repository with the RestService implementation.</p> <h2>Setting Up SS</h2> <p>Assuming you&rsquo;ve setup NHibernate and your mappings, all we need to do is setup ServiceStack.</p> <p>First things first! Install ServiceStack.</p> <pre><code>PM&gt; Install-Package ServiceStack </code></pre> <p><span class="note"><strong>Note:</strong> You can use ServiceStack.Host.* (replace the * with MVC or ASPNET) which will automatically configure the web.config. Personally I prefer to do it myself.</span></p> <p>Using the Package Manager (or GUI) install Service Stack into your project. This should add the required code to the web.config, if not you can double check your web config is setup like shown <a href="https://github.com/ServiceStack/ServiceStack/wiki/Create-your-first-webservice">here</a>.</p> <p>Next in the global.asax we want to create an AppHost and configure it:</p> <pre><code>public class Global : HttpApplication { public class SampleServiceAppHost : AppHostBase { private readonly IContainerAdapter _containerAdapter; public SampleServiceAppHost(ISessionFactory sessionFactory) : base("Service Stack with Fluent NHibernate Sample", typeof(ProductFindService).Assembly) { base.Container.Register&lt;ISessionFactory&gt;(sessionFactory); } public override void Configure(Funq.Container container) { container.Adapter = _containerAdapter; } } void Application_Start(object sender, EventArgs e) { var factory = new SessionFactoryManager().CreateSessionFactory(); (new SampleServiceAppHost(factory)).Init(); } } </code></pre> <p>In our service host we take in our NHibernate Session Factory, and we wire it up to <a href="https://github.com/ServiceStack/ServiceStack/wiki/The-IoC-container">Funq (the default IoC container SS uses)</a>, this is so when the Service is resolved, it gets the SessionFactory to create a Session.</p> <p>If you were using RavenDB, this is where you would inject your DocumentStore, and if you were using EntityFramework, you would inject that DataContext thing it uses.</p> <p>So when the application is started, we create the SessionFactory, and create an instance of the AppHost, passing in the SessionFactory.</p> <h2>Services</h2> <p>Now that SS is setup, we need to implement our services. This part is just as easy.</p> <p>In some of the SS samples such as <a href="https://github.com/ServiceStack/ServiceStack.Examples/blob/master/src/ServiceStack.MovieRest/MovieService.cs#L135">this one</a>, dependencies are injected via the properties. Personally I don&rsquo;t like this, because the service is absolutely dependent on that dependency. It cannot function without it, so in my opinion this dependency should be done via the constructor.</p> <p>I&rsquo;m not going to go over EVERY service implementation, I&rsquo;m only going to show Insert and Select By Id.</p> <h2>Insert</h2> <p>Besides the model defined for NHibernate, we need our Service Request Model, and we need our implementation.</p> <pre><code>public class ProductInsert { public string Name { get; set; } public string Description { get; set; } } </code></pre> <p>This is our Service Request Model, really plain and simple DTO used for doing a Product Insert.</p> <pre><code>public class ProductInsertService : ServiceBase&lt;ProductInsert&gt; { public ISessionFactory NHSessionFactory { get; set; } public ProductInsertService(ISessionFactory sessionFactory) { NHSessionFactory = sessionFactory; } protected override object Run(ProductInsert request) { using (var session = NHSessionFactory.OpenSession()) using (var tx = session.BeginTransaction()) { var result = request.TranslateTo&lt;Product&gt;(); session.Save(result); tx.Commit(); } return null; } } </code></pre> <p>This is our Service Implementation, as you can see we have a constructor which takes in the <code>ISessionFactory</code>, this is our NHibernate <code>ISessionFactory</code>, you need to be careful here since ServiceStack has it&rsquo;s own <code>ISessionFactory</code>:</p> <p><img src="/images/servicestack-nhibernate-1.png" alt="" /></p> <p>We need to make sure this is the NHibernate one:</p> <p><img src="/images/servicestack-nhibernate-2.png" alt="" /></p> <p>You can of course, inject your Unit Of Work, or the NHibernate Session, or what ever you like, if you&rsquo;re using Repositories you may opt to inject an instance of your desired repository such as <code>IProductRepository</code>. For this example I&rsquo;m using NHibernates SessionFactory so that the service is responsible for opening a Session and Transaction.</p> <p>So that&rsquo;s all there is to it, inject your SessionFactory, or your desired persistence implementation, and do your thing.</p> <p>The cool thing about ServiceStack is it has built in functionality to do mapping.</p> <pre><code>var result = request.TranslateTo&lt;Product&gt;(); </code></pre> <p><code>TranslateTo&lt;T&gt;</code> is functionality built into ServiceStack for mapping 1 object to another.</p> <p>If you want to update an object, ServiceStack handles that too using PopulateWith.</p> <pre><code>var existing = session.Get&lt;Product&gt;(request.Id) .PopulateWith(request); </code></pre> <p>No need to introduce anything like AutoMapper.</p> <h2>Select By Id</h2> <p>This service I&rsquo;ve called <code>ProductFindService</code>, in the future there will be a <code>ProductSearchService</code> to show selection by criteria.</p> <p>Like the Insert service, I&rsquo;ve defined a simple model which only has an Id property for selecting the product out:</p> <pre><code>public class ProductFind { public Guid Id { get; set; } } </code></pre> <p>In addition to the Request Model I have a Response Model:</p> <pre><code>public class ProductFindResponse : IHasResponseStatus { public class Product { public Guid Id { get; set; } public string Name { get; set; } public string Description { get; set; } } public Product Result { get; set; } public ResponseStatus ResponseStatus { get; set; } } </code></pre> <p>This has a nested Product class which defines all the properties of a Product. The outer Response object has a Result and Status. (<a href="http://www.philliphaydon.com/2012/03/service-stack-exceptions-and-errors/">status is for Exception/Error information</a>)</p> <p>As you can see the Response is the same name as the Request, with Response appended to the end, so that SS can create this object itself.</p> <p>When I setup these Request/Response objects in Visual Studio, I use an extension called <a href="http://visualstudiogallery.msdn.microsoft.com/9d6ef0ce-2bef-4a82-9a84-7718caa5bb45">NestIn</a> which allows me to select the two classes and nest the Response under the Request like so:</p> <p><img src="/images/servicestack-nhibernate-3.png" alt="" /></p> <p>The service is similar to the insert, we inject the SessionFactory, open a Session, no transaction (unless you want to use 2nd level caching, but that&rsquo;s beyond this post) and select out the Product:</p> <pre><code>public class ProductFindService : ServiceBase&lt;ProductFind&gt; { public ISessionFactory NHSessionFactory { get; set; } public ProductFindService(ISessionFactory sessionFactory) { NHSessionFactory = sessionFactory; } protected override object Run(ProductFind request) { using (var session = NHSessionFactory.OpenSession()) { var result = session.Load&lt;Models.Product&gt;(request.Id); return new ProductFindResponse { Result = result.TranslateTo&lt;ProductFindResponse.Product&gt;() }; } } } </code></pre> <p>Lastly we return a new Response object, and translate the result from NHibernate to the Response result.</p> <p>Easy peasy :)</p> <p>Swapping out NHibernate for anything else like RavenDB or MongoDB is super easy. I hope this helps those few people who have asked me how to use other persistence frameworks get up and running.</p> <p>I find it amazing how little code you&rsquo;re required to write to get a ServiceStack Service up and running.</p> ASP.NET MVC 4 has, REAL EMPTY PROJECT! 2012-06-05T00:00:00-07:00 http://www.philliphaydon.com/2012/06/asp-net-mvc-4-has-real-empty-project/ <p>I installed Visual Studio 2012 over the weekend, and was BLOWN AWAY when I created a brand new MVC 4 project to find:</p> <p><img src="/images/asp-real-empty-1.png" alt="" /></p> <p>See that &lsquo;Empty&rsquo; project&hellip; It now creates:</p> <p><img src="/images/asp-real-empty-2.png" alt="" /></p> <p>Look at that, nice and clean. It still forces the whole WebApi thing on you, but atleast they cut out 90% of the rubbish that was in it previously.</p> <p>I&rsquo;m REALLY happy with the changes after I previously ranted earlier this year:</p> <p><a href="/2012/02/mvc-4-project-templates-are-stupid/">MVC 4 Project Templates are stupid</a></p> <p>Thank you Microsoft!</p> CodeSchool.com is the most awesome way to learn 2012-04-11T00:00:00-07:00 http://www.philliphaydon.com/2012/04/codeschool-com-is-the-most-awesome-way-to-learn/ <p>On the 1st of April, Glenn Block posted a link that was too good to be true.</p> <p><a href="http://www.codeschool.com">http://www.codeschool.com</a></p> <p><img src="/images/code-school-1.png" alt="" /></p> <p>I have a habit of checking out most links that don&rsquo;t look like they link to a porn site or some look at photo of me and signup to see me naked. This particular link interested me because his tweet mentioned Backbone, something I&rsquo;ve been wanting to learn for a while and that I&rsquo;m been hoping <a href="https://twitter.com/#!/derickbailey">Derick Bailey</a> would add to his awesome JavaScript video collection: <a href="http://www.watchmecode.net">http://www.watchmecode.net</a> (<strong><em>his JavaScript series is absolutely brilliant and I&rsquo;ve learnt SO much from him so go support him so he will make more plz kthxbi</em></strong>)</p> <p>Anyway CodeSchool allows you to do level 1 of most courses for free, and if you like what you try you can purchase the rest of the course. Buying the courses 1 by 1 is a little bit expensive at $55 USD, but it&rsquo;s well worth the money.</p> <p>You&rsquo;re not getting just a video like you would with sites like Plural Sight, Tekpub, or any of the many other site&rsquo;s popping up lately.</p> <p>After each lesson in the course, there&rsquo;s a series of challenges which allow you to utilize your new gained knowledge and put it to the test. The Backbone course challenges you to make a small ToDo list application, starting out really basic and slowly modifying the code to follow best practice, or add new features.</p> <!--excerpt--> <p><img src="/images/code-school-2.png" alt="" /></p> <p>Each challenge builds on top of the previous, it gives you a story with some helpful information on functions to invoke or events to listen to, and you can dive back into the slides to double check things, should you forget.</p> <p>If you get stuck you can ask for hints.</p> <p>Each time you use a hint, the number of points you can gain from the challenge drops, yes that&rsquo;s right, there&rsquo;s a points counter to entice you to complete the challenges.</p> <p><img src="/images/code-school-3.png" alt="" /> <img src="/images/code-school-4.png" alt="" /></p> <p>To top it all off you get this nifty little public profile with badges to show what you&rsquo;ve completed:</p> <p><img src="/images/code-school-5.png" alt="" /></p> <p>This site is just amazing, it really taking learning to a whole new level. You&rsquo;re not stuck with boring old videos that you forget after you&rsquo;ve finished watching an hour of content, you spend up to 20 minutes learning a bunch of new stuff which you can use right away in their predefined challenges and get feedback right away. It goes a long way to help you understand what you&rsquo;re doing.</p> <p>I highly recommend anyone wanting to learn Backbone, grab this course:</p> <p><a href="http://www.codeschool.com/courses/anatomy-of-backbonejs">http://www.codeschool.com/courses/anatomy-of-backbonejs</a></p> <p>Or checkout some of the other courses available:</p> <p><a href="http://www.codeschool.com/courses">http://www.codeschool.com/courses</a></p> My must have (short) list programs/extensions etc 2012-03-24T00:00:00-07:00 http://www.philliphaydon.com/2012/03/my-must-have-short-list-programs-and-extensions-etc/ <p>We have all seen these lists before, but I&rsquo;ve decided I&rsquo;ll make a list of all the software I use or think are a must have, blog it, then this time next year I can do the list again and see how much it&rsquo;s changed.</p> <h3>Visual Studio 2010</h3> <p>What can I say, I&rsquo;m a .NET Developer :)</p> <h3>ReSharper</h3> <p><a href="http://www.jetbrains.com/resharper/">http://www.jetbrains.com/resharper/</a></p> <p>This should just ship with Visual Studio, without ReSharper I feel so unproductive in VS.</p> <h3>MindScape Web Workbench</h3> <p><a href="http://www.mindscapehq.com/products/web-workbench">http://www.mindscapehq.com/products/web-workbench</a></p> <p>This VS extension just gets better and better, I primarily got it to write LESS and CoffeeScript, but recently they added support for minifying and combining JavaScript and CSS files. Really cool stuff and I highly recommend it.</p> <h3>BugAid</h3> <p><a href="http://www.bugaidsoftware.com/">http://www.bugaidsoftware.com/</a></p> <!--excerpt--> <p>This is a relatively new extension, it extends the debugging tools in Visual Studio and gives more information where it can. It was a little annoying at first, but they are listening to the community and fixing issues, adding features, it&rsquo;s coming along nicely and I recommend it!</p> <h3>MightyMoose / NCrunch</h3> <p><a href="http://www.continuoustests.com/">http://www.continuoustests.com/</a> / <a href="http://www.ncrunch.net/">http://www.ncrunch.net/</a></p> <p>These two tools are the same taken from two different approaches with two different goals. As a result I&rsquo;m really torn between them. I love features from both, and I&rsquo;ve been using MightyMoose at work and NCrunch at home. NCrunch has code-coverage which Greg Young <a href="http://goodenoughsoftware.net/2012/03/21/code-coverage/">disagrees</a> with. I guess that&rsquo;s what&rsquo;s stopping me from adopting <a href="http://goodenoughsoftware.net/2012/03/01/mighty-moose-lolcats/">LOLCats</a> and <a href="http://goodenoughsoftware.net/2012/03/06/gary/">Gary</a>, and other cool features in MM.</p> <h3>PostgreSQL</h3> <p><a href="http://www.postgresql.org/">http://www.postgresql.org/</a></p> <p>One thing I don&rsquo;t like about SQL Server, is having to install it and have it run all the time&hellip; But I&rsquo;ve always loved PostgreSQL as well, and hated MySQL. (<em>checkout Tekpubs &ldquo;The Perils of MySQL&rdquo; for a glimpse of why I don&rsquo;t like it</em>). Why I think this is a must have is I recently found out <a href="http://www.postgresonline.com/journal/archives/172-Starting-PostgreSQL-in-windows-without-install.html">you don&rsquo;t actually need to install it to run</a>. This makes it great for a dev environment where you want to run up an instance on demand when you need it.</p> <h3>RavenDB</h3> <p><a href="http://ravendb.net/">http://ravendb.net/</a></p> <p>If you&rsquo;re a .NET developer and not already looking at, or using RavenDB&hellip; I don&rsquo;t know you&hellip; RavenDB makes working with a document database, fun, and easy to learn, and constantly blows my mind.</p> <h3>ILSpy</h3> <p><a href="http://wiki.sharpdevelop.net/ilspy.ashx">http://wiki.sharpdevelop.net/ilspy.ashx</a></p> <p>Of all the reflection tools available I prefer ILSpy. No real reason it just works and is fast.</p> <h3>Sublime Text</h3> <p><a href="http://www.sublimetext.com/">http://www.sublimetext.com/</a></p> <p>I used to be a massive fan of <a href="http://editplus.com/">EditPlus</a>, infact I&rsquo;ve used it for over 10 years&hellip; But recently found Sublime text due to <a href="http://tutsplus.com/course/30-days-to-learn-jquery/">Tuts+ 30 Days to learn jQuery</a>, and haven&rsquo;t gone back to EditPlus. It has awesome plugin features.</p> <h3>NHProf</h3> <p><a href="http://nhprof.com/">http://nhprof.com/</a></p> <p>Since I tend to use NHibernate quite a bit, well not so much now that RavenDB is about, but when using NHibernate I use NHProf to view the generated queries. One really, really, really handy tool.</p> <hr /> <p>There&rsquo;s a lot of other little tools I use, like Fiddler, <a href="https://chrome.google.com/webstore/detail/chklaanhfefbnpoihckbnefhakgolnmc">JSONView</a>, etc. But I just wanted to list the things I use all the time.</p> OrmLite Blobbing done with NHibernate and Serialized JSON... 2012-03-19T00:00:00-07:00 http://www.philliphaydon.com/2012/03/ormlite-blobbing-done-with-nhibernate-and-serialized-json/ <p>There seems to be a growing trend now with these Micro ORM&rsquo;s, at least that is what I see with <a href="https://github.com/ServiceStack/ServiceStack.OrmLite">ServiceStack.OrmLite</a>, which is the ability to persist properties of an object as a JSON, rather than in separate tables.</p> <p>Usually with a Relational approach you would create a <code>Customer</code> table, <code>Address</code> table, and most likely shove the Phone Numbers under separate columns of the customer for <code>HomePhone</code> and <code>Mobile</code>.</p> <p>This means we are limited to two types of phone numbers, and require joining or querying for the addresses.</p> <p>Do we really need separate columns for phone numbers? Do we really need to persist the addresses in another table?</p> <p>One problem I see with putting addresses into it&rsquo;s own table, is the temptation to relate them to an Order (assuming this is some sort of eCommerce system) when really there is no relationship between a customer&rsquo;s address, and the address on an order.</p> <p>Really, the order should have it&rsquo;s own address, otherwise you can never delete or update an address on a customer, and you can&rsquo;t delete the customer. However I digress and this is a topic for another day.</p> <!--excerpt--> <h2>Example by OrmLite</h2> <p>This post is about how to do it with NHibernate, but I&rsquo;m going to start by showing the example in OrmLite, then use the same example for NHibernate.</p> <p><span class="note"><strong>Note:</strong> OrmLite by default persists as JSV-format (JSON+CSV) rather than JSON. I&rsquo;m currently unaware of any way to change it to be JSON.</span></p> <p>The customer is the root aggregate, and has his own Addresses and Phone Numbers, and is modelled like so:</p> <pre><code>public enum PhoneType { Home, Work, Mobile, } public enum AddressType { Home, Work, Other, } public class Address { public string Line1 { get; set; } public string Line2 { get; set; } public string ZipCode { get; set; } public string State { get; set; } public string City { get; set; } public string Country { get; set; } } public class Customer { public Customer() { this.PhoneNumbers = new Dictionary&lt;PhoneType, string&gt;(); this.Addresses = new Dictionary&lt;AddressType, Address&gt;(); } [AutoIncrement] // Creates Auto primary key public virtual int Id { get; set; } public virtual string FirstName { get; set; } public virtual string LastName { get; set; } [Index(Unique = true)] // Creates Unique Index public virtual string Email { get; set; } public virtual Dictionary&lt;PhoneType, string&gt; PhoneNumbers { get; set; } //Blobbed public virtual Dictionary&lt;AddressType, Address&gt; Addresses { get; set; } //Blobbed public virtual DateTime CreatedAt { get; set; } } </code></pre> <p><span class="note"><strong>Note:</strong> The attributes are for OrmLite and are not used by NHibernate, and the properties have been made virtual for NHibernate.</span></p> <p>So using OrmLite if we insert some data like so:</p> <pre><code>var customer = new Customer { FirstName = "Phillip", LastName = "Haydon", Email = "test@test.com" }; customer.Addresses.Add(AddressType.Home, new Address { Line1 = "Unit 31", Line2 = "102 Banana Street", City = "Sydney", Country = "Australia", State = "NSW", ZipCode = "2009" }); customer.PhoneNumbers.Add(PhoneType.Mobile, "+61 411 122 34"); customer.PhoneNumbers.Add(PhoneType.Home, "+61 256 3234"); cmd.Insert(customer); </code></pre> <p>We can query for that data and we get the following results:</p> <p><a href="/images/nhibernate-blobbing-1.png"><img src="/images/nhibernate-blobbing-1.png" alt="" /></a></p> <p><em>(Click on the image to see it fully)</em></p> <p>As you can see PhoneNumbers are stored like so:</p> <blockquote><p>{Mobile:+61 411 122 34,Home:+61 256 3234}</p></blockquote> <p>And Addresses are stored like:</p> <blockquote><p>{Home:{Line1:Unit 31,Line2:102 Banana Street,ZipCode:2009,State:NSW,City:Sydney,Country:Australia}}</p></blockquote> <p>Now if we query for that data back out:</p> <pre><code>var customer = cmd.QuerySingle&lt;Customer&gt;(1); </code></pre> <p><img src="/images/nhibernate-blobbing-2.png" alt="" /></p> <p>You can see we get all the information back out again, no problem! This stuff is built into OrmLite which is awesome, but how do we do it in NHibernate?</p> <h2>Custom NHibernate UserType</h2> <p>So now we want to do this in NHibernate. This is a <code>UserType</code> I wrote a long time ago, well&hellip; I re-wrote it recently but wrote the initial idea a long time ago, and I&rsquo;ve personally never seen anything similar in NHibernate.</p> <p>I&rsquo;ve put this on Gist &ndash; <a href="https://gist.github.com/1936188">https://gist.github.com/1936188</a></p> <pre><code>[Serializable] public class Blobbed&lt;T&gt; : IUserType where T : class { public new bool Equals(object x, object y) { if (x == null &amp;&amp; y == null) return true; if (x == null || y == null) return false; var xdocX = JsonConvert.SerializeObject(x); var xdocY = JsonConvert.SerializeObject(y); return xdocY == xdocX; } public int GetHashCode(object x) { if (x == null) return 0; return x.GetHashCode(); } public object NullSafeGet(IDataReader rs, string[] names, object owner) { if (names.Length != 1) throw new InvalidOperationException("Only expecting one column..."); var val = rs[names[0]] as string; if (val != null &amp;&amp; !string.IsNullOrWhiteSpace(val)) { return JsonConvert.DeserializeObject&lt;T&gt;(val); } return null; } public void NullSafeSet(IDbCommand cmd, object value, int index) { var parameter = (DbParameter)cmd.Parameters[index]; if (value == null) { parameter.Value = DBNull.Value; } else { parameter.Value = JsonConvert.SerializeObject(value); } } public object DeepCopy(object value) { if (value == null) return null; //Serialized and Deserialized using json.net so that I don't //have to mark the class as serializable. Most likely slower //but only done for convenience. var serialized = JsonConvert.SerializeObject(value); return JsonConvert.DeserializeObject&lt;T&gt;(serialized); } public object Replace(object original, object target, object owner) { return original; } public object Assemble(object cached, object owner) { var str = cached as string; if (string.IsNullOrWhiteSpace(str)) return null; return JsonConvert.DeserializeObject&lt;T&gt;(str); } public object Disassemble(object value) { if (value == null) return null; return JsonConvert.SerializeObject(value); } public SqlType[] SqlTypes { get { return new SqlType[] { new StringSqlType() }; } } public Type ReturnedType { get { return typeof(T); } } public bool IsMutable { get { return true; } } } </code></pre> <p>It&rsquo;s a generic class so that I can return the type of object back, and uses json.net to handle the serialization/deserialization of the object to JSON.</p> <p>Now when mapping the properties we can specify the <code>CustomType</code> like so:</p> <pre><code>Map(x =&gt; x.Addresses, "Addresses").CustomType&lt;Blobbed&lt;Dictionary&lt;AddressType, Address&gt;&gt;&gt;(); Map(x =&gt; x.PhoneNumbers, "PhoneNumbers").CustomType&lt;Blobbed&lt;Dictionary&lt;PhoneType, string&gt;&gt;&gt;(); </code></pre> <p>The example I&rsquo;m using has two dictionaries of values. But if you were mapping a single type such as a single <code>Address</code>, you would just specify the type as above, without the <code>Dictionary</code>, <code>.CustomType&lt;Blobbed&lt;Address&gt;&gt;()</code></p> <p>The full mapping for the Customer is:</p> <pre><code>public class CustomerMap : ClassMap&lt;Customer&gt; { public CustomerMap() { Table("Customer"); Id(x =&gt; x.Id, "Id").GeneratedBy.Identity(); Map(x =&gt; x.FirstName, "FirstName"); Map(x =&gt; x.LastName, "LastName"); Map(x =&gt; x.Email, "Email"); Map(x =&gt; x.CreatedAt, "CreatedAt"); Map(x =&gt; x.Addresses, "Addresses").CustomType&lt;Blobbed&lt;Dictionary&lt;AddressType, Address&gt;&gt;&gt;(); Map(x =&gt; x.PhoneNumbers, "PhoneNumbers").CustomType&lt;Blobbed&lt;Dictionary&lt;PhoneType, string&gt;&gt;&gt;(); } } </code></pre> <p>Now we can insert some data:</p> <pre><code>using (var tx = session.BeginTransaction()) { var customer = new Customer { FirstName = "Prentice", LastName = "Porter", Email = "banana3@test.com" }; customer.Addresses.Add(AddressType.Home, new Address { Line1 = "13/187 Jones St", City = "Auckland", Country = "New Zealand", ZipCode = "0629" }); customer.PhoneNumbers.Add(PhoneType.Mobile, "+64 27 551 443"); customer.PhoneNumbers.Add(PhoneType.Home, "+64 9445 1982"); session.SaveOrUpdate(customer); tx.Commit(); } </code></pre> <p>Again, the data is inserted:</p> <p><a href="/images/nhibernate-blobbing-3.png"><img src="/images/nhibernate-blobbing-3.png" alt="" /></a></p> <p><em>(Click on the image to see it fully)</em></p> <p>Only this data is serialized as JSON rather than JSV-format.</p> <p>PhoneNumbers:</p> <blockquote><p>{&ldquo;Mobile&rdquo;:&ldquo;+64 27 551 443&rdquo;,&ldquo;Home&rdquo;:&ldquo;+64 9445 1982&rdquo;}</p></blockquote> <p>And Addresses:</p> <blockquote><p>{&ldquo;Home&rdquo;:{&ldquo;Line1&rdquo;:&ldquo;13/187 Jones St&rdquo;,&ldquo;Line2&rdquo;:null,&ldquo;ZipCode&rdquo;:&ldquo;0629&rdquo;,&ldquo;State&rdquo;:null,&ldquo;City&rdquo;:&ldquo;Auckland&rdquo;,&ldquo;Country&rdquo;:&ldquo;New Zealand&rdquo;}}</p></blockquote> <p>If we query for the data:</p> <pre><code>var customer = session.Get&lt;Customer&gt;(2); </code></pre> <p><img src="/images/nhibernate-blobbing-4.png" alt="" /></p> <p>Just like OrmLite we get the object back just the same.</p> <h2>Things to note</h2> <p>The custom user type in it&rsquo;s current state does not handle inherited objects. If you want to support it, then you can modify it to serialize and deserialize using the type information.</p> <p>This can be done like so:</p> <pre><code>JsonConvert.SerializeObject(x, Formatting.None, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }); </code></pre> <p>And</p> <pre><code>JsonConvert.DeserializeObject&lt;T&gt;(val, new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }); </code></pre> <p>What this will do is include the type information on the serialized object:</p> <blockquote><p>{&ldquo;$type&rdquo;:&ldquo;System.Collections.Generic.Dictionary2[[NHibernateJsonTest.AddressType, NHibernateJsonTest],[NHibernateJsonTest.Address, NHibernateJsonTest]], mscorlib&rdquo;,&ldquo;Home&rdquo;:{&ldquo;$type&rdquo;:&ldquo;NHibernateJsonTest.Address, NHibernateJsonTest&rdquo;,&ldquo;Line1&rdquo;:&ldquo;13/187 Jones St&rdquo;,&ldquo;Line2&rdquo;:null,&ldquo;ZipCode&rdquo;:&ldquo;0629&rdquo;,&ldquo;State&rdquo;:null,&ldquo;City&rdquo;:&ldquo;Auckland&rdquo;,&ldquo;Country&rdquo;:&ldquo;New Zealand&rdquo;}}</p></blockquote> <h2>Why would you want to do this</h2> <p>To avoid unnecessary tables and mappings. The example above is a perfect example where we can remove the need for a table on data that is never searched against and is never related to anything else.</p> <p>There&rsquo;s no need for joins or adding additional columns. We just map the object or collection to a single column and we are done, and our code knows no different.</p> <p>Also, schema changes in blobs don&rsquo;t need DDL updates. If your model changes, you add new properties, or remove old properties, the blob will get updated next time you update your data. No more scripting off schema changes.</p> Service Stack Exceptions and Errors 2012-03-09T00:00:00-08:00 http://www.philliphaydon.com/2012/03/service-stack-exceptions-and-errors/ <p><span class="note"><strong>Note:</strong> This post on ServiceStack is to do with the C# Client. JavaScript posts will be coming in the future.</span></p> <p>One of the most painful experiences with WCF is exceptions, if using WCF makes you want to slit your wrists, exceptions in WCF will make you want douse yourself in petrol and light yourself on fire.</p> <p>Before you even get to your code exceptions, you have to wade yourself through piles of retarded errors to do with Contract Mismatching, Forcefully Disconnected, Binding Issues, Random Faults&hellip; The list goes on.</p> <p>Then, it all works in development, and you put it in production, and it doesn&rsquo;t work, and to debug it you got to modify the config file, setup the <a href="http://msdn.microsoft.com/en-us/library/ms732023.aspx">diagnostics logging</a>, then view it and trawl through piles of crap.</p> <p><img src="/images/service-stack-errors-1.png" alt="" /></p> <p>(image taken from: <a href="http://weblogs.asp.net/nmarun/archive/2011/06/10/wcf-service-trace-viewer-part-1.aspx">http://weblogs.asp.net/nmarun/archive/2011/06/10/wcf-service-trace-viewer-part-1.aspx</a>)</p> <p>And in the end, it was probably a PEBKAC issue where you forgot to put a stupid attribute on a property&hellip;</p> <!--excerpt--> <p>At my previous job, a couple of my friends were up until about 4am, they spent 16 hours debugging a WCF issue, because it&rsquo;s a pain.</p> <h2>Enter Service Stack</h2> <p>One of the things I looked at early on was how it handled errors, then I neglected them because I lost interest.There&rsquo;s a couple of exceptions that aren&rsquo;t SS related. The main one you may come across is:</p> <blockquote><p>WebException <br/> Unable to connect to remote server</p></blockquote> <p>This is kind of obvious, either the remote server doesn&rsquo;t exist or you mistyped the URL, or maybe there&rsquo;s a firewall issue or something, what ever it is, it can&rsquo;t connect to your service.</p> <blockquote><p>HttpException<br/> Maximum request length exceeded.</p></blockquote> <p>You may also get an HttpException if your requests are larger than 4mb, tho that&rsquo;s pretty large, not sure what you&rsquo;re sending to get that exception. But you can modify the <a href="http://msdn.microsoft.com/en-us/library/e1f13641(vs.71">maxRequestLength</a>.aspx) to get around this one.</p> <h3>MethodNotAllowed</h3> <p>This method is the easiest to fix, it basically means your service hasn&rsquo;t been implemented, or maybe it was implemented but you didn&rsquo;t tell the AppHost about it.</p> <h3>General Exceptions</h3> <p>General exceptions as I&rsquo;ll call, them, are any unhandled exceptions that are thrown, or ones that you explicitly throw yourself.</p> <p>These exceptions are always thrown as a <a href="https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack.Common/ServiceClient.Web/ServiceClientBase.cs#L278">WebServiceException</a>. This means we can capture these exceptions in a try-catch like so:</p> <pre><code>try { } catch (WebServiceException webEx) { //Handle our Web Service Exception } </code></pre> <p>There&rsquo;s a couple of different ways you can throw exceptions, or errors. You can raise your own:</p> <pre><code>throw new ApplicationException("Ahhhh stuff happened :S"); </code></pre> <p>And then you will get this when you call the service.</p> <p><img src="/images/service-stack-errors-2.png" alt="" /></p> <p>The second way is to throw an <code>HttpError</code>. There are a few predefined errors:</p> <p><img src="/images/service-stack-errors-3.png" alt="" /></p> <p>That allow you to just pass a message:</p> <pre><code>throw HttpError.NotFound("Coffee wasn't found :( sad panda"); </code></pre> <p><img src="/images/service-stack-errors-4.png" alt="" /></p> <p>Or you can throw your own new one which allows you to define the <code>HttpStatusCode</code>:</p> <pre><code>throw new HttpError(HttpStatusCode.PaymentRequired, "Kneedz monies plz", "Please deposit monies into my bank account :)"); </code></pre> <p><img src="/images/service-stack-errors-5.png" alt="" /></p> <p>This is great stuff, it gives a LOT of flexibility to be able to give the client informative error messages rather than the infamous:</p> <blockquote><p>The connection was closed unexpectedly</p></blockquote> <h2>My errors are empty</h2> <p>So I threw an error and I didn&rsquo;t get it on the client:</p> <p><img src="/images/service-stack-errors-6.png" alt="" /></p> <p>As you can see, I&rsquo;ve lost a lot of information :( This is while throwing the exact same HttpError in the previous example.</p> <p>One of the little catches with this is the automated error handling shown above requires a naming convention of your service Request/Response objects.</p> <p>Lets say we have a <code>UserSearch</code> request object.</p> <p>If an exception is thrown, ServiceStack will try and find an object of the same name, with the suffix &lsquo;Response&rsquo;</p> <p>This this case it would look for <code>UserSearchResponse</code>.</p> <p><a href="https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack.ServiceInterface/ServiceUtils.cs#L124">https://github.com/ServiceStack/ServiceStack/blob/master/src/ServiceStack.ServiceInterface/ServiceUtils.cs#L124</a></p> <p>As you can see, the method <code>GetResponseDtoName</code> takes in what your Request object was, and appends the <code>ResponseDtoSuffix</code></p> <p>The second catch is that your Response DTO must have a property on it named <code>ResponseStatus</code>:</p> <pre><code>public ResponseStatus ResponseStatus { get; set; } </code></pre> <p>Although it&rsquo;s not required, I personally add the interface <code>IHasResponseStatus</code> to my response DTO objects. This ensures that I remember to add the property, and it&rsquo;s named correctly with the correct type.</p> <p>Here is an example:</p> <pre><code>public class UserSearch { public string NameStartsWith { get; set; } } public class UserSearchResponse : IHasResponseStatus { public IEnumerable&lt;User&gt; Results { get; set; } public class User { public int Id { get; set; } public string Name { get; set; } } public ResponseStatus ResponseStatus { get; set; } } </code></pre> <p>My <code>UserSearch</code> object is the Request, and my response is <code>UserSearchResponse</code></p> <p>I discussed with <a href="https://github.com/mythz">Demis</a>, because I wanted to use the same response object for a few different services. But he&rsquo;s specifically designed SS this way, one of the reasons for the naming is:</p> <p>If a use Requests a <code>UserSearch</code>, he can expect a <code>UserSearchResponse</code>. He doesn&rsquo;t need to know anything about the contracts or the service implementation, just that given a UserSearch request, he will get a <code>UserSearchResponse</code>.</p> <p>It&rsquo;s actually a really good point and after thinking about it, I completely agree!</p> <h2>Conclusion</h2> <p>This is only the automated error handling you get with SS, there&rsquo;s more that you can do, dive in and handle it yourself if you like. But in my opinion, the automated stuff covers a lot of scenarios and is very helpful.</p> <p>For more information on Error handling visit the wiki here: <a href="https://github.com/ServiceStack/ServiceStack/wiki/Validation">https://github.com/ServiceStack/ServiceStack/wiki/Validation</a></p> RavenDB - Flattening Object Graphs and Projections 2012-03-04T00:00:00-08:00 http://www.philliphaydon.com/2012/03/ravendb-flattening-object-graphs-and-projections/ <p>One of the guys in <a href="http://jabbr.net/#/rooms/RavenDB">JabbR RavenDB</a> chat room had a pretty interesting problem that took a while to solve. The problem was that he wasn&rsquo;t trying to return anything to do with the original document, but get a flattened view of some information inside the document.</p> <p>The scenario was a <strong>Game Server</strong> which a collection of <strong>Connected Users</strong>.</p> <pre><code>public class GameServer { public string Id { get; set; } public string ServerName { get; set; } public IEnumerable&lt;User&gt; ConnectedUser { get; set; } public class User { public string UserId { get; set; } public string Name { get; set; } public DateTimeOffset DateConnected { get; set; } } } </code></pre> <p>Given say 3 servers with a bunch of users on each server, and searching for a user who&rsquo;s name begins with &lsquo;b&rsquo; the expected result was along the lines of:</p> <!--excerpt--> <table> <tbody> <tr> <th valign="top" width="100"><strong>UserId</strong></th> <th valign="top" width="100"><strong>Name</strong></th> <th valign="top" width="144"><strong>DateConnected</strong></th> <th valign="top" width="254"><strong>ServerName</strong></th> </tr> <tr> <td valign="top" width="100">users/3</td> <td valign="top" width="100">Bob</td> <td valign="top" width="144">15/03/2012 12:44</td> <td valign="top" width="254">iPGN CS #01 Iceworld</td> </tr> <tr> <td valign="top" width="100">users/2</td> <td valign="top" width="100">Bill</td> <td valign="top" width="144">15/03/2012 1:23</td> <td valign="top" width="254">3FL CS #4</td> </tr> <tr> <td valign="top" width="100">users/8</td> <td valign="top" width="100">Benny</td> <td valign="top" width="144">15/03/2012 1:18</td> <td valign="top" width="254">3FL CS #4</td> </tr> </tbody> </table> <p>So basically for each user you get the server he&rsquo;s connected to.</p> <p>We tried everything under the sun, Reduce, Transform, etc. But couldn&rsquo;t figure out how to get the results. Infact using a Transform we could get the # of results returned, except they were all NULL. :(</p> <p>Turns out it&rsquo;s rather easy using just a Map and <code>AsProjection&lt;T&gt;</code></p> <h2>Setup Data</h2> <p>Test data can be viewed here: <a href="http://pastie.org/3516113">http://pastie.org/3516113</a></p> <h2>Index</h2> <p>The index is really easy, it&rsquo;s basically a Select Many map, but we also need to store the results from the Map.</p> <pre><code>public class GameServers_ConnectedUsers : AbstractIndexCreationTask&lt;GameServer, GameServers_ConnectedUsers.IndexResult&gt; { public GameServers_ConnectedUsers() { Map = servers =&gt; from s in servers from y in s.ConnectedUsers select new { ServerName = s.ServerName, UserName = y.Name, DateConnected = y.DateConnected, UserId = y.UserId }; Store(x =&gt; x.ServerName, FieldStorage.Yes); Store(x =&gt; x.UserName, FieldStorage.Yes); Store(x =&gt; x.DateConnected, FieldStorage.Yes); Store(x =&gt; x.UserId, FieldStorage.Yes); } public class IndexResult { public string ServerName { get; set; } public string UserName { get; set; } public DateTimeOffset DateConnected { get; set; } public string UserId { get; set; } } } </code></pre> <p>The reason for storing the results from the Map is because if we don&rsquo;t, we don&rsquo;t actually get any results back. (will show you soon)</p> <h2>Querying</h2> <p>So querying is the same as always, only we need to provide the &lsquo;AsProjection<T>&rsquo; to the query, like so:</p> <pre><code>var results = session.Query&lt;GameServers_ConnectedUsers.IndexResult, GameServers_ConnectedUsers&gt;() .Where(x =&gt; x.UserName.StartsWith("b")) .AsProjection&lt;GameServers_ConnectedUsers.IndexResult&gt;() .ToList(); </code></pre> <p>The Projection just needs to be an object that matches the result, otherwise it will attempt to return the original documents.</p> <p>If we run the query without the <code>AsProjection&lt;T&gt;</code> we end up with an exception because the result (the original document) doesn&rsquo;t match the object we were querying against <code>IndexResult</code></p> <p><img src="/images/ravendb-flattern-1.png" alt="" /></p> <p>If we set the <code>AsProjection</code> to <code>dynamic</code>, or <code>GameServer</code>, we get the original documents. BUT the funny thing is if you use <code>GameServer</code> you end up with as many results as the projection has. In this case 3.</p> <p><img src="/images/ravendb-flattern-2.png" alt="" /></p> <p>If we expand them out, we see we actually get a duplicate.</p> <p><img src="/images/ravendb-flattern-3.png" alt="" /></p> <p>But if we use <code>dynamic</code> we get unique documents:</p> <p><img src="/images/ravendb-flattern-4.png" alt="" /></p> <p>Using the <code>IndexResult</code> (or an object that matches the projection) we get the projected results that we wanted at the start of this post:</p> <p><img src="/images/ravendb-flattern-5.png" alt="" /></p> <p>Three results, and all the correct data:</p> <p><img src="/images/ravendb-flattern-6.png" alt="" /></p> <h2>Storing the results</h2> <p>I showed in the index that I was storing the results I wanted in the projection. This is because if we don&rsquo;t, we end up with this:</p> <p><img src="/images/ravendb-flattern-7.png" alt="" /></p> <p>Not only do we end up with the incorrect number of results, they are missing data that isn&rsquo;t found in the original document.</p> <p>You can see <code>GameServer</code> is there, that&rsquo;s because it&rsquo;s found on the document. We need to <code>store</code> the data so that RavenDB can return it, that means we use more disk space, but without it, RavenDB would have to query and assume the data that you wanted to return. By storing it RavenDB just returns what matches the query, and doesn&rsquo;t do any extra work.</p> <p>So if you want to return the projected results, then you need to Store them.</p> <p>I&rsquo;ve put a gist here for anyone interested.</p> <p><a href="https://gist.github.com/1972646">https://gist.github.com/1972646</a></p> Service Stack... I heart you. My conversion from WCF to SS 2012-02-21T00:00:00-08:00 http://www.philliphaydon.com/2012/02/service-stack-i-heart-you-my-conversion-from-wcf-to-ss/ <p>I&rsquo;ve just spent the weekend ripping out that dreaded WCF abomination and replacing it with Service Stack.</p> <p><a href="http://servicestack.net/">http://servicestack.net/</a></p> <blockquote><p>A modern fresh alternative to WCF. Code-first, convention-based, codegen-free. Encourages best-practices high-performance, scalable REST &amp; RPC web services.</p></blockquote> <p>Over the past couple of months I&rsquo;ve been fighting with WCF to the point I wanted to slit my wrists.</p> <p>So I asked <a href="http://jabbr.net/">JabbR</a> and Twitter if I should use Web API. Well -no- one recommended Web API and everyone recommended Service Stack.</p> <h2>It&rsquo;s a different way of thinking</h2> <p>The first noticeable difference between WCF and SS (Service Stack) is that I&rsquo;m no longer writing a single service class with a butt load of methods. Which is most likely a good thing because after a while they just become hard to manage.</p> <p>So instead of a Contract, Service, Response DTO, and Request DTO, with 9234823 methods defined in the Contract/Service. It&rsquo;s now <strong>1 Request DTO per Service.</strong></p> <p>What does that mean?</p> <!--excerpt--> <p>Well before I would have something like:</p> <pre><code>[ServiceContract] public interface IMemberQueryService { [OperationContract] MemberResponse ById(string id); [OperationContract] MemberResponse ByEmail(string email); [OperationContract] MemberResponse ByOpenId(string openId); } </code></pre> <p>Obviously with the actual service implementation and all that jazz.</p> <h2>Implementation with Service Stack</h2> <p>Now with Service Stack I would write that as a single service. This means I need a request class.</p> <pre><code>public class MemberRequest { public string Id { get; set; } public string OpenId { get; set; } public string Email { get; set; } } </code></pre> <p><span class="note"><strong>Note:</strong> My &lsquo;Id&rsquo; is a string because I&rsquo;m using RavenDB and this is an a real example</span></p> <p>The next class,the Service itself:</p> <pre><code>public class MemberService : IService&lt;MemberRequest&gt; { private IDocumentStore DocumentStore { get; set; } public MemberService(IDocumentStore documentStore) { DocumentStore = documentStore; } public object Execute(MemberRequest request) { } } </code></pre> <p>So now I have a Request and a Service. But the request is meant to handle what the WCF service with three methods was doing, so how is this implemented.</p> <p>Well rather than having three methods, I simply add the results to a collection and return the result.</p> <p>The full implementation of this service looks like so:</p> <pre><code>public class MemberService : IService&lt;MemberRequest&gt; { private IDocumentStore DocumentStore { get; set; } public MemberService(IDocumentStore documentStore) { DocumentStore = documentStore; } public object Execute(MemberRequest request) { var result = new List&lt;MemberResponse.Member&gt;(); using (var session = DocumentStore.OpenSession()) { if (!string.IsNullOrWhiteSpace(request.Id)) { var member = session.Load&lt;Member&gt;(request.Id); if (member != null) result.Add(member.TranslateTo&lt;MemberResponse.Member&gt;()); } if (!string.IsNullOrWhiteSpace(request.Email)) { var member = session.Query&lt;Member, All_Members&gt;() .SingleOrDefault(x =&gt; x.Email == request.Email); if (member != null) result.Add(member.TranslateTo&lt;MemberResponse.Member&gt;()); } if (!string.IsNullOrWhiteSpace(request.OpenId)) { var member = session.Query&lt;Member, All_Members&gt;() .SingleOrDefault(x =&gt; x.OpenId == request.OpenId); if (member != null &amp;&amp; member.OpenId.Equals(request.OpenId, StringComparison.Ordinal)) result.Add(member.TranslateTo&lt;MemberResponse.Member&gt;()); } } return new MemberResponse { Results = result }; } } </code></pre> <p>So if I have any of the information defined on the request object, I simply query for it.</p> <p>Now if you&rsquo;re looking at the method you&rsquo;re probably thinking the same thing I thought when I first looked at something similar. How the fark do I query that? <em>Well I&rsquo;ll explain that soon</em>. :)</p> <p>The last thing missing tho is the Response.</p> <p>There&rsquo;s a couple of things to note, in the code above I actually translate my Model to a DTO, this is done using the <code>TranslateTo&lt;T&gt;</code> method. This maps the object from 1 object to another, providing the two models share similar properties. This is exactly the same as AutoMapper except it doesn&rsquo;t handle relationships.</p> <p>It is possible to handle relationships however and I&rsquo;ll demonstrate that in future posts.</p> <p>Now one thing that annoyed me with WCF was getting null objects as a response. The approach used here is I have a MemberResponse which has a collection of Results.</p> <p>The actual DTO looks like so:</p> <pre><code>public class MemberResponse : IHasResponseStatus { public IEnumerable&lt;Member&gt; Results { get; set; } public class Member { public string Id { get; set; } public string OpenId { get; set; } public string DisplayName { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Email { get; set; } } public ResponseStatus ResponseStatus { get; set; } } </code></pre> <p><span class="note"><strong>Note:</strong> I like to use nested classes for the results because I can name it what it is, and modify it without breaking any other Response classes I make in the future.</span></p> <p>The response implements the interface <code>IHasResponseStatus</code> (which I think needs to be renamed to ICanHazResponseStatus) which provides the property ResponseStatus, this allows SS to attach it&rsquo;s own information about the response such as exception information.</p> <p>So rather than WCF where it just faults and throws exceptions and falls over and starts a fire, it just returns a response and gives you the information about it. AWESOME!</p> <p>Also I&rsquo;ve added the Member as a collection so that I can have multiple results if I need, maybe I want to find a user who has an OpenId of &lsquo;xyz&rsquo; and an email of &lsquo;abc&rsquo; so I can link them. No need to write yet ANOTHER WCF method.</p> <h2>Configuration</h2> <p>Configuration in WCF is always a pain in the ass, specially when dealing with message sizes, buffers, bindings and endpoints, so on and so forth somebody shoot me because WCF configuration is the bane of my existence.</p> <p>Configuring SS is so easy that I over configured it to begin with. While configuring SS I realised I can remove Autofac, AutoMapper and a bunch of configuration code. The end result was the following:</p> <pre><code>public class Global : System.Web.HttpApplication { public class QueryServiceAppHost : AppHostBase { private readonly IContainerAdapter _containerAdapter; public QueryServiceAppHost(IDocumentStore documentStore) : base("ITCompiler Query Services", typeof(MemberService).Assembly) { base.Container.Register&lt;IDocumentStore&gt;(documentStore); base.SetConfig(new EndpointHostConfig { DebugMode = true }); } public override void Configure(Funq.Container container) { container.Adapter = _containerAdapter; } } private static IDocumentStore DocumentStore { get; set; } public void Application_Start() { DocumentStore = ConfigureRavenDb(); (new QueryServiceAppHost(DocumentStore)).Init(); } private static IDocumentStore ConfigureRavenDb() { var documentStore = new DocumentStore { ConnectionStringName = "RavenDB", DefaultDatabase = "ITCompiler" }.Initialize(); IndexCreation.CreateIndexes(typeof(All_Members).Assembly, documentStore); return documentStore; } } </code></pre> <p>I would show you the original configuration I had for WCF but you would probably freak out and run.</p> <p>But I&rsquo;ve cut out Autofac, AutoMapper, and it&rsquo;s really just &lsquo;Configure RavenDB&rsquo; and &lsquo;Initialize SS&rsquo;</p> <p>I didn&rsquo;t touch the .config file, didn&rsquo;t do anything special to setup SS, simply created a AppHost class and registered my Document Store.</p> <h2>Querying the Services</h2> <p>The last piece to the puzzle was querying the newly written services. Usually with WCF I configure the ChannelFactory and then inject a new Channel for every controller that needs specific services.</p> <p>This caused a lot of configuration since each configured service has it&rsquo;s own endpoint I ended up with a lot of code.</p> <p>SS creates a reusable client for querying, and all it needs is the base URL of the service host.</p> <p>I first started just by creating a new client like so:</p> <pre><code>var client = new JsonServiceClient("http://localhost:9001"); </code></pre> <p><span class="note"><strong>Note:</strong> I use the JSON service client but there&rsquo;s a few to choose from, XML, JSV, WCF, SOAP, etc.</span></p> <p>Now when calling the client I can specify the response and pass in a request, so lets say I wanted to get a use by email address:</p> <pre><code>client.Send&lt;MemberResponse&gt;(new MemberRequest { Email = "bob@googlelymail.com" }); </code></pre> <p>This sends a request, and works out which service to invoke, passes in the request, and returns the result.</p> <p>It couldn&rsquo;t be easier. If I wanted to find a user by Id, just pass a request with just the Id.</p> <p>Now I setup my application with two different projects, one for Queries, and one for Commands. So when I setup my client I just created two really simple classes:</p> <pre><code>public class QueryServiceClient : JsonServiceClient { public QueryServiceClient(string url) : base(url) { } } </code></pre> <p>And another for Commands named CommandServiceClient.</p> <p>Then I registered them in Autofac (on the MVC site I&rsquo;m still using Autofac)</p> <pre><code>builder.RegisterType&lt;QueryServiceClient&gt;() .WithParameter(new NamedParameter("url", QueryServicesUrl)) .AsSelf() .SingleInstance(); builder.RegisterType&lt;CommandServiceClient&gt;() .WithParameter(new NamedParameter("url", CommandServicesUrl)) .AsSelf() .SingleInstance(); </code></pre> <p>Now I can just inject those two service clients and reuse them over and over.</p> <h2>Conclusion</h2> <p>I had to change my way of thinking and to be honest, I threw in the towel pretty early on. But I stuck with it. I was lucky enough to have help from the creator himself, <a href="http://www.twitter.com/demisbellot">@demisbellot</a> in the <a href="http://jabbr.net/#/rooms/servicestack">JabbR ServiceSack</a> room.</p> <p>He was kind enough to answer all my woes and put me on the right path, regardless of how silly my questions probably were.</p> <p>After a little perseverance I&rsquo;m now completely in love with Service Stack and I look forward to learning more of it&rsquo;s capabilities around Error Handling, REST, and Messaging.</p> MVC 4 Project Templates are stupid 2012-02-19T00:00:00-08:00 http://www.philliphaydon.com/2012/02/mvc-4-project-templates-are-stupid/ <p><em>begin rant</em></p> <p>Thought I would jump on the MVC 4 Beta bandwagon today, installed, create new project&hellip; And this is what I&rsquo;m greeted with:</p> <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;packages&gt; &lt;package id="AspNetMvc" version="4.0.20126.16343" /&gt; &lt;package id="AspNetRazor.Core" version="2.0.20126.16343" /&gt; &lt;package id="AspNetWebApi" version="4.0.20126.16343" /&gt; &lt;package id="AspNetWebApi.Core" version="4.0.20126.16343" /&gt; &lt;package id="AspNetWebPages.Core" version="2.0.20126.16343" /&gt; &lt;package id="EntityFramework" version="4.1.10331.0" /&gt; &lt;package id="jQuery" version="1.6.2" /&gt; &lt;package id="jQuery.Ajax.Unobtrusive" version="2.0.20126.16343" /&gt; &lt;package id="jQuery.UI.Combined" version="1.8.11" /&gt; &lt;package id="jQuery.Validation" version="1.8.1" /&gt; &lt;package id="jQuery.Validation.Unobtrusive" version="2.0.20126.16343" /&gt; &lt;package id="knockoutjs" version="2.0.0.0" /&gt; &lt;package id="Microsoft.Web.Infrastructure" version="1.0.0.0" /&gt; &lt;package id="Microsoft.Web.Optimization" version="1.0.0-beta" /&gt; &lt;package id="Modernizr" version="2.0.6" /&gt; &lt;package id="System.Json" version="4.0.20126.16343" /&gt; &lt;package id="System.Net.Http" version="2.0.20126.16343" /&gt; &lt;package id="System.Net.Http.Formatting" version="4.0.20126.16343" /&gt; &lt;package id="System.Web.Http.Common" version="4.0.20126.16343" /&gt; &lt;package id="System.Web.Providers" version="1.1" /&gt; &lt;package id="System.Web.Providers.Core" version="1.0" /&gt; &lt;/packages&gt; </code></pre> <p>This is absolutely stupid&hellip;</p> <p>I select EMPTY project template.</p> <p>EMPTY</p> <!--excerpt--> <p>So I removed the things I don&rsquo;t need to begin with:</p> <pre><code>&lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;packages&gt; &lt;package id="AspNetMvc" version="4.0.20126.16343" /&gt; &lt;package id="AspNetRazor.Core" version="2.0.20126.16343" /&gt; &lt;package id="AspNetWebApi" version="4.0.20126.16343" /&gt; &lt;package id="AspNetWebApi.Core" version="4.0.20126.16343" /&gt; &lt;package id="AspNetWebPages.Core" version="2.0.20126.16343" /&gt; &lt;package id="Microsoft.Web.Infrastructure" version="1.0.0.0" /&gt; &lt;package id="Microsoft.Web.Optimization" version="1.0.0-beta" /&gt; &lt;package id="System.Json" version="4.0.20126.16343" /&gt; &lt;package id="System.Net.Http" version="2.0.20126.16343" /&gt; &lt;package id="System.Net.Http.Formatting" version="4.0.20126.16343" /&gt; &lt;package id="System.Web.Http.Common" version="4.0.20126.16343" /&gt; &lt;package id="System.Web.Providers" version="1.1" /&gt; &lt;package id="System.Web.Providers.Core" version="1.0" /&gt; &lt;/packages&gt; </code></pre> <p>But beyond that I don&rsquo;t know if the rest can be removed or if it&rsquo;s required by MVC 4. Time for some trial and error :)</p> <p>I really hope MS decide to create a REAL empty project.</p> RavenDB - Searching across multiple properties 2012-01-18T00:00:00-08:00 http://www.philliphaydon.com/2012/01/ravendb-searching-across-multiple-properties/ <p>Ayende recently posted about <a href="http://ayende.com/blog/152833/orders-search-in-ravendb">Orders Search</a> in RavenDB which got me a little bit excited, since I was pondering how I would do searching in RavenDB without having Full Text Searching from SQL Server.</p> <p>So digging into it I wanted to try it out for myself how to use it. Given the model:</p> <pre><code>public class Post { public int Id { get; set; } public string Title { get; set; } public string Description { get; set; } public IEnumerable&lt;string&gt; Tags { get; set; } public DateTime DatePosted { get; set; } } </code></pre> <p>I&rsquo;ve setup 10 posts (<a href="http://pastie.org/3200462">click here for the insert pastie</a>) just with some really basic data.</p> <p>So I&rsquo;m going to detail here all the data that I&rsquo;ve setup.</p> <!--excerpt--> <h2>Tags</h2> <table border="0" cellspacing="0" cellpadding="2" width="400"> <tbody> <tr> <td valign="top" width="200"><strong>Tag Name</strong></td> <td valign="top" width="200"><strong># of Posts Containing Tag</strong></td> </tr> <tr> <td valign="top" width="200">html</td> <td valign="top" width="200">3</td> </tr> <tr> <td valign="top" width="200">c#</td> <td valign="top" width="200">6</td> </tr> <tr> <td valign="top" width="200">ravendb</td> <td valign="top" width="200">4</td> </tr> <tr> <td valign="top" width="200">nhibernate</td> <td valign="top" width="200">3</td> </tr> <tr> <td valign="top" width="200">javascript</td> <td valign="top" width="200">1</td> </tr> <tr> <td valign="top" width="200">coffeescript</td> <td valign="top" width="200">2</td> </tr> <tr> <td valign="top" width="200">less</td> <td valign="top" width="200">3</td> </tr> <tr> <td valign="top" width="200">search</td> <td valign="top" width="200">6</td> </tr> <tr> <td valign="top" width="200">closures</td> <td valign="top" width="200">1</td> </tr> <tr> <td valign="top" width="200">jquery</td> <td valign="top" width="200">2</td> </tr> <tr> <td valign="top" width="200">css</td> <td valign="top" width="200">1</td> </tr> <tr> <td valign="top" width="200">queryover</td> <td valign="top" width="200">2</td> </tr> <tr> <td valign="top" width="200">mapreduce</td> <td valign="top" width="200">4</td> </tr> </tbody> </table> <h2>Titles</h2> <p>Nothing interesting, just &lsquo;Test Post X&rsquo; for each one to identify them.</p> <h2>Description</h2> <p>Basically for this testing I&rsquo;ve taken the blog post names of a few things from Google Reader, that some-way relate to the tags above. Take a look at the script mentioned above to see the data.</p> <h2>Creating the Index</h2> <p>So the first thing I want to do is create a Map with a Reduce Result, but we aren&rsquo;t going to add the Reduce to the index, since we don&rsquo;t need it to store that data or do anything with it. We purely want the Reduce Result that matches the map, so that we can query against it.</p> <pre><code>public class Post_Search : AbstractIndexCreationTask&lt;Post, Post_Search.ReduceResult&gt; { public class ReduceResult { public object[] SearchQuery { get; set; } public DateTime DatePosted { get; set; } } public Post_Search() { Map = posts =&gt; from post in posts select new { SearchQuery = post.Tags.Concat(new[] { post.Description, post.Title }), DatePosted = post.DatePosted }; } } </code></pre> <p>This index is a little bit funky, and differs from what Ayende showed in his example. I wanted to try something a little different.</p> <p>In my scenario I have a collection of Tag&rsquo;s that I wanted to include in the search, this the tags is already a collection, I concatenate the additional array of items I want to add into the map.</p> <p>The SearchQuery is the property that we will search against, while the DatePosted wont be included in the Search, but is there to provide additional filtering on my search.</p> <h2>Querying</h2> <p>Querying threw me off at first, because in order to query against this index, we have to specify the ReduceResult class.</p> <p>So we end up with the starting of our query looking like this:</p> <pre><code>var result = session.Query&lt;Post_Search.ReduceResult, Post_Search&gt;() </code></pre> <p>At first I thought &ldquo;oh, that means we end up with a ReduceResult result type, this is pointless and useless&rdquo;. But I commented on Ayende&rsquo;s blog post and it turns out we can call &lsquo;As<T>&rsquo; on the query.</p> <p>Without filtering the results just yet, our query would look like the following:</p> <pre><code>var result = session.Query&lt;Post_Search.ReduceResult, Post_Search&gt;() .As&lt;Post&gt;() .ToList(); </code></pre> <p>So if I run this up now, for a quick test, I should get 10 results back of type Post</p> <p><img src="/images/ravendb-searching-1.png" /></p> <p>Great!</p> <p>So now I need to begin filtering out the results. To begin with I&rsquo;m doing to use the .Where extension. Since we are looking an object array, we can&rsquo;t directly compare it to a string, but if we explicitly cast it to an object we can look for:</p> <p>coffeescript expecting 2 results:</p> <pre><code>var result = session.Query&lt;Post_Search.ReduceResult, Post_Search&gt;() .Where(x =&gt; x.SearchQuery == (object)"coffeescript") .As&lt;Post&gt;() .ToList(); </code></pre> <p><img src="/images/ravendb-searching-2.png" /></p> <p>How about javascript expecting 2 (1 via Tag and 1 via the Description)</p> <p><img src="/images/ravendb-searching-3.png" /></p> <p>Oh, we didn&rsquo;t get the desired result&hellip; This is because the search is only doing a search on an exact match. Since the search value is an exact match of the tag, the result is returned.</p> <p>So to fix this we need to make the index analysed. Adding to the index:</p> <pre><code>Index(x =&gt; x.SearchQuery, FieldIndexing.Analyzed); </code></pre> <p>If we run the exact same query again:</p> <p><img src="/images/ravendb-searching-4.png" /></p> <p>Now we get 2 results.</p> <p>Now to try something a little bit different, using &lsquo;Search&rsquo;, if we wanted to search for something like mvc which happens to only be in the description, rather than using &lsquo;Where&rsquo; like shown above, we can use &lsquo;Search&rsquo; like so:</p> <pre><code>var result = session.Query&lt;Post_Search.ReduceResult, Post_Search&gt;() .Search(x =&gt; x.SearchQuery, "mvc") .As&lt;Post&gt;() .ToList(); </code></pre> <p>This will give us the same result, except it looks much cleaner</p> <p><img src="/images/ravendb-searching-5.png" /></p> <p>Now there&rsquo;s 1 catch I&rsquo;ve found with this, which is searching is always an exact match. I&rsquo;m not sure (no research done into lucene yet) if lucene has the ability to do a wild-card type search similar to SQL like: &lsquo;%mvc%&rsquo;, but you can get suggestions from this.</p> <p>For example if I search for &lsquo;coffee&rsquo; rather than &lsquo;coffeescript&rsquo; I would expect all documents containing &lsquo;coffee&rsquo; to be returned. This doesn&rsquo;t happen. It does give you suggestions though.</p> <p>Looking at the management studio for &lsquo;coffee&rsquo; :</p> <p><img src="/images/ravendb-searching-6.png" /></p> <p><em>Side Comment: I think it would be cool if RavenDB provided the ability to have say include suggestions, like:</em></p> <pre><code>var result = session.Query&lt;Post_Search.ReduceResult, Post_Search&gt;() .Search(x =&gt; x.SearchQuery, "coffee") .IncludeAllSuggestions() .As&lt;Post&gt;() .ToList(); </code></pre> <p>Or other variations such as:</p> <ul> <li>.Suggestions.IncludeAll()</li> <li>.Suggestions.IncludeTop(3)</li> <li>.Suggestions.IncludeAll(WhenResults.AreEmpty)</li> <li>.Suggestions.IncludeAll(WhenResults.AreLessThan, 10)</li> </ul> <p>Hopefully you can work out where I&rsquo;m going with this?</p> <p>Ok continuing on. Why do we need to call &lsquo;As<T>()&rsquo; on the query?</p> <p>Well from my understanding of how RavenDB works is like this, when we create an index, it&rsquo;s creating a sub-set of data that points to the document in RavenDB.</p> <p>For example I have all those documents inserted (<a href="http://pastie.org/3200462">link for the lazy</a>), and these are all stored like so:</p> <p><img src="/images/ravendb-searching-7.png" /></p> <p>When we created the index with the following Map:</p> <pre><code>Map = posts =&gt; from post in posts select new { SearchQuery = post.Tags.Concat(new[] { post.Description, post.Title }), DatePosted = post.DatePosted }; </code></pre> <p>It basically created an index that looks like this, for the data above:</p> <table> <tbody> <tr> <td valign="top" rowspan="2" width="50">posts/2</td> <td valign="top" width="540">SearchQuery: ["c#", "nhibernate", "search", "queryover", "Benjamin Day slides us into "How to be a C# ninja in 10 easy steps"", "Test Post 2"</td> </tr> <tr> <td valign="top">DatePosted: "2012-01-02T00:00:00.0000000"</td> </tr> </tbody> </table> <p>So the index actually points directly to a Document in RavenDB, when we search against the index, if a match is found, the index returns the Id &lsquo;posts/2&rsquo; back, and that knows to go to the posts collection and grab the document with Id 2.</p> <p>The problem with the query is we need to specify an object to query against.</p> <p>So we introduced the ReduceResult <em>(not sure on this naming but I took it from Ayende&rsquo;s blog)</em>, this allows us to specify the Properties we defined in our index, as search criteria, but now our query is expecting ReduceResult:</p> <p><img src="/images/ravendb-searching-8.png" /></p> <p>By specifying as we are telling the query that our result is going to be a type of &lsquo;Post&rsquo;:</p> <p><img src="/images/ravendb-searching-9.png" /></p> <h2>Conclusion</h2> <p>This functionality is really cool, it allows us to easily search against multiple different properties without having to create messy conjunctions in our LINQ. If we were to attempt to do this without an index, we would probably end up writing something like:</p> <pre><code>var result = session.Query&lt;Post&gt;() .Where(x =&gt; x.Description.Contains("c#") || x.Tags.Any(y =&gt; y == "c#") || x.Title.Contains("c#") ) .ToList(); </code></pre> <p>And really, that&rsquo;s just nasty&hellip; Specially considering we get the same results for writing more readable code:</p> <p><img src="/images/ravendb-searching-10.png" /></p> RavenDB - Map Reduce 2011-12-22T00:00:00-08:00 http://www.philliphaydon.com/2011/12/ravendb-map-reduce/ <p>So, learning Map Reduce in RavenDB I decided that to take what I learnt from the index created in my previous post. I think I picked something rather difficult to begin with, but I&rsquo;ve succeeded</p> <p>Given a document Article which has a collection of Tags.</p> <p>I want to get a Count of each Tag across all Articles.</p> <pre><code>public class Content { public int Id { get; set; } public string Title { get; set; } public IEnumerable&lt;Tag&gt; Tags { get; set; } } public class Tag { public string Name { get; set; } } </code></pre> <p><span class="note"><strong>Note:</strong> Tag is it&rsquo;s own class because I added additional properties to it.</span></p> <!--excerpt--> <p>Now I insert some data:</p> <pre><code>using (var session = documentStore.OpenSession()) { session.Store(new Content { Title = "Test Title for a Video", Tags = new List&lt;Tag&gt; { new Tag() {Name = "c#"}, new Tag() {Name = "autofac"}, new Tag() {Name = "asp.net"}, } }); session.Store(new Content { Title = "Test Title for an Article", Tags = new List&lt;Tag&gt; { new Tag() {Name = "c#"}, new Tag() {Name = "nhibernate"}, new Tag() {Name = "fluent-nhibernate"}, new Tag() {Name = "mvc"} } }); session.Store(new Content { Title = "Test Title for an Article", Tags = new List&lt;Tag&gt; { new Tag() {Name = "ravendb"}, new Tag() {Name = "asp.net"}, new Tag() {Name = "autofac"}, new Tag() {Name = "c#"} } }); session.SaveChanges(); } </code></pre> <p>So I&rsquo;m expecting a count of:</p> <ul> <li>3 x c#</li> <li>2 x autofac</li> <li>2 x asp.net</li> <li>1 x ravendb</li> <li>1 x mvc</li> <li>1 x nhibernate</li> <li>1 x fluent-nhibernate</li> </ul> <p>I&rsquo;m going to pull these out with a defined type rather than dynamic/object, so I&rsquo;ve created a new class with Count and Name:</p> <pre><code>public class TagResult { public int Count { get; set; } public string Name { get; set; } } </code></pre> <p>So creating a new Index:</p> <pre><code>public class All_Tags : AbstractMultiMapIndexCreationTask&lt;TagResult&gt; { public All_Tags() { } } </code></pre> <p>The first thing I need to do is map out ONLY the Tag&rsquo;s, when I select out the Tag&rsquo;s, I&rsquo;m also going to include another field called Count, with a default value of 1. This is so I can re-use it to sum the total number of times the tag is used.</p> <pre><code>AddMap&lt;Content&gt;(contents =&gt; from content in contents from tag in content.Tags select new { Name = tag.Name, Count = 1 }); </code></pre> <p>This would give me a result that contains duplicates for the tags. Along the lines of:</p> <table> <tr> <td>c#</td> <td>1</td> </tr> <tr> <td>c#</td> <td>1</td> </tr> <tr> <td>c#</td> <td>1</td> </tr> <tr> <td>autofac</td> <td>1</td> </tr> <tr> <td>autofac</td> <td>1</td> </tr> <tr> <td>asp.net</td> <td>1</td> </tr> <tr> <td>asp.net</td> <td>1</td> </tr> <tr> <td>ravendb</td> <td>1</td> </tr> <tr> <td>mvc</td> <td>1</td> </tr> <tr> <td>nhibernate</td> <td>1</td> </tr> <tr> <td>fluent-nhibernate</td> <td>1</td> </tr> </table> <p>So what I need to do in the Reduce, is group the tags together by their Name.</p> <pre><code>Reduce = results =&gt; from result in results group result by result.Name into tag select new { Count = tag.Sum(x =&gt; x.Count), Name = tag.Key, }; </code></pre> <p>So here, I group all the tags together by their name, but I also sum the &lsquo;count&rsquo; value together to get the total number of times the tag is used.</p> <p>Now run up the app and view the index:</p> <p><img src="/images/ravendb-map-reduce-1.png" alt="" /></p> <p>Now if I query the index:</p> <p><img src="/images/ravendb-map-reduce-2.png" alt="" /></p> <p>Awesome. Now to query this, I have to use the TagResult class defined previously, and the All_Tags index just created.</p> <pre><code>using (var session = documentStore.OpenSession()) { var result = session.Query&lt;TagResult, All_Tags&gt;() .ToList(); foreach (var tag in result) { Console.WriteLine(tag.Count + " x " + tag.Name); } session.SaveChanges(); } </code></pre> <p>Running this I get the following result:</p> <p><img src="/images/ravendb-map-reduce-3.png" alt="" /></p> <p>The results I expected previously.</p> <p>So there you have it. Map Reduce.</p> RavenDB Inheritance-Revisited 2011-12-14T00:00:00-08:00 http://www.philliphaydon.com/2011/12/ravendb-inheritance-revisited/ <p>So after my initial post on <a href="/2011/12/ravendb-inheritance/">RavenDB Inheritance</a>, and the issue I had with polymorphic queries, and seeking help from the guys in <a href="http://jabbr.net/">JabbR</a> and the (RavenDB Google Group)[http://groups.google.com/group/ravendb/browse_thread/thread/c71df8f1cd92e04c], <a href="http://ayende.com/blog/">Ayende</a> ended up doing a screen cast with me where he solved all my problems.</p> <p>One of the things he asked me was what I was trying to achieve by having a polymorphic query, which was a very good question, something I hadn&rsquo;t really thought about.</p> <p>The problem I was trying to solve was actually displaying search results.</p> <h2>The Problem</h2> <p>So I&rsquo;m working on a personal project, and I need to display a few things which are similar, but different. There&rsquo;s 3 different types but I&rsquo;ll use two to keep it simple. I&rsquo;ve also cut out most of the properties.</p> <p>So I have an abstract class Content, with two derived classes, Article and Video.</p> <pre><code>public abstract class Content { public int Id { get; set; } public string Title { get; set; } public DateTime DatePublished { get; set; } } public class Article : Content { public string HtmlContent { get; set; } } public class Video : Content { public string Description { get; set; } public string VideoUrl { get; set; } } </code></pre> <!--excerpt--> <p>Then I initialize the DocumentStore and store a couple of documents.</p> <pre><code>var documentStore = (new DocumentStore() { Url = "http://localhost:8080" }).Initialize(); using (var session = documentStore.OpenSession()) { session.Store(new Video { DatePublished = DateTime.Now, Description = "Test Description for a Video", Title = "Test Title for a Video", VideoUrl = "http://www.youtube.com/watch?v=PGz9GokDkkg" }); session.Store(new Article { DatePublished = DateTime.Now, Title = "Test Title for an Article", HtmlContent = "Some content for the article..." }); session.SaveChanges(); } </code></pre> <p>This time I&rsquo;m not using the Convention to store the two documents as &lsquo;Content&rsquo;, rather I&rsquo;m allowing it to store them as what they are. This gives me a result in Raven like:</p> <p><img src="/images/ravendb-inheritance-revisited-1.png" alt="" /></p> <p>Now if I query for Video:</p> <pre><code>using (var session = documentStore.OpenSession()) { var result = session.Query&lt;Video&gt;().ToList(); foreach (var content in result) { Console.WriteLine(content.Id); Console.WriteLine(content.Title); } } </code></pre> <p>I get the output of the first Document.</p> <p><img src="/images/ravendb-inheritance-revisited-2.png" alt="" /></p> <p>Likewise if I select &lsquo;Article&rsquo; I get the Article document that I previously stored.</p> <p>So how do I get a list of Content?</p> <h2>The Solution</h2> <p>So, the solution is really, really easy, it&rsquo;s an index.</p> <p>The first thing Ayende showed me was creating the index in RavenDB Management Studio, then he showed me doing it in code. I&rsquo;m just going to show it done in code.</p> <p>I created a class called &lsquo;All_Content&rsquo; (with an underscore) like so:</p> <pre><code>public class All_Content : AbstractMultiMapIndexCreationTask { public All_Content() { AddMap&lt;Article&gt;(articles =&gt; from article in articles select new { article.Id, article.Title, article.DatePublished }); AddMap&lt;Video&gt;(videos =&gt; from video in videos select new { video.Id, video.Title, video.DatePublished }); } } </code></pre> <p><em>It reminds me of writing a Union View in SQL Server in some ways.</em> It basically maps to the Articles and Videos, but only selects the things I need. Those of which would actually be displayed to the screen or that are common between the two document types.</p> <p>Then I create the index right after I initialize the DocumentStore:</p> <pre><code>IndexCreation.CreateIndexes(typeof(All_Content).Assembly, documentStore); </code></pre> <p>This creates the index in RavenDB for me.</p> <p><img src="/images/ravendb-inheritance-revisited-3.png" alt="" /></p> <p>As you can see, even tho I specified the class index with an underscore, it converts it to All/Content, that&rsquo;s a really nice way of presenting it. I think it will go well for being able to create descriptive indexes in the future.</p> <p>And the index itself:</p> <p><img src="/images/ravendb-inheritance-revisited-4.png" alt="" /></p> <p>Now I need to actually query against the index. That&rsquo;s also really really easy. When I specify the type, I can specify the index with it:</p> <pre><code>using (var session = documentStore.OpenSession()) { var result = session.Query&lt;Content, All_Content&gt;().ToList(); foreach (var content in result) { Console.WriteLine(content.Id); Console.WriteLine(content.Title); } } </code></pre> <p>Now when I run this I get the output:</p> <p><img src="/images/ravendb-inheritance-revisited-5.png" alt="" /></p> <p>Awesome!</p> <p>The really interesting thing I found is that if I look at what&rsquo;s returned:</p> <p><img src="/images/ravendb-inheritance-revisited-6.png" alt="" /></p> <p>Are the correct CLR types that I originally defined. So I haven&rsquo;t lost all the additional fields by not defining them. I&rsquo;m still learning but for now I assume it allows those fields to be searchable.</p> <h2>Extras</h2> <p>One of the additional things Ayende showed me was that you can include other documents that don&rsquo;t inherit from the base type. You can include those in the index map, and then rather than returning a concrete type, you can specify object, or dynamic.</p> <pre><code>var result = session.Query&lt;dynamic, All_Content&gt;().ToList(); </code></pre> <p>RavenDB is really powerful. It&rsquo;s truly amazing, and so much nicer to work with in .NET than other document databases like MongoDB.</p> RavenDB Inheritance 2011-12-10T00:00:00-08:00 http://www.philliphaydon.com/2011/12/ravendb-inheritance/ <p><span class="note"><strong>Note:</strong> Updated solution: <a href="http://www.philliphaydon.com/2011/12/ravendb-inheritance-revisited/">http://www.philliphaydon.com/2011/12/ravendb-inheritance-revisited/</a></span></p> <p>Continuing my learning of RavenDB, I wanted to see how it handled Inheritance.</p> <p>I found: <a href="http://ravendb.net/faq/polymorphic-indexes">http://ravendb.net/faq/polymorphic-indexes</a></p> <p>Which showed what to do allow you to select over all types of <code>Animal</code> for the example shown. So I wanted to see what happens before and after using this method.</p> <p>So like the example shown I&rsquo;ve created an <code>Animal</code>, with a <code>Dog</code> and <code>Cat</code>.</p> <pre><code>public abstract class Animal { public int Id { get; set; } public string Name { get; set; } } public class Dog : Animal { } public class Cat : Animal { } </code></pre> <p>Now if I insert a Dog and Cat:</p> <pre><code>using (var session = documentStore.OpenSession()) { session.Store(new Dog() { Name = "Test Dog" }); session.Store(new Cat() { Name = "Test Cat" }); session.SaveChanges(); } </code></pre> <!--excerpt--> <p>What&rsquo;s stored in RavenDB is two separate documents, one for &lsquo;dogs&rsquo; and one for &lsquo;cats&rsquo;.</p> <p><img src="/images/ravendb-inheritance-revisited-1.png" alt="" /></p> <p>If I include the Convention.</p> <pre><code>var documentConvention = new DocumentConvention() { FindTypeTagName = type =&gt; { if (typeof (Animal).IsAssignableFrom(type)) return "animals"; return DocumentConvention.DefaultTypeTagName(type); } }; </code></pre> <p><span class="note"><strong>Note:</strong> You can do the conversion when the DocumentStore is initialized, I broke the two up so that it would fit easier into my blog. Otherwise it&rsquo;s too nested and yucky.</span></p> <pre><code>var documentStore = (new DocumentStore() { Url = "http://localhost:8080", Conventions = documentConvention }).Initialize(); </code></pre> <p>Now when I insert a Dog and Cat I get:</p> <p><img src="/images/ravendb-inheritance-revisited-2.png" alt="" /></p> <p>Awesome. If we look at the document however:</p> <p><img src="/images/ravendb-inheritance-revisited-3.png" alt="" /></p> <p>There is no information about it being a cat or dog, I thought it would add some sort of discriminator similar to how NHibernate works.</p> <p>However, if we look at the Metadata tab:</p> <p><img src="/images/ravendb-inheritance-revisited-4.png" alt="" /></p> <p>We can see the CLR type is stored in the metadata so RavenDB knows what type to create when we query it.</p> <p>This means if we query for <code>Animal</code> we get a list of Dogs and Cats.</p> <pre><code>using (var session = documentStore.OpenSession()) { var result = session.Query&lt;Animal&gt;(); foreach (var animal in result) { Console.WriteLine(animal.Name); } } </code></pre> <p><img src="/images/ravendb-inheritance-revisited-5.png" alt="" /></p> <p>However, if you wanted to query for just Dogs, like so:</p> <pre><code>var result = session.Query&lt;Dog&gt;().ToList(); </code></pre> <p>It doesn&rsquo;t seem to work :(</p> <p><img src="/images/ravendb-inheritance-revisited-6.png" alt="" /></p> <p>I&rsquo;m probably just doing something wrong, either way, the more I play with RavenDB. The more I love it.</p> Post a collection of ViewModel's to a MVC Action with jQuery 2011-12-07T00:00:00-08:00 http://www.philliphaydon.com/2011/12/post-a-collection-of-viewmodels-to-a-mvc-action-with-jquery/ <p>Maybe I searched for the wrong thing, but I couldn&rsquo;t find what I was looking for :( My Bing and Google fu failed me.</p> <p>Basically I wanted to post a collection of ViewModels to an MCV action. Turns out it&rsquo;s rather simple.</p> <p>Lets say I have a bunch of Products, and Products are managed in a WarehouseLocation. A product doesn&rsquo;t have a warehouse location, since it could exist in multiple locations.</p> <p>If I&rsquo;m currently working in Location A, I want to post a collection of Products to an action, as well as the WarehouseLocationId.</p> <p>So given a simple ViewModel, and an Action:</p> <pre><code>public class ProductViewModel { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } } </code></pre> <p>and</p> <!--excerpt--> <pre><code>public JsonResult Update(int warehouseLocationId, IEnumerable&lt;ProductViewModel&gt; products) { //Do something with the products... return Json(new {Staus = "success"}); } </code></pre> <p>I think usually when someone sends data from jQuery it&rsquo;s usually a single parameter,so the JSON would look something like:</p> <pre><code>var data = { id: 1,name: 'test name', price: 15.95 }; </code></pre> <p>This would populate an action that looked like:</p> <pre><code>public JsonResult Update(ProductViewModel product) </code></pre> <p>But what I was faced with was passing in two parameters, one of which is a collection&hellip;</p> <p>MVC seems to pair up the posted result with the parameter name, in the same way they it does for Route parameters. So to the JSON needs to look like:</p> <pre><code>var data = { warehouseLocationId: 12, products: [{ Id: 1, Name: "Product 1", Price: 15.95 }, { Id: 3, Name: "Product 2", Price: 12.50 }] }; </code></pre> <p>As you can see the key&rsquo;s on the first level match the parameter names, while the array on products, match the ViewModel.</p> <p>Taking this exact data and posting it to the action:</p> <pre><code>$.ajax({ type: 'POST', url: '@Url.Action("Update", "Home")', data: JSON.stringify(data), contentType: 'application/json', success: function(result) { //Do something with result... }, dataType: 'json' }); </code></pre> <p>I submit that, and with a breakpoint on my action I see:</p> <p><img src="/images/jquery-mvc-1.png" alt="" /></p> <p>^ The warehouseLocationId&hellip;</p> <p><img src="/images/jquery-mvc-2.png" alt="" /></p> <p>^ 2 products with the values:</p> <p><img src="/images/jquery-mvc-3.png" alt="" /></p> <p>And:</p> <p><img src="/images/jquery-mvc-4.png" alt="" /></p> <p>The exact same data we defined in our JavaScript.</p> <p>The really cool thing about this, is you can have nested collections also. Using the same scenario, but extending Product to have a collection of Categories like so:</p> <pre><code>public class ProductViewModel { public int Id { get; set; } public string Name { get; set; } public decimal Price { get; set; } public IEnumerable&lt;Category&gt; Categories { get; set; } } public class Category { public int Id { get; set; } public string Name { get; set; } } </code></pre> <p>I can update the JSON object to include Category information on 1 of the two products:</p> <pre><code>var data = { warehouseLocationId: 12, products: [{ Id: 1, Name: "Product 1", Price: 15.95 }, { Id: 3, Name: "Product 2", Price: 12.50, Categories: [{ Id: 1, Name: "Category 1" }, { Id: 1, Name: "Category 2" }] }] }; </code></pre> <p>And submit that in the same way as before, capturing the results in the Action we get the first product with null for the categories, since we didn&rsquo;t define it as an empty array:</p> <p><img src="/images/jquery-mvc-5.png" alt="" /></p> <p>While the second Product has 2 items, the first item is Category 1, and the second item is Category 2.</p> <p><img src="/images/jquery-mvc-6.png" alt="" /></p> <p><img src="/images/jquery-mvc-7.png" alt="" /></p> <p>And that&rsquo;s it, easy peasy, sending a collection of ViewModels from jQuery to an MVC Action.</p> <p>I &lt;3 MVC :)</p> Split Windows + Web Workbench = Win 2011-11-27T00:00:00-08:00 http://www.philliphaydon.com/2011/11/split-windows-web-workbench-win/ <p>One of the cool features of the <a href="http://www.mindscapehq.com/products/web-workbench/">Web Workbench</a> from Mindscape is the ability to generate the output files. Prior to using the Web Workbench I was using <a href="http://www.dotlesscss.org/">.LESS{}</a> which uses an HTTP Handler to generate the output files for LESS.</p> <p>The problem with this is sometimes I would write some CSS and not realise I missed something only to find my site doesn&rsquo;t display anything, then I have to figure out what I did wrong.</p> <p>With the Web Workbench, and it&rsquo;s ability to generate the files every time I save, makes me less error prone.</p> <p>But the most efficient way of working with it I found (when writing a lot of CSS in 1 sitting) is to split my windows so the first window has where I&rsquo;m writing, and the second window has the generated CSS file.</p> <p><img src="/images/split-screen-1.png" alt="" /></p> <p>If I make an error on the left side:</p> <p><img src="/images/split-screen-2.png" alt="" /></p> <p>I see the error on the right.</p> <p>If I make a change to the left, (added a background colour) i see the change on the right.</p> <!--excerpt--> <p><img src="/images/split-screen-3.png" alt="" /></p> <p>This makes it really handy when applying nested rules. Such as nesting a hover rule to an anchor tag. Sometimes I forget to include the colon.</p> <p><img src="/images/split-screen-4.png" alt="" /></p> <p>Maybe in the next version of the Web Bench, Mindscape can include side-by-side windows that scroll with each other :) Tho it would be difficult depending on how much CSS was generated. Would still be a nice feature.</p> <p>Either way, the Web Workbench is a tool that can&rsquo;t be missed.</p> Optional Parameters with AttributeRouting 2011-11-27T00:00:00-08:00 http://www.philliphaydon.com/2011/11/optional-parameters-with-attributerouting/ <p>I found a little trick with using Optional Parameters with <a href="https://github.com/mccalltd/AttributeRouting/wiki/2.-Usage">AttributeRouting</a>, by using standard optional parameters in the action.</p> <p>The documentation says you can add an attributes to specify the defaults, or add <code>=value</code> to the parameter name, and I guess that&rsquo;s a more correct way to generate routes, but you can achieve the same affect by making the parameter optional. Like so:</p> <pre><code>[GET("videos/{?page}")] public ActionResult Videos(int page = 1) { return View("Result"); } </code></pre> <p>If I browse to the URL:</p> <p><img src="/images/attribute-routing-1.png" alt="" /></p> <p>It uses the default value of 1.</p> <p><img src="/images/attribute-routing-2.png" alt="" /></p> <p>Now when appending a number to the end of the URL:</p> <!--excerpt--> <p><img src="/images/attribute-routing-3.png" alt="" /></p> <p>It captures the correct value:</p> <p><img src="/images/attribute-routing-4.png" alt="" /></p> <p>I prefer this method, the optional parameter on the action is more quickly identified, than looking at the attribute to see the defaults. (in my opinion)</p> <p>Ahh AttributeRouting, how I love you.</p> Unit of Work with WCF and Autofac 2011-11-06T00:00:00-07:00 http://www.philliphaydon.com/2011/11/unit-of-work-with-wcf-and-autofac/ <p>I&rsquo;ve just spent the last few days trying to find a way to have a Unit of Work with WCF, but it seems no one has a nice clean easy solution.</p> <p>The first, and the only decent solution I found was here:</p> <p><a href="http://ianfnelson.com/archives/2010/04/09/wcf-nhibernate-unit-of-work-endpoint-behavior">http://ianfnelson.com/archives/2010/04/09/wcf-nhibernate-unit-of-work-endpoint-behavior</a></p> <p>The problem I found with this solution is that the ICallContextInitializer as well as the EndpointBehavior is only created once. So it would seem all calls to a service would share the same Unit of Work instance.</p> <p>Maybe Castle Windsor does something fancy and injects a brand new <code>EndpointBehavior</code> every request to a service, but for me, it seemed the <code>ServiceBehavior</code>, <code>EndpointBehavior</code>, and <code>ICallContextInitializer</code> were all created once.</p> <p>This caused my service to resolve a different instance of <code>IUnitOfWork</code> to what was in the <code>ICallContextInitializer</code>.</p> <h2>Interim Solution 1</h2> <p>The first solution I came up with was to use Autofac to call Commit on release:</p> <pre><code>builder.RegisterType(typeof (UnitOfWork)) .As(typeof (IUnitOfWork)) .InstancePerLifetimeScope() .OnRelease(x =&gt; { ((IUnitOfWork) x).Commit(); }); </code></pre> <!--excerpt--> <p>It works&hellip; but it seemed like a real hack, so I kept digging.</p> <p>I posted on <a href="http://stackoverflow.com/questions/7989918/using-a-custom-endpoint-behavior-with-wcf-and-autofac">StackOverflow</a> &amp; <a href="http://groups.google.com/group/autofac/browse_thread/thread/7310498aea634abd">Autofac Google Group</a>, but so far I haven&rsquo;t had anyone suggest a good solution.</p> <h2>Solution 2</h2> <p>The next took a while to come up with.</p> <p><span class="note"><strong>Note:</strong> I don&rsquo;t know if this is an appropriate solution for utilizing a Unit of Work with WCF. It works for me but if there is a better solution I would like to hear it.</span></p> <p>I started by giving all my classes an interface called IService.</p> <pre><code>public interface IService { IUnitOfWork UnitOfWork { get; set; } } </code></pre> <p>My Service implements this interface:</p> <pre><code>public class WasteInventoryQueryService : IWasteInventoryQueryService, IService { public IUnitOfWork UnitOfWork { get; set; } public IWasteStockRepository WasteStockRepository { get; set; } public WasteInventoryQueryService(IUnitOfWork unitOfWork, IWasteStockRepository wasteStockRepository) { UnitOfWork = unitOfWork; WasteStockRepository = wasteStockRepository; } ... } </code></pre> <p>Next I created some behaviours similar to the linked article.</p> <p>Since finding that the ServiceBehavior, EndpointBehavior and ICallContextInitializer all are created once, I started at the ServiceBehavior.</p> <p>I created a class called EndpointResolverServiceBehavior, it&rsquo;s purpose is to inject all the endpoint behaviours I create.</p> <pre><code>public class EndpointResolverServiceBehavior : IServiceBehavior { protected IEnumerable&lt;IEndpointBehavior&gt; EndpointBehaviors { get; set; } public EndpointResolverServiceBehavior(IEnumerable&lt;IEndpointBehavior&gt; endpointBehaviors) { EndpointBehaviors = endpointBehaviors; } #region Implementation of IServiceBehavior public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { } public void AddBindingParameters(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase, Collection&lt;ServiceEndpoint&gt; endpoints, BindingParameterCollection bindingParameters) { } public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase) { foreach (var endpoint in serviceDescription.Endpoints) { foreach (var endpointBehavior in EndpointBehaviors) { endpoint.Behaviors.Add(endpointBehavior); } } } #endregion } </code></pre> <p>Next I created an EndpointBehavior called UnitOfWorkEndpointBehavior, it&rsquo;s purpose is to add the ICallContextInitializer instance.</p> <pre><code>public class UnitOfWorkEndpointBehavior : IEndpointBehavior { public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters) { } public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime) { } public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher) { foreach (DispatchOperation operation in endpointDispatcher.DispatchRuntime.Operations) { operation.CallContextInitializers.Add(new UnitOfWorkCallContextInitializer()); } } public void Validate(ServiceEndpoint endpoint) { } } </code></pre> <p>And then is the ICallContextInitializer.</p> <pre><code>public class UnitOfWorkCallContextInitializer : ICallContextInitializer { private PropertyInfo _userObjectInfo; private readonly BindingFlags _flags = BindingFlags.NonPublic | BindingFlags.Instance; public object BeforeInvoke(InstanceContext instanceContext, IClientChannel channel, Message message) { if (_userObjectInfo == null) _userObjectInfo = instanceContext.GetType() .GetProperty("UserObject", _flags); return _userObjectInfo.GetValue(instanceContext, null) as IService; } public void AfterInvoke(object correlationState) { var uow = correlationState as IService; if (uow != null) uow.UnitOfWork.Commit(); } } </code></pre> <p>While debugging I found out that the InstanceContext has a private property which has the current service attached to it:</p> <p><img src="/images/uow-autofac-1.png" alt="" /></p> <p><img src="/images/uow-autofac-2.png" alt="" /></p> <p>(click the image for a larger view)</p> <p>So I reflected the property and casted it to an IService, and return the result. When the service has been invoked, the result passed out of the &lsquo;BeforeInvoke&rsquo; method, is passed into the &lsquo;AfterInvoke&rsquo;.</p> <p><img src="/images/uow-autofac-3.png" alt="" /></p> <p>So basically I return the result from the BeforeInvoke which is passed into the AfterInvoke. Then I attempt to cast it to an IService again.</p> <p>If the cast is successful, then I can call Commit on my UnitOfWork.</p> <p>The last piece is to wire up the Behavior with Autofac.</p> <pre><code>builder.RegisterType(typeof(UnitOfWorkEndpointBehavior)).As(typeof(IEndpointBehavior)); builder.RegisterType(typeof(EndpointResolverServiceBehavior)).As(typeof(IServiceBehavior)); Container = builder.Build(); AutofacHostFactory.Container = Container; AutofacHostFactory.HostConfigurationAction = host =&gt; { host.Description.Behaviors.Add(Container.Resolve&lt;IServiceBehavior&gt;()); }; </code></pre> <p>And it&rsquo;s done. I have a working Unit of Work, that is injected into my Service and Committed after the service has been invoked.</p> <p>The only down-side I see to all of this, is that if an exception is thrown that I don&rsquo;t capture, then the UoW will still be committed regardless.</p> <p>If anyone has any better solutions, let me know! :)</p> Windows Phone, Windows Live and MSN 2011-11-02T00:00:00-07:00 http://www.philliphaydon.com/2011/11/windows-phone-windows-live-and-msn/ <p>Windows Phone 7.5 has been getting some awesome reviews, and rightly so. The thing is amazing. I really think Microsoft has begun leading the way for the mobile platform.</p> <p>But I&rsquo;m highly pissed off with the Windows Phone team. Why? <strong>Because to use MSN, your msn contacts must be associated with the first live account you register to the phone.</strong></p> <p>I don&rsquo;t even know what to say about this, it&rsquo;s so silly. I understand that it might get confusing to allow multiple Facebook accounts, multiple Windows Live accounts, etc.</p> <p>But could they not allow you to choose which account MSN contacts are associated to?</p> <p>When I first setup my phone I didn&rsquo;t use the Windows Live account I use for MSN (my Hotmail) since it&rsquo;s existed since 1997, it&rsquo;s got 100&rsquo;s of contacts I don&rsquo;t want in my phone-book, a lot of MSN contacts exist from work, or playing online games, or from forums etc. So I used the Windows Live account that I use for MSDN. I added all my contacts and everything was great, (after I imported all my contacts from outlook into Windows Live Contacts)</p> <!--excerpt--> <p>I attached my Facebook account, went to People > Settings > Filter Contacts, and turned off Facebook so they do not show in my normal contacts list. This allows me to have normal phone users, but see the Facebook users on the Messaging list.</p> <p>Now I want to show MSN contacts, so I load up the next Windows Live account, it loads all my contacts, but when I go to messaging, I get NOTHING. No MSN users at all.</p> <p>On my second Windows Phone (yes I have two) I reformatted it, and signed it up on my Hotmail Windows Live account, and what do I see? All my MSN contacts.</p> <p>Ok so the team didn&rsquo;t give us the option to select which Live account we can use for MSN&hellip; So I went to download IM+</p> <h2>DEAD END</h2> <blockquote><p>ATTENTION MSN/WLM users! MSN/WLM is not supported in 1.7 version of IM+ due to Microsoft Marketplace request. If you would like to continue using MSN/WLM in IM+, do not update to 1.7 version from version 1.2. We will continue working on this situation with Microsoft.</p></blockquote> <p>WTF&hellip; So not only can I not use MSN on my phone natively. The team has blocked anyone else from providing the feature in their own applications&hellip;</p> <p>That&rsquo;s not fair at all.</p> <p>Microsoft should be ashamed.</p> <p>So as it stands, if you don&rsquo;t use your MSN account as your Windows Phone account, you can&rsquo;t use MSN.</p> <p>Microsoft is definitely leading the way in Mobile platform, but they massively screwed up MSN for many users.</p> RavenDB - Changing the Lo on the HiLo Generator 2011-10-24T00:00:00-07:00 http://www.philliphaydon.com/2011/10/ravendb-changing-the-lo-on-the-hilo-generator/ <p>Well I&rsquo;m currently learning RavenDB, it&rsquo;s awesome! But I noticed when I put data in, all the Id&rsquo;s generated every time I ran up my application to test were:</p> <p>1, 2, 3, 4, 5&hellip;</p> <p>1024, 1025, 1026, 1027, 1028&hellip;</p> <p>2048, 2049, 2050, 2051, 2052&hellip;</p> <p>This would be fine after the app is deployed since I wouldn&rsquo;t be restarting it over and over and over, but during development I personally find it annoying that the numbers jump so high.</p> <p>Fortunately I figured out a way. (which about an hour later I found on Google Groups, granted I had to use a different keyword to find it)</p> <p>Basically you just need to create a new instance of the <code>MultiTypeHiLoKeyGenerator</code> class, passing in the arguments and assigning it to the document store:</p> <pre><code>var documentStore = (new DocumentStore { Url = "http://localhost:12321/" }).Initialize(); var generator = new MultiTypeHiLoKeyGenerator(documentStore, 10); documentStore.Conventions.DocumentKeyGenerator = entity =&gt; generator.GenerateDocumentKey(documentStore.Conventions, entity); using (var session = documentStore.OpenSession()) { session.Store(new Project() { Title = "Hello World" }); session.SaveChanges(); } </code></pre> <p>So running up my app once:</p> <!--excerpt--> <p><img src="/images/ravendb-hilo-1.png" alt="" /></p> <p>And again:</p> <p><img src="/images/ravendb-hilo-2.png" alt="" /></p> <p>Now the identity only increases every time the app restarts. And to show it generates more than 1 number&hellip;</p> <p><img src="/images/ravendb-hilo-3.png" alt="" /></p> <p>It took a while of hunting on the net, but it turns out Googling &amp; Binging, or searching (StackOverflow/Google Groups) for the keyword <code>Lo</code> doesn&rsquo;t work, the argument is <code>capacity</code> and searching for that on Google Groups lead me here:</p> <p><a href="http://groups.google.com/group/ravendb/browse_thread/thread/95a5b33a5d30eb71/a5197e2e01376e65?lnk=gst&amp;q=capacity#a5197e2e01376e65">http://groups.google.com/group/ravendb/browse_thread/thread/95a5b33a5d30eb71/a5197e2e01376e65?lnk=gst&amp;q=capacity#a5197e2e01376e65</a></p> <p>Hopefully someone else finds this useful :)</p> NHibernate Designer 2 2011-10-20T00:00:00-07:00 http://www.philliphaydon.com/2011/10/nhibernate-designer-2/ <p>The guys at MindScape have released their next version of NHibernate Designer, which now supports Fluent NHibernate and a whole heap of new features.</p> <p>They also dropped the price down to just $99!</p> <p>I recommend checking it out</p> <p><a href="http://www.mindscapehq.com/blog/index.php/2011/10/19/nhibernate-designer-2-is-here/">http://www.mindscapehq.com/blog/index.php/2011/10/19/nhibernate-designer-2-is-here/</a></p> <p><a href="http://www.mindscapehq.com/products/nhdesigner">http://www.mindscapehq.com/products/nhdesigner</a></p> Website Folder Structure? CSS Files? Does anyone care? I do... 2011-10-17T00:00:00-07:00 http://www.philliphaydon.com/2011/10/website-folder-structure-css-files-does-anyone-care-i-do/ <p>When we build website&rsquo;s, more often than not we have: Separation of Concerns. Even if at most it&rsquo;s just basic 3-tier Architecture</p> <p>What annoys me though is a lot of time no one ever thinks about separation of concerns when it comes to the folder structure of their website, and where things go.</p> <h2>Folders</h2> <p>The one thing that annoys me above all else, is when &lsquo;layout images&rsquo; (images for layout, design, styling etc) of the website, are shoved into the same folder that holds what I call &ldquo;Content Images&rdquo;.</p> <p>For example:</p> <pre><code>root/ root/css/ root/images/ </code></pre> <p>What I prefer to do is structure it so the css folder has it&rsquo;s own images folder, specifically for layout images.</p> <pre><code>root/ root/css/ root/css/images/ root/images </code></pre> <!--excerpt--> <p>To take it a step further, I often have images, icons, and fonts.</p> <pre><code>root/ root/css/ root/css/fonts/ root/css/icons/ root/css/images/ root/images </code></pre> <p>This way I don&rsquo;t have to worry about finding specific icons in a folder full of images, I don&rsquo;t have to worry about sifting through images to find ones related to the layout/design, they are all neatly tucked away in their own specific areas.</p> <p>When it comes to folder structure however, NuGet gets in the way.</p> <p>It would be nice if it allowed you to specify where file types should go. At the moment &lsquo;css&rsquo; files seem to go into &lsquo;Content&rsquo;. JavaScript files go into &lsquo;Scripts&rsquo;. But what I would rather have is all lower-case names, and &lsquo;css&rsquo; rather than &lsquo;content&rsquo;. Until then, I just download those sort of dependencies manually and create my own folder structure.</p> <h2>CSS</h2> <p>The next thing that I find annoying is the God Style Sheet. It&rsquo;s the StyleSheet that people name:</p> <pre><code>Styles.css </code></pre> <p>It&rsquo;s the only one that exists in the project, it&rsquo;s over 100k in size, no comments, no christmas trees. Just lines and lines of fail.</p> <p>The approach I used to take (before finding .LESS) was creating multiple StyleSheets that were small and easy to maintain, sometimes I would end up with up to 12, possibly more depending on the size of the website.</p> <p>Each StyleSheet would be responsible for a specific task, so I would have something like the following:</p> <pre><code>/css/reset.css (this is just one of those many reset StyleSheets found on the net) /css/layout.css /css/main.css /css/header.css /css/footer.css /css/main-navigation.css /css/... </code></pre> <p>When sections of the website were broken down like this, it did require flicking between StyleSheets now-n-then, but they became much smaller and easier to maintain. I also became far-less at risk of Unwanted Side Effects.</p> <p>Now with .LESS and LESS, it&rsquo;s easy to have only a few StyleSheets, since now you can tab within a specific region and continue to write styles that only apply to that region.</p> <p>For example, given a Footer element. You could come up with something like:</p> <pre><code>footer { border-top: 2px #182a33 solid; padding-top: 30px; nav { a { font-family: @footer-link-font; font-size: @footer-link-size; color: @footer-link-color; text-decoration: none; &amp;:hover { color: @footer-link-color-hover; text-decoration: underline; } } li &gt; span { color: @footer-text-color; font-family: @footer-text-font; font-size: @footer-text-size; } h4 { color: @footer-heading-color; font-family: @footer-heading-font; font-size: @footer-heading-size; font-weight: bold; margin-bottom: 35px; padding-top: 17px; } &gt; ul &gt; li { width: 165px; float: left; display: block; line-height: 18px; } } } </code></pre> <p>This would in turn generate the following CSS for you.</p> <pre><code>footer { border-top: 2px #182a33 solid; padding-top: 30px; } footer nav a { font-family: arial; font-size: 12px; color: #00adee; text-decoration: none; } footer nav a:hover { color: #00adee; text-decoration: underline; } footer nav li &gt; span { color: #a8a8a8; font-family: arial; font-size: 12px; } footer nav h4 { color: white; font-family: arial; font-size: 16px; font-weight: bold; margin-bottom: 35px; padding-top: 17px; } footer nav &gt; ul &gt; li { width: 165px; float: left; display: block; line-height: 18px; } </code></pre> <p>I find it much easier to manage writing &lsquo;LESS&rsquo; then traditional CSS.</p> <h2>Conclusion</h2> <p>I didn&rsquo;t want to go into too much detail, my main point is I think people should put a little more thought into how they structure their folders, files, naming, etc when creating websites. We focus so much time on trying to main our applications and code maintainable, but somehow neglect the website itself, and after a while we just end up fighting with it.</p> The benefits of letting the ORM generate the Identity (part 1) 2011-09-22T00:00:00-07:00 http://www.philliphaydon.com/2011/09/the-benefits-of-letting-the-orm-generate-the-identity-part-1/ <p>One thing I&rsquo;ve learnt is that letting the database generate the identity for you is a bad thing. It always annoyed me that Oracle never gave a feature like <a href="http://dev.mysql.com/doc/refman/5.0/en/example-auto-increment.html">AUTO_INCREMENT</a> in MySQL or <a href="http://msdn.microsoft.com/en-us/library/aa933196(SQL.80">IDENTITY</a>.aspx) in SQL Server. I never understood, when inserting data how do I give it an Id?</p> <p>Well one of the benefits of ORMs such as NHibernate is we can generate the identity our-self, or rather, the ORM can generate it so we don&rsquo;t rely on the database. This also plays a major part in our code base when we insert a graph or batch of data and how the identity is added to our object.</p> <p>Ayende <a href="http://ayende.com/blog/3915/nhibernate-avoid-identity-generator-when-possible">recommend avoiding identity</a>.</p> <p>The thing with using SQL Server"s identity is that we need to select the identity back out after we do an insert. Not only that, when using <a href="http://msdn.microsoft.com/en-us/library/ms190348.aspx">NEWID()</a>/<a href="http://msdn.microsoft.com/en-us/library/ms189786.aspx">NEWSEQUENTIALID()</a> there is no way to select the value back other than using all the fields in a select in order to get the GUID relates to the record with all those values matching.</p> <p>For example:</p> <p>Given this rather simple table using IDENTITY.</p> <pre><code>CREATE TABLE People ( Id int NOT NULL IDENTITY (1, 1) PRIMARY KEY, FirstName nvarchar(100) NOT NULL, Surname nvarchar(100) NOT NULL ) </code></pre> <!--excerpt--> <p>And I&rsquo;ll demo with NEWID() as well.</p> <pre><code>CREATE TABLE Fruit ( Id uniqueidentifier NOT NULL PRIMARY KEY DEFAULT (NEWID()), Name nvarchar(100) NOT NULL ) </code></pre> <p><span class="note"><strong>Note:</strong> I&rsquo;m unaware of anyway to get NHibernate to use NEWSEQUENTIALID()</span></p> <p>We map these in NHibernate like so:</p> <pre><code>public class PersonMap : ClassMap&lt;Person&gt; { public PersonMap() { Table("People"); Id(x =&gt; x.Id).GeneratedBy.Identity(); Map(x =&gt; x.FirstName); Map(x =&gt; x.Surname); } } public class FruitMap : ClassMap&lt;Fruit&gt; { public FruitMap() { Table("Fruit"); Id(x =&gt; x.Id).GeneratedBy.GuidNative(); Map(x =&gt; x.Name); } } </code></pre> <p>If we insert data into People and Fruit like so:</p> <pre><code>using (var tx = session.BeginTransaction()) { var person = new Person { FirstName = "Phillip", Surname = "Haydon" }; var fruit = new Fruit { Name = "Apple" }; session.SaveOrUpdate(person); session.SaveOrUpdate(fruit); tx.Commit(); } </code></pre> <p>We get the following statement&rsquo;s run:</p> <pre><code>- statement #1 begin transaction with isolation level: Unspecified - statement #2 INSERT INTO People (FirstName, Surname) VALUES ('Phillip' /* @p0 */, 'Haydon' /* @p1 */); select SCOPE_IDENTITY() - statement #3 select newid() - statement #4 INSERT INTO Fruit (Name, Id) VALUES ('Apple' /* @p0 */, '3411c820-f9cc-4385-97a1-31cf7e7c612c' /* @p1 */) - statement #5 commit transaction </code></pre> <p>What&rsquo;s interesting is for the Identity, we have to select the SCOPE_IDENTITY() back after the insert so that we can populate the Person object, and for the Fruit object, we have to select NEWID() first as a separate statement, then add it to the business object, and commit it.</p> <p>This round-trip to the database in order to get the GUID first before doing the insert is completely unnecessary, not to mention has a performance impact.</p> <p>Inserting 50,000 items for each, with the batch-size set to 50, yields the following:</p> <table> <tr> <td>IDENTITY</td> <td>28951</td> </tr> <tr> <td>NEWID</td> <td>30241</td> </tr> </table> <p>(value in milliseconds)</p> <p><span class="note"><strong>Note:</strong> These benchmarks are quick-nasty benchmarks and were only run once.</span></p> <p>The interesting thing is neither IDENTITY or NEWID batched any of the insert statements together, they were all issued as separate statements.</p> <p>(re-run the test inserting 3 to show SQL output)</p> <p>The &lsquo;Person&rsquo; insert looks like this:</p> <pre><code>- statement #1 begin transaction with isolation level: Unspecified - statement #2 INSERT INTO People (FirstName, Surname) VALUES ('Phillip0' /* @p0 */, 'Haydon' /* @p1 */); select SCOPE_IDENTITY() - statement #3 INSERT INTO People (FirstName, Surname) VALUES ('Phillip1' /* @p0 */, 'Haydon' /* @p1 */); select SCOPE_IDENTITY() - statement #4 INSERT INTO People (FirstName, Surname) VALUES ('Phillip2' /* @p0 */, 'Haydon' /* @p1 */); select SCOPE_IDENTITY() - statement #5 commit transaction </code></pre> <p>Each insert has to be done 1 by 1, since it needs to select the identity back.</p> <p>The &lsquo;Fruit&rsquo; table on the other hand:</p> <pre><code>- statement #1 begin transaction with isolation level: Unspecified - statement #2 select newid() - statement #3 select newid() - statement #4 select newid() - statement #5 INSERT INTO Fruit (Name, Id) VALUES ('Apple0' /* @p0_0 */, '269bc638-74b4-4568-85d1-45b6e537fcbd' /* @p1_0 */) INSERT INTO Fruit (Name, Id) VALUES ('Apple1' /* @p0_1 */, 'fc848779-b173-4c31-b8b6-0a7735c0c2dc' /* @p1_1 */) INSERT INTO Fruit (Name, Id) VALUES ('Apple2' /* @p0_2 */, '232c8971-18c7-486d-9152-26c969c3b632' /* @p1_2 */) - statement #6 commit transaction </code></pre> <p>It select 50,000 GUIDs first, then it issues all the insert statement&rsquo;s in batches of 50.</p> <p>Now lets look at HiLo and GuidComb (GuidComb is a Sequencial Guid, but NH also allows normal Guids), two ways of generating identities in the ORM rather than the database.</p> <p>The tables are the same as before, except they don&rsquo;t have &lsquo;IDENTITY&rsquo; or a Default Value.</p> <p>The mappings have been updated to:</p> <pre><code>Id(x =&gt; x.Id).GeneratedBy.HiLo("100"); </code></pre> <p>And</p> <pre><code>Id(x =&gt; x.Id).GeneratedBy.GuidComb(); </code></pre> <p>Running a single insert for both results in:</p> <pre><code>- statement #1 begin transaction with isolation level: Unspecified - statement #2 Reading high value: select next_hi from hibernate_unique_key with (updlock, rowlock) - statement #3 Updating high value: update hibernate_unique_key set next_hi = 2 /* @p0 */ where next_hi = 1 /* @p1 */ - statement #4 INSERT INTO People (FirstName, Surname, Id) VALUES ('Phillip' /* @p0_0 */, 'Haydon' /* @p1_0 */, 101 /* @p2_0 */) - statement #5 INSERT INTO Fruit (Name, Id) VALUES ('Apple' /* @p0_0 */, '3229618e-bd8a-45ae-8ad5-9f660016980d' /* @p1_0 */) - statement #6 commit transaction </code></pre> <p>Besides NHibernate getting the first Hi value for use in the HiLo algorithm, both insert statement did not require selecting or generating any identity, it was all done in NHibernate.</p> <p>This makes inserting 3 &lsquo;Person&rsquo; much more efficient:</p> <pre><code>- statement #1 begin transaction with isolation level: Unspecified - statement #2 Reading high value: select next_hi from hibernate_unique_key with (updlock, rowlock) - statement #3 Updating high value: update hibernate_unique_key set next_hi = 3 /* @p0 */ where next_hi = 2 /* @p1 */ - statement #4 INSERT INTO People (FirstName, Surname, Id) VALUES ('Phillip0' /* @p0_0 */, 'Haydon' /* @p1_0 */, 202 /* @p2_0 */) INSERT INTO People (FirstName, Surname, Id) VALUES ('Phillip1' /* @p0_1 */, 'Haydon' /* @p1_1 */, 203 /* @p2_1 */) INSERT INTO People (FirstName, Surname, Id) VALUES ('Phillip2' /* @p0_2 */, 'Haydon' /* @p1_2 */, 204 /* @p2_2 */) - statement #5 commit transaction </code></pre> <p>3 insert&rsquo;s done as a single batch statement.</p> <p>And inserting 3 Fruit:</p> <pre><code>- statement #1 begin transaction with isolation level: Unspecified - statement #2 INSERT INTO Fruit (Name, Id) VALUES ('Apple0' /* @p0_0 */, 'db902160-edbb-49c7-bf52-9f660018299a' /* @p1_0 */) INSERT INTO Fruit (Name, Id) VALUES ('Apple1' /* @p0_1 */, '5e852528-3a6f-41d2-a6b1-9f660018299a' /* @p1_1 */) INSERT INTO Fruit (Name, Id) VALUES ('Apple2' /* @p0_2 */, '2f63c6e8-e595-4393-ad15-9f660018299a' /* @p1_2 */) - statement #3 commit transaction </code></pre> <p>Again, 3 insert&rsquo;s done as a single batch statement.</p> <p>If we run 50,000 inserts again:</p> <table> <tr> <td>HiLo</td> <td>9287</td> </tr> <tr> <td>GuidComb</td> <td>9060</td> </tr> </table> <p>That is over 3 times faster!</p> <p>So as you can see, for just doing batch inserting, with a full Session (rather than stateless) and allowing the ORM to generate identities, we can significantly improve performance.</p> Fluent NHibernate - Table Inheritance - Discriminators (Part 2) 2011-08-22T00:00:00-07:00 http://www.philliphaydon.com/2011/08/fluent-nhibernate-table-inheritance-discriminators-part-2/ <p>This is part two, to my post about <a href="/2011/08/fluent-nhibernate-table-inheritance-discriminators/">Table Inheritance using Discriminators</a>, in this post I just want to demonstrate the outcome when the sub-classes have their own properties, or possibly a property that maps to the same column.</p> <p>First thing however is Mark Perry pointed out in the comments that specifying a value for the baseClassDiscriminator will force it to store the value in the database as an INT rather than a a VARCHAR.</p> <pre><code>DiscriminateSubClassesOnColumn("PostType", 0); </code></pre> <p>This will create the table with an INT like so:</p> <pre><code>create table WallPost ( Id UNIQUEIDENTIFIER not null, PostType INT not null, DatePosted DATETIME null, Title NVARCHAR(255) null, Content NVARCHAR(255) null, primary key ( Id )) </code></pre> <p>Maybe INT is too big however, maybe we only want a SMALLINT? That will give us 32k sub-classes&hellip;</p> <pre><code>DiscriminateSubClassesOnColumn("PostType", (short)0); </code></pre> <!--excerpt--> <!-- --> <pre><code>PostType SMALLINT not null, </code></pre> <p>But even that is too many, so maybe we need TINYINT, that gives us 0-255. I doubt you would ever have 255 sub-classes, so we can specify the discriminator as a byte.</p> <pre><code>DiscriminateSubClassesOnColumn("PostType", (byte)0); </code></pre> <p>And that gives us:</p> <pre><code>create table WallPost ( Id UNIQUEIDENTIFIER not null, PostType TINYINT not null, DatePosted DATETIME null, Title NVARCHAR(255) null, Content NVARCHAR(255) null, primary key ( Id )) </code></pre> <p>Nice, much better.</p> <p>Not to mention when querying now, it uses the INT value rather than the number being used as a string like before:</p> <pre><code>SELECT this_.Id as Id0_0_, this_.DatePosted as DatePosted0_0_, this_.Title as Title0_0_, this_.Content as Content0_0_ FROM WallPost this_ WHERE this_.PostType = 1 </code></pre> <p>So the next thing I want to show is what happens when we add a property to 1 sub-class and not the other. (or properties than exist in 1, and properties that exist in the other)</p> <p>Give the same example as my previous post, I&rsquo;ve added one property to the class, a &lsquo;Url&rsquo; property.</p> <p><img src="/images/fnh-table-inheritance-1.png" alt="" /></p> <p>This will get created as a normal column in the database.</p> <pre><code>create table WallPost ( Id UNIQUEIDENTIFIER not null, PostType TINYINT not null, DatePosted DATETIME null, Title NVARCHAR(255) null, Content NVARCHAR(255) null, Url NVARCHAR(255) null, primary key ( Id )) </code></pre> <p>When we insert now, a LinkShare and a Text wallpost:</p> <pre><code>var wallPost = new TextWallPost { DatePosted = DateTime.Now, Title = "My First Wall Post", Content = "Is Awesome!" }; var linkPost = new LinkShareWallPost() { DatePosted = DateTime.Now, Title = "My First Link Share", Content = "Is Awesome!", Url = "http://www.philliphaydon.com/" }; session.Save(wallPost); session.Save(linkPost); </code></pre> <p>The link share one will include the Url.</p> <pre><code>- statement #1 INSERT INTO WallPost (DatePosted, Title, Content, PostType, Id) VALUES ('2011-08-21T23:53:10.00' /* @p0 */, 'My First Wall Post' /* @p1 */, 'Is Awesome!' /* @p2 */, 1, '2dc7981b-507b-4d36-8ecc-9f460189a27d' /* @p3 */) - statement #2 INSERT INTO WallPost (DatePosted, Title, Content, Url, PostType, Id) VALUES ('2011-08-21T23:53:10.00' /* @p0 */, 'My First Link Share' /* @p1 */, 'Is Awesome!' /* @p2 */, 'http://www.philliphaydon.com/' /* @p3 */, 2, '5edfe0f2-e179-4615-88e4-9f460189a284' /* @p4 */) </code></pre> <p>The &lsquo;Url&rsquo; column must be null, or have a default value assigned to it so that when inserting a Text wallpost, the column doesn&rsquo;t need to be specified.</p> <p>If we query for the base class:</p> <pre><code>var result = session.QueryOver&lt;WallPost&gt;().List(); </code></pre> <p>This will query for all columns:</p> <pre><code>SELECT this_.Id as Id0_0_, this_.DatePosted as DatePosted0_0_, this_.Title as Title0_0_, this_.Content as Content0_0_, this_.Url as Url0_0_, this_.PostType as PostType0_0_ FROM WallPost this_ </code></pre> <p>Just like it did before. No changes, likewise if we query for just the Text wallpost, it will not include the &lsquo;Url&rsquo; column:</p> <pre><code>var result = session.QueryOver&lt;TextWallPost&gt;().List(); </code></pre> <p>Results in:</p> <pre><code>SELECT this_.Id as Id0_0_, this_.DatePosted as DatePosted0_0_, this_.Title as Title0_0_, this_.Content as Content0_0_ FROM WallPost this_ WHERE this_.PostType = 1 </code></pre> <p>If we query for the LinkShare wall post:</p> <pre><code>var result = session.QueryOver&lt;LinkShareWallPost&gt;().List(); </code></pre> <p>This results in the &lsquo;Url&rsquo; column being selected:</p> <pre><code>SELECT this_.Id as Id0_0_, this_.DatePosted as DatePosted0_0_, this_.Title as Title0_0_, this_.Content as Content0_0_, this_.Url as Url0_0_ FROM WallPost this_ WHERE this_.PostType = 2 </code></pre> <p>So NHibernate is efficient in that it only queries for what it actually needs. If you extend your sub-classes out to have a couple of properties each then they will only query for the required fields for that sub-class.</p> <p>It is possible for sub-classes to share properties. For example if introduced a new sub-class, MovieShare, which has a VideoUrl, as well as a SiteUrl property:</p> <p><img src="/images/fnh-table-inheritance-2.png" alt="" /></p> <p>We can map the classes like so:</p> <pre><code>public class TextWallPostMap : SubclassMap&lt;TextWallPost&gt; { public TextWallPostMap() { DiscriminatorValue(1); } } public class LinkShareWallPostMap : SubclassMap&lt;LinkShareWallPost&gt; { public LinkShareWallPostMap() { DiscriminatorValue(2); Map(x =&gt; x.Url).Column("Url"); } } public class MovieShareWallPostMap : SubclassMap&lt;MovieShareWallPost&gt; { public MovieShareWallPostMap() { DiscriminatorValue(3); Map(x =&gt; x.SiteUrl).Column("Url"); Map(x =&gt; x.VideoUrl).Column("VideoUrl"); } } </code></pre> <p>When the table is created, &lsquo;Url&rsquo; column is only created once:</p> <pre><code>create table WallPost ( Id UNIQUEIDENTIFIER not null, PostType TINYINT not null, DatePosted DATETIME null, Title NVARCHAR(255) null, Content NVARCHAR(255) null, Url NVARCHAR(255) null, VideoUrl NVARCHAR(255) null, primary key ( Id )) </code></pre> <p>Now when we insert:</p> <pre><code>var wallPost = new TextWallPost { DatePosted = DateTime.Now, Title = "My First Wall Post", Content = "Is Awesome!" }; var linkPost = new LinkShareWallPost() { DatePosted = DateTime.Now, Title = "My First Link Share", Content = "Is Awesome!", Url = "http://www.philliphaydon.com/" }; var moviePost = new MovieShareWallPost() { DatePosted = DateTime.Now, Title = "My First Movie Share", Content = "Is Awesome!", SiteUrl = "http://www.philliphaydon.com/", VideoUrl = "http://www.youtube.com/watch?v=GaoLU6zKaws" }; session.Save(wallPost); session.Save(linkPost); session.Save(moviePost); </code></pre> <p>The insert will share the same &lsquo;Url&rsquo; column for both the LinkShare, and the MovieShare:</p> <pre><code>- statement #1 INSERT INTO WallPost (DatePosted, Title, Content, PostType, Id) VALUES ('2011-08-22T00:22:05.00' /* @p0 */, 'My First Wall Post' /* @p1 */, 'Is Awesome!' /* @p2 */, 1, '0e9cef50-d609-4a62-8909-9f47000611cb' /* @p3 */) - statement #2 INSERT INTO WallPost (DatePosted, Title, Content, Url, PostType, Id) VALUES ('2011-08-22T00:22:05.00' /* @p0 */, 'My First Link Share' /* @p1 */, 'Is Awesome!' /* @p2 */, 'http://www.philliphaydon.com/' /* @p3 */, 2, '8deb343e-941f-4ae1-aba7-9f47000611d0' /* @p4 */) - statement #3 INSERT INTO WallPost (DatePosted, Title, Content, Url, VideoUrl, PostType, Id) VALUES ('2011-08-22T00:22:05.00' /* @p0 */, 'My First Movie Share' /* @p1 */, 'Is Awesome!' /* @p2 */, 'http://www.philliphaydon.com/' /* @p3 */, 'http://www.youtube.com/watch?v=GaoLU6zKaws' /* @p4 */, 3, '6bc80750-3fb2-4830-bccf-9f47000611d0' /* @p5 */) </code></pre> <p>And querying is still as it was before. No changes.</p> <p>One really important thing to remember is. You cannot change a type from 1 type to another, meaning you cannot change a LinkShare to a MovieShare. Any sub-class you create should never have any reason to change, if for some reason it DOES change, you should delete it, and create a new one.</p> <p>By that I mean delete the object, and insert a new one of the specified sub-class. While it is possible to use native SQL to change the discriminator value, there&rsquo;s no way to do it in HQL, Criteria, LINQ, or QueryOver, because it&rsquo;s just wrong. If it needs to change, you probably need to re-think your domain and persistence.</p> <p>Next post will be about Table per Sub-Class mapping.</p> NHibernate Work-Around is not really a Work-Around... 2011-08-15T00:00:00-07:00 http://www.philliphaydon.com/2011/08/nhibernate-work-around-is-not-really-a-work-around/ <p>Over the weekend I came across a blog post about NHibernate, and an apparent work-around for a feature not supported by NHibernate.</p> <p>The original post can be found here: <a href="http://www.arrangeactassert.com/nhibernate-linq-workaround-for-system-notsupportedexception/">nHibernate LINQ workaround for System.NotSupportedException</a></p> <p>Basically the author wanted to write something along the lines of:</p> <pre><code>var fruitIds = new List&lt;int&gt; { 5, 8, 13 }; using (var session = factory.OpenSession()) { var result = from f in session.Query&lt;NHFruit&gt;() join i in fruitIds on f.Id equals i select f; foreach (var fruit in result) Console.WriteLine(fruit.Name); } </code></pre> <p>Where the query joins to a list of Ids to filter the results out. This however, happens to throw an exception:</p> <!--excerpt--> <p><img src="/images/nhibernate-workaround-1.png" alt="" /></p> <p>Normally this sort of query would be written like so:</p> <pre><code>var fruitIds = new List&lt;int&gt; { 5, 8, 13 }; using (var session = factory.OpenSession()) { var result = from f in session.Query&lt;NHFruit&gt;() where fruitIds.Contains(f.Id) select f; foreach (var fruit in result) Console.WriteLine(fruit.Name); } </code></pre> <p>This generates an &lsquo;in&rsquo; clause in the SQL.</p> <pre><code>select nhfruit0_.Id as Id0_, nhfruit0_.Name as Name0_ from Fruit nhfruit0_ where nhfruit0_.Id in (5 /* @p0 */,8 /* @p1 */,13 /* @p2 */) Nice and clean, pretty standard SQL. </code></pre> <p>Now I must admit when I first read his code I made the assumption that it would actually pull ALL results into memory, and do the join in memory.</p> <p>I commented on his blog with the following comment:</p> <blockquote><p>I don"t see how this is a &ldquo;work-around&rdquo; your first attempt at the query is attempting to join something in memory, to something still in the database. Thats clearly not, and will never be a supported feature of NHibernate&hellip; The second query is passing a list of ID"s into the database to use for comparison.</p></blockquote> <p>At the time of writing the comment, I was a bit annoyed. The author replied:</p> <blockquote><p>Never be supported in NHibernate&hellip; well it works using Entity Framework and that&rsquo;s why I consider it to be a workaround.</p></blockquote> <p>So lets give it a go.</p> <p>Give the following query:</p> <pre><code>var fruitIds = new List&lt;int&gt; { 5, 8, 13 }; using (var ctx = new EFTestEntities()) { var result = from f in ctx.Fruits join i in fruitIds on f.Id equals i select f; foreach (var fruit in result) Console.WriteLine(fruit.Name); } </code></pre> <p>The exact same as the attempt in NHibernate, it generates the following SQL&hellip;</p> <pre><code>SELECT [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name] FROM [dbo].[Fruit] AS [Extent1] INNER JOIN (SELECT [UnionAll1].[C1] AS [C1] FROM (SELECT 5 AS [C1] FROM (SELECT 1 AS X) AS [SingleRowTable1] UNION ALL SELECT 8 AS [C1] FROM (SELECT 1 AS X) AS [SingleRowTable2]) AS [UnionAll1] UNION ALL SELECT 13 AS [C1] FROM (SELECT 1 AS X) AS [SingleRowTable3]) AS [UnionAll2] ON [Extent1].[Id] = [UnionAll2].[C1] </code></pre> <p>WTF.</p> <p><img src="/images/nhibernate-workaround-2.png" alt="" /></p> <p>It creates a select statement, for each value that you want to select&hellip; I thought &ldquo;oh ok, i wonder what the execution plan looks like for that, compared to a normal in-clause from NHibernate.</p> <p>Using both the queries already shown above, showing the actual execution plans, I get the following:</p> <p><img src="/images/nhibernate-workaround-3.png" alt="" /></p> <p>Wow&hellip; But it gets better, I have 20 records in my database, and I thought, what happens if my list of Ids contains 10 different ids:</p> <p>Same queries, but with:</p> <pre><code>var fruitIds = new List&lt;int&gt; { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 }; </code></pre> <p>Entity Framework (I don&rsquo;t even want to paste this in here&hellip;):</p> <pre><code>SELECT [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name] FROM [dbo].[Fruit] AS [Extent1] INNER JOIN (SELECT [UnionAll8].[C1] AS [C1] FROM (SELECT [UnionAll7].[C1] AS [C1] FROM (SELECT [UnionAll6].[C1] AS [C1] FROM (SELECT [UnionAll5].[C1] AS [C1] FROM (SELECT [UnionAll4].[C1] AS [C1] FROM (SELECT [UnionAll3].[C1] AS [C1] FROM (SELECT [UnionAll2].[C1] AS [C1] FROM (SELECT [UnionAll1].[C1] AS [C1] FROM (SELECT 2 AS [C1] FROM (SELECT 1 AS X) AS [SingleRowTable1] UNION ALL SELECT 4 AS [C1] FROM (SELECT 1 AS X) AS [SingleRowTable2]) AS [UnionAll1] UNION ALL SELECT 6 AS [C1] FROM (SELECT 1 AS X) AS [SingleRowTable3]) AS [UnionAll2] UNION ALL SELECT 8 AS [C1] FROM (SELECT 1 AS X) AS [SingleRowTable4]) AS [UnionAll3] UNION ALL SELECT 10 AS [C1] FROM (SELECT 1 AS X) AS [SingleRowTable5]) AS [UnionAll4] UNION ALL SELECT 12 AS [C1] FROM (SELECT 1 AS X) AS [SingleRowTable6]) AS [UnionAll5] UNION ALL SELECT 14 AS [C1] FROM (SELECT 1 AS X) AS [SingleRowTable7]) AS [UnionAll6] UNION ALL SELECT 16 AS [C1] FROM (SELECT 1 AS X) AS [SingleRowTable8]) AS [UnionAll7] UNION ALL SELECT 18 AS [C1] FROM (SELECT 1 AS X) AS [SingleRowTable9]) AS [UnionAll8] UNION ALL SELECT 20 AS [C1] FROM (SELECT 1 AS X) AS [SingleRowTable10]) AS [UnionAll9] ON [Extent1].[Id] = [UnionAll9].[C1] </code></pre> <p>NHibernate:</p> <pre><code>select nhfruit0_.Id as Id0_, nhfruit0_.Name as Name0_ from Fruit nhfruit0_ where nhfruit0_.Id in (2 /* @p0 */,4 /* @p1 */,6 /* @p2 */,8 /* @p3 */, 10 /* @p4 */,12 /* @p5 */,14 /* @p6 */,16 /* @p7 */, 18 /* @p8 */,20 /* @p9 */) </code></pre> <p>Now if you run with the execution plans, (I pressed execute 10 times before taking this screenshot)</p> <p><img src="/images/nhibernate-workaround-4.png" alt="" /></p> <p>The more parameters you add, the slower it gets.</p> <p>You can&rsquo;t blame Entity Framework though. EF supports the same query as NHibernate!</p> <pre><code>var fruitIds = new List&lt;int&gt; { 2, 4, 6, 8, 10, 12, 14, 16, 18, 20 }; using (var ctx = new EFTestEntities()) { var result = from f in ctx.Fruits where fruitIds.Contains(f.Id) select f; foreach (var fruit in result) Console.WriteLine(fruit.Name); } </code></pre> <p>Entity Framework generates the following query:</p> <pre><code>SELECT [Extent1].[Id] AS [Id], [Extent1].[Name] AS [Name] FROM [dbo].[Fruit] AS [Extent1] WHERE [Extent1].[Id] IN (2,4,6,8, 10,12,14,16, 18,20) </code></pre> <p>So I personally think the original approach, to do a join on an in-memory list, is bad practice, regardless of weather it works or not. It&rsquo;s bad.</p> <p>It&rsquo;s also bad to blindly write LINQ queries without ever looking at the SQL they produce. Sure it&rsquo;s great to not have to worry about writing SQL, but you should still always be aware of the SQL that is been run, sometimes slightly changing the LINQ can massively alter the SQL that is produced.</p> MVC Routing with Attributes makes routing awesome 2011-08-09T00:00:00-07:00 http://www.philliphaydon.com/2011/08/mvc-routing-with-attributes-makes-routing-awesome/ <p>I evaluated HEAPS of code/libraries and threw in the towel and decided that getting lower-case routes, while still having Area&rsquo;s, was a complete and utter waste of time and effort because they were all crappy, and broke stuff, or didn&rsquo;t work.</p> <p>That was until my mate Brad grabbed <a href="https://github.com/mccalltd/AttributeRouting">AttributeRouting</a> from <a href="http://nuget.org/List/Packages/AttributeRouting">Nuget</a>. Oh well you know what, this is the best thing sliced bread.</p> <p>First and foremost, it solved the number 1 issue I had with routing, lowercase Urls. This is how simple is it to make Routes lowercase.</p> <pre><code>routes.MapAttributeRoutes(config =&gt; { config.UseLowercaseRoutes = true; }); </code></pre> <p>Wow&hellip; Yet you bing for lowercase routes, and you end up with strange solutions&hellip; Here&rsquo;s a couple.</p> <p><a href="http://stackoverflow.com/questions/878578/how-can-i-have-lowercase-routes-in-asp-net-mvc">http://stackoverflow.com/questions/878578/how-can-i-have-lowercase-routes-in-asp-net-mvc</a></p> <p>This question links to:</p> <p><a href="http://coderjournal.com/2008/03/force-mvc-route-url-lowercase/">http://coderjournal.com/2008/03/force-mvc-route-url-lowercase/</a></p> <p>This breaks Area&rsquo;s, why? Because to handle an Area it appends <code>?Area=areaname</code> to the Url. FAIL. Probably worked great for MVC 1,but considering I&rsquo;ve seen it linked in MVC 3 questions,I consider it fail.</p> <!--excerpt--> <p><a href="http://stackoverflow.com/questions/878578/how-can-i-have-lowercase-routes-in-asp-net-mvc/1731652#1731652">http://stackoverflow.com/questions/878578/how-can-i-have-lowercase-routes-in-asp-net-mvc/1731652#1731652</a></p> <p>Writing them in lowercase? Really?</p> <p>Pass, I&rsquo;ll stick with AR, it&rsquo;s too simple, it&rsquo;s ridiculously simple. I love it!</p> <p>The next thing I love, is that instead of writing Routes, and then writing <code>HttpGet</code> <code>HttpPost</code> on all the actions, I just have to write <code>GET</code> and <code>POST</code> on the actions, and even define the URL along with it, and bam, it&rsquo;s clear and explicit how you get to that action.</p> <p>Such as:</p> <pre><code>[POST("Auth/Login")] public ActionResult Login(LoginViewModel loginViewModel, string returnUrl) </code></pre> <p>It&rsquo;s obvious to me, that I can access this Action by navigating to www.mysite.com/auth/login</p> <pre><code>[GET("Content/{slug}")] public ActionResult Index(string slug) </code></pre> <p>Page content can be accessed via www.mysite.com/content/my-slug</p> <p>And when controllers are divided into Area&rsquo;s, I can just define the area with the controller class:</p> <pre><code>[RouteArea("Admin")] public class HomeController : BaseController </code></pre> <p>I could define the namespace to use for Area&rsquo;s in the Area Registration, but it just seems&hellip; hacky&hellip; AR is definitely worth checking out.</p> Fluent NHibernate - Table Inheritance - Discriminators 2011-08-08T00:00:00-07:00 http://www.philliphaydon.com/2011/08/fluent-nhibernate-table-inheritance-discriminators/ <p>So a long time ago <a href="http://jameskovacs.com/">James Kovacs</a> posted a article about <a href="http://nhforge.org/blogs/nhibernate/archive/2011/02/16/get-load-polymorphism-in-nhibernate-3.aspx">get/load polymorphism</a> with NHibernate, which was cool and all but I always wanted to know how to map it all in Fluent NHibernate. I worked it out at the time but I guess it&rsquo;s taken me 7 months to write it down.</p> <p>First up is using a single table, mapping them to multiple classes, this is done using a discriminator. Fluent NHibernate calls this &lsquo;table-per-class-hierarchy strategy&rsquo;, which doesn&rsquo;t make sense to me. But meh.</p> <p>So I&rsquo;m going to begin with the following classes to demonstrate this:</p> <p><img src="/images/fnh-descrim-1.png" alt="" /></p> <p>So if I was to select all WallPost&rsquo;s it would give me instances of LinkShare, and Text wall posts.</p> <p>These classes are really basic at the moment.</p> <pre><code>public class WallPost { public virtual Guid Id { get; set; } public virtual DateTime DatePosted { get; set; } public virtual string Title { get; set; } public virtual string Content { get; set; } } public class TextWallPost : WallPost { } public class LinkShareWallPost : WallPost { } </code></pre> <!--excerpt--> <p>First we map the Wall Post:</p> <pre><code>public class WallPostMap : ClassMap&lt;WallPost&gt; { public WallPostMap() { Table("WallPost"); Id(x =&gt; x.Id).GeneratedBy.GuidComb(); DiscriminateSubClassesOnColumn("PostType"); Map(x =&gt; x.DatePosted); Map(x =&gt; x.Title); Map(x =&gt; x.Content); } } </code></pre> <p>As you see, there is a &lsquo;DescriminateSubClassesOnColumn&rsquo; method which specifies a column. This is what NHibernate uses to figure out which type of Sub Class to create.</p> <p>Next we need to map the Sub Classes.</p> <pre><code>public class TextWallPostMap : SubclassMap&lt;TextWallPost&gt; { public TextWallPostMap() { DiscriminatorValue(1); } } public class LinkShareWallPostMap : SubclassMap&lt;LinkShareWallPost&gt; { public LinkShareWallPostMap() { DiscriminatorValue(2); } } </code></pre> <p>Here I have specified the Discriminator Value for each sub class. If I save a TextWallPost, it will save the value &lsquo;1&rsquo; to the column &lsquo;PostType&rsquo;. Then when it pulls it from the database, it uses this value to decide the SubClass to create.</p> <p>The generated table looks like:</p> <p><img src="/images/fnh-descrim-2.png" alt="" /></p> <p>Now if I insert a couple of posts:</p> <pre><code>using (var tx = session.BeginTransaction()) { var wallPost = new TextWallPost { DatePosted = DateTime.Now, Title = "My First Wall Post", Content = "Is Awesome!" }; var linkPost = new LinkShareWallPost() { DatePosted = DateTime.Now, Title = "My First Link Share", Content = "Is Awesome!" }; session.Save(wallPost); session.Save(linkPost); tx.Commit(); } </code></pre> <p>I&rsquo;ve done nothing more than create instances of the classes I want, and commit them to the database, the SQL that is generated looks like:</p> <p><img src="/images/fnh-descrim-3.png" alt="" /></p> <p>So when it generates the SQL it puts the discriminator value in for us.</p> <p>If I select all &lsquo;WallPost&rsquo; from the database:</p> <pre><code>var result = session.QueryOver&lt;WallPost&gt;().List(); foreach (var wallPost in result) { Console.WriteLine(wallPost.Title); } </code></pre> <p>It just does a normal select:</p> <p><img src="/images/fnh-descrim-4.png" alt="" /></p> <p>Nice right? What&rsquo;s cool is if we look at the list of results we get, we get instances of WallPost, and instances of LinkShareWallPost back:</p> <p><img src="/images/fnh-descrim-5.png" alt="" /></p> <p>Now suppose we wanted to select JUST Link Shares.</p> <pre><code>var result = session.QueryOver&lt;LinkShareWallPost&gt;().List(); foreach (var wallPost in result) { Console.WriteLine(wallPost.Title); } </code></pre> <p>NHibernate will actually write the query to select only WallPosts that specify the Discriminator type defined in our Sub Class mapping.</p> <p><img src="/images/fnh-descrim-6.png" alt="" /></p> <p>So if we look at the results in VS:</p> <p><img src="/images/fnh-descrim-7.png" alt="" /></p> <p>Very nice stuff indeed.</p> <p>There&rsquo;s future posts on this stuff to come :)</p> MVC +Areas + Routes... Order of Routes Matter! 2011-07-27T00:00:00-07:00 http://www.philliphaydon.com/2011/07/mvc-areas-routes-order-of-routes-matter/ <p>The order in which routes are registered, really is pretty damn important, otherwise it can have really strange side-effects.</p> <p>I have a site, which has 3 areas, and no default&hellip; &lsquo;non-area&rsquo;.</p> <ul> <li>Admin</li> <li>Members</li> <li>Site</li> </ul> <p>So rather than having the structure:</p> <p><img src="/images/mvc-routes-1.png" alt="" /></p> <p>Where the root/default site is in the main directory, with two areas. I wanted this structure:</p> <p><img src="/images/mvc-routes-2.png" alt="" /></p> <p>So no root/default, and just a &lsquo;Site&rsquo; area which would be the default.</p> <p><span class="note"><strong>Note:</strong>The default route is removed from Global.asax&hellip; for now</span></p> <!--excerpt--> <p>This works perfectly fine if all the URL&rsquo;s are accessed like:</p> <pre><code>http://localhost:147/Site/Home/Index http://localhost:147/Admin/Home/Index http://localhost:147/Member/Home/Index </code></pre> <p>If we run this in a browser we get the following:</p> <p><img src="/images/mvc-routes-3.png" alt="" /></p> <p>These routes are registered automatically when you add an Area, in a <em>AreaName</em>AreaRegistration file.</p> <p><img src="/images/mvc-routes-4.png" alt="" /></p> <p>The routes generated look like the following:</p> <pre><code>namespace RoutingIssue.Areas.Members { public class MembersAreaRegistration : AreaRegistration { public override string AreaName { get { return "Members"; } } public override void RegisterArea(AreaRegistrationContext context) { context.MapRoute( "Members_default", "Members/{controller}/{action}/{id}", new { action = "Index", id = UrlParameter.Optional } ); } } } </code></pre> <p>But with different AreaName&rsquo;s of course. You get the idea.</p> <p>Now what we want to do is change the Site route, to work from the root directly like:</p> <pre><code>http://localhost:147/ </code></pre> <p>This is where my assumptions began to go wrong&hellip; I updated the route like so:</p> <pre><code>public override void RegisterArea(AreaRegistrationContext context) { context.MapRoute( "Site_default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); } </code></pre> <p>So I&rsquo;ve removed &lsquo;Site&rsquo; from the path, and added the default controller.</p> <p>This is where things started to get messy. At first, it worked, in my sample project. Then I added AutoFac, MiniProfiler, some Content, and a few other things. That&rsquo;s when it all went pear shaped.</p> <p><img src="/images/mvc-routes-5.png" alt="" /></p> <p>It seems to have lost the information about the routes for Admin/Member.</p> <p>Creating a new project with it working, and with my current project. I wrote some Trace.Write(&ldquo;AreaName&rdquo;) code into each AreaRegistration. The working project outputted:</p> <ul> <li>Members</li> <li>Admin</li> <li>Site</li> </ul> <p>However the second project, where it was failing, outputted:</p> <ul> <li>Site</li> <li>Members</li> <li>Admin</li> </ul> <p>So what&rsquo;s happening is in my project, it registers the default route first without the Area:</p> <pre><code>context.MapRoute( "Site_default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); </code></pre> <p>Took me hours to figure this out. That MVC cannot guarantee the order of which Area&rsquo;s are registered. The second two Area&rsquo;s didn&rsquo;t stand a chance.</p> <p>The solution was to move the Site route to the global.asax file, and specify an Area on it. My Site registration looks like:</p> <pre><code>public override void RegisterArea(AreaRegistrationContext context) { //context.MapRoute( // "Site_default", // "{controller}/{action}/{id}", // new { controller = "Home", action = "Index", id = UrlParameter.Optional } //); Trace.WriteLine("Site"); } </code></pre> <p>While my global.asax file has:</p> <pre><code>public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "default", "{controller}/{action}/{id}", new { controller = "Home", action = "Index", id = UrlParameter.Optional }, new string[] { "RoutingIssue.Areas.Site.Controllers" } ).DataTokens.Add("Area", "Site"); } </code></pre> <p>This means the default route is registered after my Areas, and everything works perfectly again :)</p> NServiceBus Video on dnrTV 2011-07-19T00:00:00-07:00 http://www.philliphaydon.com/2011/07/nservicebus-video-on-dnrtv/ <p>Good introduction video on dnrTV with Udi Dahan for getting started with NServiceBus.</p> <p>It&rsquo;s pretty recent too, June 23rd, 2011.</p> <blockquote><p><strong>Udi Dahan on NServiceBus</strong></p> <p>Udi Dahan shows you how to use the fabulous NServiceBus to provide reliable messaging using both a request/response and publish/subscribe architecture. He shows how much easier it is to use NServiceBus than to use WCF for reliable messaging.</p></blockquote> <p><a href="http://dnrtv.com/default.aspx?ShowID=202">http://dnrtv.com/default.aspx?ShowID=202</a></p> Getting Started - NServiceBus with Multiple Startup Projects 2011-07-11T00:00:00-07:00 http://www.philliphaydon.com/2011/07/getting-started-nservicebus-with-multiple-startup-projects/ <p>I never actually realized this, but one of the things that baffled me was how Udi Dahan, when giving his training, or when playing with the NServiceBus demo&rsquo;s&hellip; How multiple projected were started.</p> <p>It actually made implementing NServiceBus somewhat difficult for me to begin with, because I never knew Visual Studio had a feature to specify multiple projects as startup projects.</p> <p><img src="/images/getting-started-nservicebus-1.png" alt="" /></p> <p>If you right click a Solution and go to &lsquo;Properties&rsquo; you are presented with the above window.</p> <p>In &ldquo;Startup Project&rdquo; there&rsquo;s an option to select multiple projects, this solution which is a NServiceBus demo, shows 3 projects set to start.</p> <!--excerpt--> <p>Ahhh it all makes sense now. 7 years of using Visual Studio and I didn&rsquo;t know this feature existed. All this time I had being starting projects manually from the bin directories thinking &ldquo;there must be an easier way&rdquo;.</p> <p>Yet if I Googled &ldquo;visual studio multiple startup projects&rdquo; the first link is:</p> <p><a href="http://msdn.microsoft.com/en-us/library/ms165413(v=vs.80">How to: Set Multiple Startup Projects</a>.aspx)</p> <p>Ah we live and we learn :)</p> Hide & Show Buttons with Sencha Touch 2011-06-12T00:00:00-07:00 http://www.philliphaydon.com/2011/06/hide-show-buttons-with-sencha-touch/ <p>I&rsquo;m currently building a demo for work using <a href="http://www.sencha.com/products/touch/">Sencha Touch mobile JavaScript framework</a>, and needed to change the state of some buttons dependent on which &lsquo;card&rsquo; is shown.</p> <p>The Doc Api is a little hard to follow in my opinion, but I eventually worked it out.</p> <p>In hindsight I guess I could have used a single button to do this, but I will demonstrate it with two.</p> <p>To demonstrate this I&rsquo;m going to use a Panel, with the buttons to flick between the cards. Instead of using a TabPanel.</p> <p>So to start with I have a Panel, with a ToolBar docked to the bottom, a couple of buttons, and two cards.</p> <p><img src="/images/sencha-1.png" alt="" /></p> <pre><code>var rootPanel; Ext.setup({ onReady: function () { rootPanel = new Ext.Panel({ fullscreen: true, layout: 'card', style: 'background-color:lightblue;', dockedItems: [ { dock: 'bottom', xtype: 'toolbar', items: [ { html: 'Card 1 Button' }, { docked: 'right', html: 'Card 2 Button' } ] } ], items: [{ html: 'card 1' }, { html: 'card 2' }] }); } }); </code></pre> <!--excerpt--> <p>At the moment it&rsquo;s all nested, so the first thing I&rsquo;ll do is pull the toolbar items out, I&rsquo;ll also assign them to local variables and create them using the Ext.Button type. This gives us access to the methods and events for the buttons.</p> <pre><code>var btnCardOne = new Ext.Button({ html: 'Card 1 Button' }); var btnCardTwo = new Ext.Button({ docked: 'right', hidden: true, html: 'Card 2 Button' }); </code></pre> <p>items: [btnCardOne, btnCardTwo]</p> <p>You will notice I also set the second button&rsquo;s state to be hidden.</p> <p><img src="/images/sencha-2.png" alt="" /></p> <p>So we still have the same screen, less one button.</p> <p>Next we want to add an event to the button, like so:</p> <pre><code>var btnCardOne = new Ext.Button({ html: 'Card 1 Button', handler: function () { rootPanel.setActiveItem(1, { type: 'slide' }); btnCardOne.setVisible(false); btnCardTwo.setVisible(true); } }); var btnCardTwo = new Ext.Button({ docked: 'right', hidden: true, html: 'Card 2 Button', handler: function () { rootPanel.setActiveItem(0, { type: 'slide' }); btnCardOne.setVisible(true); btnCardTwo.setVisible(false); } }); </code></pre> <p>Because the buttons are just local variables we can access them in each event, so in the first button, we want to set the active item (card) to 1, turn off button one, and turn on button two.</p> <p>Then in the second button, we do the opposite. Now clicking each button flicks between the two.</p> <p><img src="/images/sencha-3.png" alt="" /> <img src="/images/sencha-4.png" alt="" /></p> Joining the Windows Phone 7 Club 2011-06-10T00:00:00-07:00 http://www.philliphaydon.com/2011/06/joining-the-windows-phone-7-club/ <p>Yesterday, my new Windows Phone 7 arrived. I ordered a HTC HD7 from eBay, since it&rsquo;s like $350 cheaper than buying it from an Australian retailer. Not only that it seems carriers aren&rsquo;t supporting WP7 too much yet, as two shopped that I enquired about the phone, both tried to talk me out of getting a WP7.</p> <p><img src="/images/windows-phone-club-1.png" alt="" /> <img src="/images/windows-phone-club-2.png" alt="" /></p> <p>(Photos from <a href="http://www.gsmarena.com/htc_hd7-pictures-3338.php">http://www.gsmarena.com/htc_hd7-pictures-3338.php</a>)</p> <p>It&rsquo;s definitely far superior to my iPhone4, after spending a night playing around with it, pretty much everything is better, in my opinion. (I will NEVER hand over money for an Apple product ever again.)</p> <p>The one flaw that Windows Phone 7 does have, is it&rsquo;s contact. Microsoft really dropped the ball on the contact, or &lsquo;People&rsquo; as they call them. The idea is great, but it lacks the ability to sync contact with outlook with ease. Contact&rsquo;s are synced to&hellip; everything else.</p> <!--excerpt--> <p>At first I thought outlook contact&rsquo;s could only be synced with exchange, but it turns out you can do it&hellip; but you need to sync your contacts to your windows live account,and then to your phone. <a href="http://support.microsoft.com/kb/2454811#21method">http://support.microsoft.com/kb/2454811#21method</a></p> <p>Google Mail contact&rsquo;s is a pain to sync to since it has a habit of adding people to &lsquo;My Contact&rsquo; without asking, and Facebook contacts are included when they don&rsquo;t even include contact details like a mobile number, or email. Which means if you have a lot of friends &lsquo;random people&rsquo; on your friends list, your &lsquo;People&rsquo; section becomes bloated.</p> <p>The other thing that&rsquo;s rather annoying about contact&rsquo;s is they aren&rsquo;t filtered for certain applications. If I create an email, and add a contact. It shows all contacts and not contacts that have an email.</p> <p>Or if I create a call, or text, it doesn&rsquo;t filter contacts to only those who have a mobile/telephone number.</p> <p>I&rsquo;ll get over the usability issues around &lsquo;People&rsquo; but for now I find it annoying.</p> <p>Time to break out the WP7 Developer Tools!</p> Refactoring those static method calls for testability! 2011-05-27T00:00:00-07:00 http://www.philliphaydon.com/2011/05/refactoring-those-static-method-calls-for-testability/ <p>One thing I love about working on a legacy application is the weird things I get to problem solve.</p> <p>A lot of the old system has an awful lot of static method calls, which doesn&rsquo;t leave much to be desired for when it comes to unit testing. I was working on a piece of the system today which is written in .NET 2.0, and is tightly coupled to everything in existence.</p> <p>I didn&rsquo;t want to go introduce interfaces and wrapper classes in order to abstract out all the dependencies, but I wanted to unit test the work without having to touch the database, which is what these static method calls were doing.</p> <p>The code I dealt with was something along the lines of&hellip;</p> <pre><code>public class ProductService { public static void Save(Product product) { throw new Exception("This would normally touch a db..."); } } </code></pre> <p><em>(Example is completely made up for this blog post and isn&rsquo;t actual code from work)</em></p> <!--excerpt--> <p>The class that calls this is along the lines of&hellip;</p> <pre><code>public class SomeService { public void DoSomething(User user, Product product) { //Do a bunch of stuff... if (user.IsVip) product.Price *= 0.90; ProductService.Save(product); //Do some more stuff... } } </code></pre> <p>So there&rsquo;s a direct call to the static method &lsquo;Save&rsquo;, now unit testing this class, like&hellip;</p> <pre><code>[TestMethod] public void Test() { //Arrange SomeService serviceUnderTest = new SomeService(); User user = new User(); user.IsVip = true; Product product = new Product(); product.Price = 5.00d; //Act serviceUnderTest.DoSomething(user, product); //Assert Assert.AreEqual(4.5d, product.Price); } </code></pre> <p>Running the test I would like to expect a result of &lsquo;4.5&rsquo; for the price, but what I get is the exception thrown from the ProductService.</p> <p>The solution, that didn&rsquo;t involve interfaces, a wrapper around the service, etc.</p> <pre><code>public class SomeService { internal delegate void ProductServiceDelegate (Product product); private ProductServiceDelegate _productServiceDelegate; internal ProductServiceDelegate ProductServiceSave { get { if (_productServiceDelegate == null) _productServiceDelegate = ProductService.Save; return _productServiceDelegate; } set { _productServiceDelegate = value; } } public void DoSomething(User user, Product product) { //Do a bunch of stuff... if (user.IsVip) product.Price *= 0.90; ProductServiceSave(product); //Do some more stuff... } } </code></pre> <p>So what I&rsquo;ve done is introduce a delegate for the ProductService&rsquo;s &lsquo;Save&rsquo; method, and made it internal with &lsquo;InternalsVisibleTo&rsquo; on the AssemblyInfo file so that unit testing project can see it.</p> <p>Now I can update the unit test with:</p> <pre><code>[TestMethod] public void TestMethod1() { SomeService serviceUnderTest = new SomeService(); User user = new User(); user.IsVip = true; Product product = new Product(); product.Price = 5.00d; serviceUnderTest.ProductServiceSave = new SomeService.ProductServiceDelegate( delegate(Product productParam) { productParam.Id = 1; }); serviceUnderTest.DoSomething(user, product); Assert.AreEqual(4.5d, product.Price); Assert.AreEqual(1, product.Id); } </code></pre> <p>So on the class under test I add a test method to the property which just sets the Id of the product to &lsquo;1&rsquo;, to simulate that the product was saved, and now I don&rsquo;t have to worry about the dependency on the ProductService class anymore.</p> NHibernate Querying for Max value 2011-05-17T00:00:00-07:00 http://www.philliphaydon.com/2011/05/nhibernate-querying-for-max-value/ <p>Browsing the net today for something to do with Fluent NHibernate I came across a blog post.</p> <p><a href="http://frankmao.com/2011/01/14/nhibernate-subquery/">http://frankmao.com/2011/01/14/nhibernate-subquery/</a></p> <p>The blog post is to do with Subquery, but I got a little bit confused since the post itself doesn&rsquo;t have anything to do with Subqueries.</p> <p>About the actual post tho, NHibernate.Linq does actually support Min/Max operators.</p> <p>Infact I just wrote a quick test to see the SQL it generated, the following code:</p> <pre><code>var result = session.Linq&lt;TestProduct&gt;().Max(x =&gt; x.Value); </code></pre> <p>Generates the following SQL.</p> <pre><code>SELECT max(this_.Value) as y0_ FROM [TestProduct] this_ </code></pre> <p>NHibernate.Linq has basically been deprecated however since NH3.0 has it&rsquo;s own built in Linq provider, rewriting that query in NH3.0 would look like:</p> <pre><code>var result = session.Query&lt;BaseClass&gt;().Max(x =&gt; x.Id); </code></pre> NServiceBus Templates 2011-05-12T00:00:00-07:00 http://www.philliphaydon.com/2011/05/nservicebus-templates/ <p>For anyone whose interested, the Visual Studio Gallery has some templates for NServiceBus.</p> <p><a href="http://visualstudiogallery.msdn.microsoft.com/9546d382-7ffa-4fb8-8c0f-b7825d5fd085">http://visualstudiogallery.msdn.microsoft.com/9546d382-7ffa-4fb8-8c0f-b7825d5fd085</a></p> <hr /> <p>NServiceBus Templates includes project and item templates for those building solutions upon NServiceBus.</p> <p><strong>Project Templates</strong></p> <ul> <li>Client Endpoint &ndash; defines a project that performs as a client</li> <li>Server Endpoint &ndash; defines a project that performs as a server</li> <li>Publisher Endpoint &ndash; defines a project that performs as a publisher</li> </ul> <p><strong>Item Templates</strong></p> <ul> <li>Message Handler &ndash; default implementation of the IHandleMessages<T> interface</li> <li>EndpointConfig &ndash; default implementation of developer endpoint configuration</li> </ul> <!--excerpt--> <p><strong>Instructions</strong></p> <ul> <li>Project templates include a custom wizard that will prompt for a directory. This directory should be the path to your NServiceBus assemblies and the generic host. Select the directory and hit &ldquo;Finish&rdquo; to complete the project.</li> </ul> <p><strong>Futures</strong></p> <ul> <li>Distributor Endpoint</li> <li>Worker Endpoint</li> <li>Complete Solutions <ul> <li>Pub/Sub</li> <li>Request/Response</li> <li>Client/Server</li> <li>Distributor/Worker</li> </ul> </li> </ul> Finding the correct Process Id for a website for DotTrace 2011-04-28T00:00:00-07:00 http://www.philliphaydon.com/2011/04/finding-the-correct-process-id-for-a-website-for-dottrace/ <p>Finding which process belonged to which application pool was simple in IIS6, it was a simple case of running up a Command Prompt and typing in <code>iisapp.vbs</code>.</p> <p>Unfortunately the script wasn&rsquo;t bought across to IIS7. So when it came to profiling a site I was baffled as to why the DotTrace results were showing information for threads completely unrelated to the website I was looking at.</p> <p>Turns out I was looking at the wrong Process Id&hellip;</p> <p><img src="/images/process-1.png" alt="" /></p> <p>So I needed to figure out which Process Id belonged to which site.</p> <!--excerpt--> <p>IIS7 ships with a little command line tool called <code>AppCmd</code>. Which is handy, simply open up a Command Prompt and navigate to:</p> <pre><code>C:\Windows\System32\inetsrv&gt; </code></pre> <p>Then type in the command:</p> <pre><code>appcmd list wp </code></pre> <p>This will list out all the sites and their Process Id:</p> <p><img src="/images/process-2.png" alt="" /></p> <p>Problem solved!</p> <p>More information about the tool can be found here:</p> <p><a href="http://learn.iis.net/page.aspx/114/getting-started-with-appcmdexe/">http://learn.iis.net/page.aspx/114/getting-started-with-appcmdexe/</a></p> jQuery Templating - Nested Collections 2011-04-23T00:00:00-07:00 http://www.philliphaydon.com/2011/04/jquery-templating-nested-arrays/ <p>Was asked me a couple of weeks ago if it was possible to have nested collections in a jQuery template. Well you can! The sample code kind of buries the ability since it tries to demonstrate too many things at once. But it&rsquo;s rather simple.</p> <pre><code>{{each *array*}} *stuff* {{/each}} </code></pre> <p>So assuming we have a simple json object like&hellip;</p> <pre><code>var people = [ { firstName: "James", favouriteColours: [ { colorName: "green" }, { colorName: "red" } ] }, { firstName: "Jack", favouriteColours: [ { colorName: "blue" }, { colorName: "red" } ] }, { firstName: "Jim", favouriteColours: [ { colorName: "blue" }, { colorName: "black" }, { colorName: "white" } ] } ]; </code></pre> <p>We can iterate over the people and then their favourite colours by using <code>each</code> in the template like so:</p> <!--excerpt--> <pre><code>&lt;script id="sample" type="text/x-jquery-tmpl"&gt; Name: ${firstName} &lt;br /&gt; Colours: {{each favouriteColours}} ${this.colorName} {{/each}} &lt;hr /&gt; &lt;/script&gt; </code></pre> <p>You&rsquo;re not limited to 1 level of collections, if you had many levels you can have an <code>each</code> inside an <code>each</code>&hellip; inside an <code>each</code>. But that would be getting silly.</p> NHibernate - Querying relationships at depth! 2011-04-13T00:00:00-07:00 http://www.philliphaydon.com/2011/04/nhibernate-querying-relationships-are-depth/ <p>The title may be a bit leading, this isn&rsquo;t about querying one-to-many-to-many, that is simply not possible. Well it may be possible, but it&rsquo;s not practical by any means.</p> <p>It&rsquo;s not practical because when querying for one-to-many you end up with a cartesian product. With a one-to-many it&rsquo;s easy to transform the data knowing the root is a single result while the relationship is a collection of all the results.</p> <p>If you have a many-to-many it works too since it&rsquo;s the distinct root and the relating collection of all results for a single root item.</p> <p>But to select a one-to-many-to-many it&rsquo;s far too complicated to work out what the hell is going on. Well in my opinion it&rsquo;s far too complicated.</p> <!--excerpt--> <p>However if you have a one-to-many-to-one, so three levels deep&hellip; Lets say&hellip; A blog, with many posts, each with an author.</p> <p><img src="/images/nhibernate-depth-1.png" alt="" /></p> <p>We can query the 3rd level with the posts relatively easily.</p> <p>If we take a relatively simple query, to fetch a blog with posts and display the title/author like so:</p> <pre><code>var sessionFactory = new SessionFactoryManager().CreateSessionFactory(); Blog blog = null; using (var session = sessionFactory.OpenSession()) { blog = session.QueryOver&lt;Blog&gt;() .Where(x =&gt; x.Id == 1) .Fetch(x =&gt; x.Posts).Eager .SingleOrDefault(); Console.WriteLine(blog.Name); Console.WriteLine("--"); foreach (var post in blog.Posts) { Console.WriteLine("Title: " + post.Title); Console.WriteLine("Author: " + post.Author.FirstName); Console.WriteLine("--"); } } </code></pre> <p>We can eager load the posts&hellip;</p> <p><img src="/images/nhibernate-depth-2.png" alt="" /></p> <p>No problems. Except when we grab the Author, we end up with a select+n scenario&hellip;</p> <p><img src="/images/nhibernate-depth-3.png" alt="" /></p> <p>This is bad bad bad! So the idea would be to eager load the Author with the post, the problem is .Fetch() doesn&rsquo;t allow you to specify a property of a collection&hellip;</p> <p>That&rsquo;s where &lsquo;JoinAlias&rsquo; comes in handy, I assume this stuff comes from HQL/Criteria, but I prefer not to use that stuff.</p> <p>Instead of using &lsquo;Fetch&rsquo; we are going to replace it with a &lsquo;JoinAlias&rsquo; like so:</p> <pre><code>Post posts = null; Author author = null; blog = session.QueryOver&lt;Blog&gt;() .Where(x =&gt; x.Id == 1) .JoinAlias(x =&gt; x.Posts, () =&gt; posts) .JoinAlias(() =&gt; posts.Author, () =&gt; author) .SingleOrDefault(); </code></pre> <p>Opps&hellip;</p> <p><img src="/images/nhibernate-depth-4.png" alt="" /></p> <p>It&rsquo;s executed two queries, the first query looks fine&hellip;</p> <p><img src="/images/nhibernate-depth-5.png" alt="" /></p> <p>The data returned is correct too, except NH doesn&rsquo;t seem to think so, it actually queries for the Posts a second time.</p> <p>However, updating the query to specify a join type:</p> <pre><code>Post posts = null; Author author = null; blog = session.QueryOver&lt;Blog&gt;() .Where(x =&gt; x.Id == 1) .JoinAlias(x =&gt; x.Posts, () =&gt; posts, JoinType.LeftOuterJoin) .JoinAlias(() =&gt; posts.Author, () =&gt; author) .SingleOrDefault(); </code></pre> <p>We end up with a single query, with all the correct results.</p> <p><img src="/images/nhibernate-depth-6.png" alt="" /></p> <p><img src="/images/nhibernate-depth-7.png" alt="" /></p> Installing MongoDB Service with logs 2011-04-12T00:00:00-07:00 http://www.philliphaydon.com/2011/04/installing-mongodb-service-with-logs/ <p>Just tried to install MongoDB as a service on Windows 7, but came up with issues trying to specify where to store the logs&hellip;</p> <p><a href="http://www.mongodb.org/display/DOCS/Windows+Service">http://www.mongodb.org/display/DOCS/Windows+Service</a></p> <p>The example on the website shows a directory path, but when you look at the help in the command windows it says:</p> <p><img src="/images/mongodb-install-1.png" alt="" /></p> <blockquote><p>all output going to: c:mongodblogs logpath [c:mongodblogs] should be a file name not a directory</p></blockquote> <p>I&rsquo;m not sure why, maybe the documentation isn&rsquo;t up to date, but specifying a physical file, like &lsquo;log.txt&rsquo; the service installs fine.</p> Career Starting Salary 2011-03-28T00:00:00-07:00 http://www.philliphaydon.com/2011/03/career-starting-salary/ <p>Every now-n-then I read threads on forums to do with pay &amp; salary in the IT industry, and it always frustrates me when I come across posts where people are whinging about junior / no experience jobs being offered for &lsquo;low pay&rsquo;.</p> <p>The latest thread can be seen here: <a href="http://forums.whirlpool.net.au/forum-replies.cfm?t=1657193">http://forums.whirlpool.net.au/forum-replies.cfm?t=1657193</a></p> <p>In the thread the original poster was complaining about a job ad being advertised at 35-40k, for a grad position. It seems that a lot of people agree with him. Some of the comments are:</p> <blockquote><p>35k is shockingly low. You could walk out and get an office job with no training and no stress for that amount. As a grad you will have to be learning things in your spare time etc.</p></blockquote> <!-- --> <blockquote><p>In IT you need to be good to get good money. If that&rsquo;s not you then change your career, plenty of industries where you get good money even if you are just average or worse&hellip;</p></blockquote> <!-- --> <blockquote><p>I still think it&rsquo;s dangerous practice to offer an absolutely disgraceful salary like $35k to gradutes</p></blockquote> <!-- --> <blockquote><p>35k is a a stupid sallary for a new Grad in this day and age. Heck, as a grad I would even consider 50k too low. Good luck trying to fill that role !!</p></blockquote> <!--excerpt--> <p>And one of my favourites:</p> <blockquote><p>$35k is terrible&hellip; what&rsquo;s the point of going to uni and graduating with a degree if 35k is all you get&hellip; u might as well get a basic admin job that pays $40-50k&hellip;</p></blockquote> <p>That&rsquo;s just a few of the comments from the first 4 pages of 19+ pages.</p> <p>I don&rsquo;t understand how people find this low, I don&rsquo;t know how things work in America, but in Australia and New Zealand a grad student in IT simply cannot expect to work out of Uni and into a 100k job.</p> <p>When I started working about 7 years ago at 18, I started on 35k. (for the record I never went to university, I did a couple of diplomas then started working).</p> <p>I was discussing this with a good friend of mine, last night and he told me he started on $10.30/hr (about 21k), without asking him I bet he would say it was worth it, he&rsquo;s very experienced and works for a great company.</p> <p>I just don&rsquo;t think grad students or &lsquo;tafe&rsquo; (as it&rsquo;s called in Australia) have the knowledge to sit down at a desk and cut code, you need to mentor them and hold their hand.</p> <p>That&rsquo;s not to say ALL grad/tafe students need to have their hand held, you may end up with someone like Mark Zuckerberg, but those types of people are different, Mark was doing programming in the 90&rsquo;s when his father taught him BASIC.</p> <p>I think the problem stems from the fact a lot of people get into programming because they think it&rsquo;s easy money, sure with ~10 years experience and good references you can get 100k+, but you just don&rsquo;t walk out of Uni or Tafe into that sort of money. Programming is more of a hobby than a career, it&rsquo;s something you do because your passionate about it, not because you want to get paid lots. After you&rsquo;ve been in the industry for&hellip; 15+ years? Then you can worry about being paid lots, but prior to that, should be happy you&rsquo;re doing something you love.</p> <p>I think 35k is justified because it actually costs the company you&rsquo;re working for, to mentor you, and hold your hand for at-least the first year of your career.</p> <p>After a year it&rsquo;s easy to move up the food chain, that first year is the hardest to find a job, and I think it&rsquo;s selfish to whinge for low pay, when an employer can&rsquo;t rely on you to get a task done without asking a billion questions.</p> <p>The excuse that you can get an admin job for 40-50k is silly, after a few years in such a role, you&rsquo;re still going to be doing the same old boring shit, at least as a programmer you&rsquo;re going to move up onto bigger and better projects, harder problems to solve, and what you seem to crave so much&hellip; more money.</p> <p>&lt;/rant></p> WP7 Nights at the Round Table - Feb 28 2011-02-19T00:00:00-08:00 http://www.philliphaydon.com/2011/02/wp7-nights-at-the-round-table-feb-28/ <p><a href="http://www.nickharris.net/2011/02/wp7-nights-at-the-round-table-feb-28/">http://www.nickharris.net/2011/02/wp7-nights-at-the-round-table-feb-28/</a></p> <p><strong>Event: </strong><br/> WP7 Nights at the Round Table &ndash; Feb 28th Sydney</p> <p><strong>Purpose: </strong><br/> Let&rsquo;s get together for some drinks to trade WP7 Dev stories, demos or seek free advice from other devs to help get your app off the ground and into Marketplace. This event will be informal, around bar tables, so bring along your device or laptop if you wish to show people what you have been up to.</p> <p><strong>Let us know your coming: </strong><br/> If your on LinkedIn please indicate your attendance here &ndash; <a href="http://events.linkedin.com/WP7-Nights-Round-Table-Feb-28th/pub/571016">http://events.linkedin.com/WP7-Nights-Round-Table-Feb-28th/pub/571016</a> or in the comments section below.</p> <p><strong>Date, Time, Location: </strong><br/> 6-8pm <br/> Tues 28th Feb 2010 <br/> City Hotel, <br/> Corner of King and Kent St, Sydney CBD.</p> Not.LazyLoad - Eager Loading with NHibernate 3.0 2011-01-30T00:00:00-08:00 http://www.philliphaydon.com/2011/01/not-lazyload-eager-loading-with-nhibernate-3-0/ <p>A friend asked me about fetching relationships with NHibernate when something couldn&rsquo;t be lazy-loaded.</p> <p>The reason it couldn&rsquo;t be lazy-loaded was because he uses Session-Per-Call, my preference is Session-Per-Request. (this is web based, I&rsquo;ve never actually used NHibernate in a non-web scenario, yet)</p> <p>The solution he&rsquo;s currently using is to turn off lazy-loading at the mapping. This is all kinds of bad.</p> <p>I think it&rsquo;s best to demonstrate why turning off lazy-loading at the mapping is bad. I&rsquo;ve come up with a, well what I consider pretty standard Blog.</p> <p><img src="/images/nhibernate-lazy-load-1.png" alt="" /></p> <p>Nothing special but needed something that has a few relationship"s. (I think you can click that image to make it bigger)</p> <!--excerpt--> <p>So as we can see, a Post has 4 relationships, and a Comment has a relationship back to the Post and User.</p> <p>I&rsquo;ve mapped it and created some test data:</p> <p><a href="/stuffz/NH-Blog-Mappings.cs.txt">View Full Maps</a></p> <p><a href="/stuffz/NH-Blog-Scripts.sql.txt">View SQL Script</a></p> <p>Right, so the maps are set to Not LazyLoad the relationships.</p> <h3>Post</h3> <pre><code>public class PostMap : ClassMap&lt;Post&gt; { public PostMap() { Id(x =&gt; x.Id); Map(x =&gt; x.Title); Map(x =&gt; x.Content); Map(x =&gt; x.PublishedAt); References(x =&gt; x.Author) .Column("UserId") .Not.LazyLoad(); HasManyToMany(x =&gt; x.Tags) .Table("PostTags") .ParentKeyColumn("PostId") .ChildKeyColumn("TagId") .Not.LazyLoad(); HasManyToMany(x =&gt; x.Categories) .Table("PostCategories") .ParentKeyColumn("PostId") .ChildKeyColumn("CategoryId") .Not.LazyLoad(); HasMany(x =&gt; x.Comments) .KeyColumn("PostId") .Inverse() .Not.LazyLoad(); } } </code></pre> <h3>Comment</h3> <pre><code>public class CommentMap : ClassMap&lt;Comment&gt; { public CommentMap() { Id(x =&gt; x.Id); Map(x =&gt; x.Content); References(x =&gt; x.Commenter) .Column("UserId") .Not.LazyLoad(); References(x =&gt; x.Post) .Column("PostId") .Not.LazyLoad(); } } </code></pre> <p>I haven&rsquo;t mapped any relationships the other way, keeping it simple, stupid.</p> <p>Right, so lets assume we wanted to load Post 1, and display the Title and the Categories the post was in. We didn&rsquo;t care about the User, or the Comments, or anything like that.</p> <pre><code>var sessionFactory = new SessionFactoryManager().CreateSessionFactory(); using (var session = sessionFactory.OpenSession()) { var post = session.Query&lt;Post&gt;() .SingleOrDefault(x =&gt; x.Id == 1); Console.WriteLine("Post: " + post.Title); Console.WriteLine("Category: "); post.Categories.ForEach(x =&gt; Console.WriteLine(x.Name)); } </code></pre> <p>If we were writing the query ourselves, all we would want is the Post, and the Categories, well because we mapped all the references and collections as Not.LazyLoad, NHibernate is kind enough to go and grab that information for us. The SQL Generated results in:</p> <p><img src="/images/nhibernate-lazy-load-2.png" alt="" /></p> <p>(Image is screen shot from <a href="http://www.nhprof.com/">NHProf</a>)</p> <p>AHHHHH Bad bad bad!!! It&rsquo;s loaded all that information we don&rsquo;t care about!</p> <p>Right, lets set everything back to normal, and leave Lazy Loading on! Run the same query, and see what happens.</p> <h3>Post</h3> <pre><code>public class PostMap : ClassMap&lt;Post&gt; { public PostMap() { Id(x =&gt; x.Id); Map(x =&gt; x.Title); Map(x =&gt; x.Content); Map(x =&gt; x.PublishedAt); References(x =&gt; x.Author) .Column("UserId"); HasManyToMany(x =&gt; x.Tags) .Table("PostTags") .ParentKeyColumn("PostId") .ChildKeyColumn("TagId"); HasManyToMany(x =&gt; x.Categories) .Table("PostCategories") .ParentKeyColumn("PostId") .ChildKeyColumn("CategoryId"); HasMany(x =&gt; x.Comments) .KeyColumn("PostId") .Inverse(); } } </code></pre> <h3>Comment</h3> <pre><code>public class CommentMap : ClassMap&lt;Comment&gt; { public CommentMap() { Id(x =&gt; x.Id); Map(x =&gt; x.Content); References(x =&gt; x.Commenter) .Column("UserId"); References(x =&gt; x.Post) .Column("PostId"); } } </code></pre> <p>Lets see what happens now.</p> <p><img src="/images/nhibernate-lazy-load-3.png" alt="" /></p> <p>Great! Much nicer, we haven&rsquo;t got all that information we didn&rsquo;t want. The only problem is, what about this scenario?</p> <pre><code>var sessionFactory = new SessionFactoryManager().CreateSessionFactory(); Post post; using (var session = sessionFactory.OpenSession()) { post = session.Query&lt;Post&gt;() .SingleOrDefault(x =&gt; x.Id == 1); Console.WriteLine("Post: " + post.Title); } Console.WriteLine("Category: "); post.Categories.ForEach(x =&gt; Console.WriteLine(x.Name)); </code></pre> <p>Lets assume that the &lsquo;using&rsquo; block was a call to a repository, to get a particular post, and we needed to iterate over the categories a little bit later?</p> <p><img src="/images/nhibernate-lazy-load-4.png" alt="" /></p> <p>Oh no, not what we wanted because the object is now disconnected from the session, it can&rsquo;t lazy load the categories. This I suspect is the issue my friend got.</p> <p>So the solution? To Eager Load!</p> <pre><code>Post post; using (var session = sessionFactory.OpenSession()) { post = session.Query&lt;Post&gt;() .Where(x =&gt; x.Id == 1) .Fetch(x =&gt; x.Categories) .SingleOrDefault(); Console.WriteLine("Post: " + post.Title); } Console.WriteLine("Category: "); post.Categories.ForEach(x =&gt; Console.WriteLine(x.Name)); </code></pre> <p>This results in a single query being issued:</p> <p><img src="/images/nhibernate-lazy-load-5.png" alt="" /></p> <p>What&rsquo;s this query look like?</p> <p><img src="/images/nhibernate-lazy-load-6.png" alt="" /></p> <p>Not bad! Definitely saves a second trip to the database to grab the categories. But there&rsquo;s a problem, there types of queries result in cartesian product result-set. (Think that&rsquo;s what it&rsquo;s called)</p> <p>If we issue that query our-self we end up with this:</p> <p><img src="/images/nhibernate-lazy-load-7.png" alt="" /></p> <p>We actually get Post back twice, because it&rsquo;s got two categories. It&rsquo;s only because we told NHibernate we wanted a single result that it knew the Root aggregate is distinct.</p> <p>So what happens if we wanted more than 1 post, and eager load the relationships?</p> <pre><code>var sessionFactory = new SessionFactoryManager().CreateSessionFactory(); IList&lt;Post&gt; posts; using (var session = sessionFactory.OpenSession()) { posts = session.QueryOver&lt;Post&gt;() .Fetch(x =&gt; x.Categories).Eager .List(); } foreach (var post in posts) { Console.WriteLine("Post: " + post.Title); Console.WriteLine("Categories:"); foreach (var category in post.Categories) { Console.WriteLine(" - " + category.Name); } Console.WriteLine("--"); } </code></pre> <p>Nothing special, right? Except&hellip; because we get duplicate posts in the last query, imagine what we get when we actually iterate over this result.</p> <pre><code>Post: Post 1 Categories: - Category 1 - Category 3 -- Post: Post 1 Categories: - Category 1 - Category 3 -- Post: Post 2 Categories: - Category 2 -- Post: Post 3 Categories: - Category 1 - Category 2 - Category 3 -- Post: Post 3 Categories: - Category 1 - Category 2 - Category 3 -- Post: Post 3 Categories: - Category 1 - Category 2 - Category 3 -- </code></pre> <p>Scary right? We can fix this using NH Transformations.</p> <pre><code>using (var session = sessionFactory.OpenSession()) { posts = session.QueryOver&lt;Post&gt;() .Fetch(x =&gt; x.Categories).Eager .TransformUsing(new DistinctRootEntityResultTransformer()) .List(); } </code></pre> <p>This formats the result to be distinct posts with the related Categories like so:</p> <pre><code>Post: Post 1 Categories: - Category 1 - Category 3 -- Post: Post 2 Categories: - Category 2 -- Post: Post 3 Categories: - Category 1 - Category 2 - Category 3 -- </code></pre> <p>Perfect!</p> <p>As you can imagine, eager loading is a pretty powerful feature, but we still have to be careful to not load too many relationships. Because eager loading doesn&rsquo;t break the relationships into different result-set queries, we can end up with inefficient queries because there are too many, or possibly too complex joins.</p> <p>We could over-come some of these BY we, Not.LazyLoadby creating the object graph ourselves by using NHibernates <code>Future&lt;T&gt;</code> feature, to batch queries together to reduce the number of database trips. That&rsquo;s a post for another day.</p> Let Keyword in ORMs 2011-01-29T00:00:00-08:00 http://www.philliphaydon.com/2011/01/let-keyword-in-orms/ <p>A while ago <a href="http://www.mindscapehq.com/">MindScape</a> posted a new feature called <a href="http://www.mindscapehq.com/blog/index.php/2010/09/14/ninja-domain-properties-in-lightspeed/">Ninja Properties</a> for their ORM, LightSpeed. Their post happened to be a scenario I used to solve with LINQ 2 SQL using the &lsquo;let&rsquo; keyword to create a composite type to query against.</p> <p>This would allow you to do something along the lines of:</p> <pre><code>var poo = from s in ctx.Members let fullname = s.FirstName + " " + s.LastName where fullname == "Robert Williams" select s; </code></pre> <p>This nifty query would generate SQL like so:</p> <pre><code>SELECT [t1].[Id], [t1].[FirstName], [t1].[LastName] FROM ( SELECT [t0].[Id], [t0].[FirstName], [t0].[LastName], ([t0].[FirstName] + ' ') + [t0].[LastName] AS [value] FROM [Member] AS [t0] ) AS [t1] WHERE [t1].[value] = 'Robert Williams' </code></pre> <p>After commenting in their blog post about it they implemented it and put it into the nightly build. So after some months I finally got around to testing it, for a couple of reasons. Back when NHibernate 3.0 was in Alpha, this technique didn&rsquo;t work! So I thought I would test it out and see if it does, as well as checkout the SQL that&rsquo;s generated.</p> <!--excerpt--> <p>I&rsquo;m using the following ORM&rsquo;s</p> <ul> <li>LightSpeed 3.11 Nightly Build (3.1 it doesn&rsquo;t work)</li> <li>NHibernate 3.0</li> <li>Linq 2 Sql</li> <li>Entity Framework 4</li> </ul> <p>The data model is simple, but I have two scenarios I want to test. I created a Member and Task. The Member has a One-to-Many with Tasks.The test data:</p> <pre><code>insert into member (firstname, lastname) values ('Robert', 'Williams') insert into member (firstname, lastname) values ('Michael', 'Jones') insert into member (firstname, lastname) values ('William', 'Brown') insert into member (firstname, lastname) values ('David', 'Davis') insert into member (firstname, lastname) values ('Richard', 'Miller') insert into member (firstname, lastname) values ('Charles', 'Wilson') insert into task (MemberId, Name) values(1, 'Task 1') insert into task (MemberId, Name) values(1, 'Task 2') insert into task (MemberId, Name) values(1, 'Task 3') insert into task (MemberId, Name) values(1, 'Task 4') insert into task (MemberId, Name) values(2, 'Task 1') insert into task (MemberId, Name) values(2, 'Task 2') insert into task (MemberId, Name) values(2, 'Task 3') insert into task (MemberId, Name) values(3, 'Task 4') </code></pre> <p><strong>Scenario 1:</strong> Find all Members where fullname contains &lsquo;w&rsquo;, case insensitive (lowercase the fullname)</p> <p><strong>Scenario 2:</strong> Find all Members who have more than 2 tasks.</p> <p><span class="note"><strong>Note:</strong> These tests are not to say one ORM is better than another, I did this purely out of curiosity and am sharing my results.</span></p> <h2>Scenario 1</h2> <p>I ran the same query against each ORM (to see the full script click here), the query is:</p> <pre><code>var poo = from s in ctx.Members let fullname = s.FirstName + " " + s.LastName where fullname.ToLower().Contains("w") select s; </code></pre> <p>All queries are identical with the exception of the &lsquo;in&rsquo; part, varying between ORMs.</p> <p>LightSpeed : <code>from s in uow.Members</code><br/> NHibernate 3.0 : <code>from s in session.Query&lt;NHibernate.Member&gt;()</code><br/> Linq 2 Sql : <code>from s in ctx.Members</code><br/> Entity Framework 4: <code>from s in mmc.Members</code></p> <p>The output was as follows:</p> <pre><code>---- LINQ 2 SQL Robert William Charles ---- LightSpeed Robert William Charles ---- NHibernate 3.0 Robert William Charles ---- EntityFramework 4 Robert William Charles </code></pre> <p>All ORM&rsquo;s worked perfectly. How about the SQL Generated from these?</p> <h3>Linq 2 SQL:</h3> <pre><code>SELECT [t1].[Id], [t1].[FirstName], [t1].[LastName] FROM ( SELECT [t0].[Id], [t0].[FirstName], [t0].[LastName], ([t0].[FirstName] + ' ') + [t0].[LastName] AS [value] FROM [Member] AS [t0] ) AS [t1] WHERE LOWER([t1].[value]) LIKE '%w%' </code></pre> <h3>LightSpeed:</h3> <pre><code>SELECT Member.Id AS [Member.Id], Member.FirstName AS [Member.FirstName], Member.LastName AS [Member.LastName] FROM Member WHERE LOWER(((Member.FirstName + ' ') + Member.LastName)) LIKE '%w%' </code></pre> <h3>NHibernate:</h3> <pre><code>select member0_.Id as Id0_, member0_.FirstName as FirstName0_, member0_.LastName as LastName0_ from [Member] member0_ where lower(member0_.FirstName+' '+member0_.LastName) like ('%'+'w'+'%') </code></pre> <h3>Entity Framework 4.0:</h3> <pre><code>SELECT [Extent1].[Id] AS [Id], [Extent1].[FirstName] AS [FirstName], [Extent1].[LastName] AS [LastName] FROM [dbo].[Member] AS [Extent1] WHERE LOWER([Extent1].[FirstName] + N' ' + [Extent1].[LastName]) LIKE N'%w%' </code></pre> <p>Note: The first 3 queries are RPC&rsquo;s and show in SQL Profiler with parameters, I&rsquo;ve stripped the parameters out to show the readable query.</p> <p>Great, so all 3 work fine. Tho I don&rsquo;t like the SQL generated by Linq 2 Sql. Hard to believe Stack Overflow runs off it.</p> <h2>Scenario 2</h2> <p>The second scenario is again, the exact same query, you could write this multiple ways, however I found it cleaner to use &lsquo;let&rsquo; back when I was using Linq 2 Sql. (to see the full script click here), the query is:</p> <pre><code>var poo = from s in ctx.Members let tasks = s.Tasks.COUNT() as Computed where tasks &gt; 2 select s; </code></pre> <p>Again, the only difference is the &lsquo;in&rsquo; part of the query.</p> <p>The output was as follows:</p> <pre><code>---- LINQ 2 SQL Robert Michael ---- LightSpeed Exception: Specified method is not supported. ---- NHibernate 3.0 Robert Michael ---- EntityFramework 4 Robert Michael </code></pre> <p>All achieved the same results, except for LightSpeed. However I didn&rsquo;t think NHibernate would support this?!? Seems they have done quite a bit of work implementing LINQ since Alpha.</p> <p>How about the SQL generated?</p> <h3>Linq 2 Sql:</h3> <pre><code>SELECT [t2].[Id], [t2].[FirstName], [t2].[LastName] FROM ( SELECT [t0].[Id], [t0].[FirstName], [t0].[LastName], ( SELECT COUNT(*) FROM [Task] AS [t1] WHERE [t1].[MemberId] = [t0].[Id] ) AS [value] FROM [Member] AS [t0] ) AS [t2] WHERE [t2].[value] &gt; 2 </code></pre> <h3>NHibernate:</h3> <pre><code>select member0_.Id as Id0_, member0_.FirstName as FirstName0_, member0_.LastName as LastName0_ from [Member] member0_ where (select cast(count(*) as INT) from [Task] tasks1_ where member0_.Id=tasks1_.MemberId) &gt; 2 </code></pre> <h3>Entity Framework:</h3> <pre><code>SELECT [Project1].[Id] AS [Id], [Project1].[FirstName] AS [FirstName], [Project1].[LastName] AS [LastName] FROM ( SELECT [Extent1].[Id] AS [Id], [Extent1].[FirstName] AS [FirstName], [Extent1].[LastName] AS [LastName], (SELECT COUNT(1) AS [A1] FROM [dbo].[Task] AS [Extent2] WHERE [Extent1].[Id] = [Extent2].[MemberId]) AS [C1] FROM [dbo].[Member] AS [Extent1] ) AS [Project1] WHERE [Project1].[C1] &gt; 2 </code></pre> <p>I get the feeling that NHibernate generates more efficient queries than L2S/EF. Might be worth doing some performance testing against them oneday. :)</p> <p>Anyway as you can see, &lsquo;let&rsquo; keyword allows you to create some nice queries that are easy to ready instead of trying to complicate things in your &lsquo;where&rsquo; clause, when writing LINQ.</p> Mindscape NHibernate Designer Discount 2011-01-21T00:00:00-08:00 http://www.philliphaydon.com/2011/01/mindscape-nhibernate-designer-discount/ <p>Mindscape have a 60% discount on their NHibernate Designer.</p> <p><a href="http://www.mindscapehq.com/blog/index.php/2011/01/20/60-off-nhibernate-designer-act-fast/">http://www.mindscapehq.com/blog/index.php/2011/01/20/60-off-nhibernate-designer-act-fast/</a></p> <blockquote><p>How to obtain this special When making your purchase please enter the following discount code: NHSPECIAL You should immediately see the price drop to $99, saving you $150 USD!</p></blockquote> <p>Great tool for anyone who hates writing XML or loves GUI&rsquo;s.</p> LightSpeed and Eager Loaded properties 2011-01-20T00:00:00-08:00 http://www.philliphaydon.com/2011/01/lightspeed-and-eager-loaded-properties/ <p>Today <a href="http://www.mindscapehq.com/">Mindscape</a>, the makers of the ORM <a href="http://www.mindscapehq.com/products/lightspeed">LightSpeed</a> and other awesome <a href="http://www.mindscapehq.com/products/">products</a> posted a blog on <a href="http://www.mindscapehq.com/blog/index.php/2011/01/19/controlling-lightspeed-entity-loading-with-named-aggregates/">Lazy-Loading/Eager-Loading properties</a> with LightSpeed.</p> <p>Why can&rsquo;t NHibernate do this! And when I say why can&rsquo;t NHibernate do this, I mean, why can&rsquo;t NHibernate do this with Query/QueryOver.</p> <p>Ayende detailed this time last year, the ability to <a href="http://ayende.com/Blog/archive/2010/01/27/nhibernate-new-feature-lazy-properties.aspx">lazy-load properties</a>, but currently Query/QueryOver only support One-To-Many and One-To-One relationships.</p> <p>NHibernate will support the ability to Lazy-Load a property but you can&rsquo;t specify it to be eager loaded.</p> <p>So you do</p> <pre><code>Map(x =&gt; x.FullDescription).CustomSqlType("NTEXT") .LazyLoad(); </code></pre> <p>Running a query would result in:</p> <p><img src="/images/lightspeed-1.png" alt="" /></p> <p>Great&hellip; But you currently cannot do:</p> <!--excerpt--> <pre><code>var video = session.QueryOver&lt;Video&gt;() .Fetch(x =&gt; x.FullDescription).Eager .List(); </code></pre> <p>This will execute, the exact same query.</p> <p>I do have one gripe with the way LightSpeed works tho, and that is that you have to give your aggregate as a string name, I really think they should give the ability to specify the property(ies) via a lambda.</p> <p>Without giving it a test drive, I feel if I changed the name of the aggregate and forgot to update everywhere it was referenced, I&rsquo;m going to end up with a maintenance nightmare.</p> <p>Anyway checkout LightSpeed, it&rsquo;s awesome, it&rsquo;s everything Entity Framework should have been.</p> <p><a href="http://www.mindscapehq.com/products/lightspeed">http://www.mindscapehq.com/products/lightspeed</a></p> Revisiting 'Exists' in NHibernate 3.0 and QueryOver 2011-01-19T00:00:00-08:00 http://www.philliphaydon.com/2011/01/revisiting-exists-in-nhibernate-3-0-and-queryover/ <p>A while ago I wrote about <a href="http://www.philliphaydon.com/2010/09/queryover-with-nhibernate-3-lovin-it/">my experience with NHibernate 3.0 and Query over</a> by having a go at converting an application to NH3.0, and faced the challenge of writing a query which contained an &lsquo;exists&rsquo; where clause. At the time my solution resulted in an &lsquo;in&rsquo; clause since I couldn&rsquo;t work out how to do an exists.</p> <p>Today at work I faced the same challenge, except this time I solved it WOO Yay for solving things.</p> <h2>The Problem</h2> <p>We have a many-to-many relationship between Jobs and Roles. Which looks something along the lines of:</p> <p><img src="/images/nhibernate-queryover-1.png" alt="" /></p> <p>I cut a bunch of stuff out but you get the idea.</p> <!--excerpt--> <p>So what was required was on the screen was all the Jobs, you expand the Jobs and it lists all the Roles for that Job, sweet. When you add a new Role, it brings up a Drop Down List with all the Roles that are not assigned to the Job.</p> <p>The existing query was along the lines of:</p> <pre><code>SELECT r.RoleId, r.Name, r.IsEnabled, r.RoleType FROM Role r WITH (NOLOCK) WHERE [IsEnabled] = 1 AND r.RoleId NOT IN (SELECT RoleId FROM JobRole j WHERE j.JobId = 2 AND j.RoleId != 1) </code></pre> <p>This worked great, except it was hard coded in XML and someone added a new column,and it brokeded stuff. Good thing is we are migrating to Fluent NHibernate.</p> <p>Now I could have written this query to be identical to the original,except I decided I wanted to get that damn exists working.</p> <h2>The Solution</h2> <p>The first thing I noticed, which I did NOT see when i originally tried this back on Alpha was &lsquo;WhereExists&rsquo;</p> <p>My first attempt (<strong><em>which did NOT work</em></strong>) was as follows:</p> <pre><code>var existing = QueryOver.Of&lt;JobRole&gt;() .Where(x =&gt; x.Job.JobId == jobId) .And(x =&gt; x.Role.RoleId != roleId) .Select(x =&gt; x.Role); result = Session.QueryOver&lt;Role&gt;() .Where(x =&gt; x.IsEnabled) .WithSubquery.WhereNotExists(existing) .OrderBy(x =&gt; x.Name).Asc .List(); </code></pre> <p>This produced SQL that was relatively close! But the outer query wasn&rsquo;t filtering the sub query.</p> <pre><code>SELECT this_.RoleId as RoleId4_0_, this_.Name as Name4_0_, this_.IsEnabled as IsEnabled4_0_, this_.RoleType as RoleType4_0_ FROM Role this_ WHERE this_.IsEnabled = 1 /* @p0 */ and not exists (SELECT this_0_.RoleId as y0_ FROM JobRole this_0_ WHERE this_0_.JobId = 4 /* @p1 */ and not (this_0_.RoleId = 0 /* @p2 */)) </code></pre> <p>So I created an alias (<strong><em>which did work</em></strong>) like so:</p> <pre><code>Role roleAlias = null; var existing = QueryOver.Of&lt;JobRole&gt;() .Where(x =&gt; x.Job.JobId == jobId) .And(x =&gt; x.Role.RoleId != roleId) .And(x =&gt; x.Role.RoleId == roleAlias.RoleId) .Select(x =&gt; x.Role); result = Session.QueryOver&lt;Role&gt;(() =&gt; roleAlias) .Where(x =&gt; x.IsEnabled) .WithSubquery.WhereNotExists(existing) .OrderBy(x =&gt; x.Name).Asc .List(); </code></pre> <p>The alias is null to begin with, and I use it in the detached query (the 2nd And), then when I create the outer query which will be my results, I create the alias by specifying it in the QueryOver. This wires up the SQL to use the outer query to filter the sub query like so:</p> <pre><code>SELECT this_.RoleId as RoleId4_0_, this_.Name as Name4_0_, this_.IsEnabled as IsEnabled4_0_, this_.RoleType as RoleType4_0_ FROM Role this_ WHERE this_.IsEnabled = 1 /* @p0 */ and not exists (SELECT this_0_.RoleId as y0_ FROM JobRole this_0_ WHERE this_0_.JobId = 4 /* @p1 */ and not (this_0_.RoleId = 0 /* @p2 */) and this_0_.RoleId = this_.RoleId) </code></pre> <p>So it turns out it&rsquo;s actually really easy, I just wish there was more documentation on this stuff since books like <a href="https://www.packtpub.com/nhibernate-3-0-cookbook/book">NHibernate 3.0 Cookbook</a> fail at giving any real detail on NH3.0&hellip; No offense to <a href="http://jasondentler.com/blog">Jason</a> because I think the book is great, but it could have been much better if it focused on NH3.0 and using it rather than having so much non-3.0 related stuff in it.</p> System.Data.SQLite isolationLevel Exception 2011-01-02T00:00:00-08:00 http://www.philliphaydon.com/2011/01/system-data-sqlite-isolationlevel-exception/ <p>I introduced SQLite to our Unit Testing at work to aid with testing the stuff written with NHibernate, most of our repositories are rather simple but some of them require some specific criteria that it would be nice to test our queries work.</p> <p>The problem is some of the queries have a transaction with the <code>IsolationLevel</code> as <code>ReadUncommitted</code>.</p> <p>Everything works perfectly fine until it comes to testing, the problem is SQLite does not support anything other than <code>Serializable</code> and <code>ReadCommitted</code>.</p> <p>I spent a while trying to see if there was a way to have an interceptor for NHibernate to capture the <code>BeginRequest</code> and replace the isolation level with something that would work, when that failed I took a look at extending the SQLite dialect but that just became confusing.</p> <p>In the end I reflected the <code>System.Data.SQLite</code> assembly (before i downloaded the sourcecode) to see what was happening when <code>BeginTransaction</code> was being called.</p> <p>There&rsquo;s two places it checks, the first is in <code>SQLiteConnection</code> under <code>BeginTransaction</code>:</p> <pre><code>if (isolationLevel != IsolationLevel.Serializable &amp;&amp; isolationLevel != IsolationLevel.ReadCommitted) throw new ArgumentException("isolationLevel"); </code></pre> <!--excerpt--> <p>The second is in the same file under Open:</p> <pre><code>if (_defaultIsolation != IsolationLevel.Serializable &amp;&amp; _defaultIsolation != IsolationLevel.ReadCommitted) throw new NotSupportedException("Invalid Default IsolationLevel specified"); </code></pre> <p>The second one is only if you&rsquo;ve configured SQLite to have a default isolationLevel, so I&rsquo;ve changed both.</p> <p>So before the change, if i ran the following code (to demonstrate the scenario):</p> <pre><code>[TestMethod] public void SQLite_WithTransction_ShouldNotThowException() { object id; using (var tx = _session.BeginTransaction(IsolationLevel.ReadUncommitted)) { id = _session.Save(new Test { Name = "Test" }); tx.Commit(); } Assert.AreEqual(1, Convert.ToInt32(id)); } </code></pre> <p>When the test runs, the following error is thrown:</p> <blockquote><p>NHibernate.TransactionException: Begin failed with SQL exception &ndash;> System.ArgumentException: isolationLevel</p></blockquote> <p>Now if I update the two exceptions:</p> <pre><code>if (_defaultIsolation != IsolationLevel.Serializable &amp;&amp; _defaultIsolation != IsolationLevel.ReadCommitted) _defaultIsolation = IsolationLevel.ReadCommitted; </code></pre> <p>And</p> <pre><code>if (isolationLevel != IsolationLevel.Serializable &amp;&amp; isolationLevel != IsolationLevel.ReadCommitted) isolationLevel = _defaultIsolation; </code></pre> <p>Compile and all that stuff&hellip;</p> <p>Now when I run the test:</p> <p><img src="/images/sqlite-exception-1.png" alt="" /></p> <p>Problem solved, now I can run unit tests against repositories that happen to use Isolation Levels not supported by SQLite.</p> <p><a href="/stuffz/System.Data_.SQLite.ForTesting.zip">System.Data.SQLite.ForTesting.zip</a></p> <p>Attached is the assembly if anyone else wants to use it for their tests.</p> Blog Update to WordPress w/ SqlSrv 2010-12-28T00:00:00-08:00 http://www.philliphaydon.com/2010/12/blog-update-to-wordpress-w-sqlsrv/ <p>Over the past few days I&rsquo;ve moved my blog from BlogEngine.Net to WordPress, since BlogEngine is fail.</p> <p>I didn&rsquo;t go with a hosted solution since it costs money just to use my own domain name, infact it costs more to use my own domain name than it cost me to register the damn thing. So I investigated blogs and came across:</p> <p><a href="http://wordpress.visitmix.com/development/installing-wordpress-on-sql-server">http://wordpress.visitmix.com/development/installing-wordpress-on-sql-server</a></p> <p>Seems someone or somepeople have ported wordpress to work on SQL Server, so people who are on Windows with SQL Server and don&rsquo;t want to use FailSQL MySQL can take advantage of wordpress.</p> <p>As much as I hate PHP after moving to .Net, the one thing the PHP community did right was all the different CMS and Blog solutions out there, something the .Net community lacks. As far as I&rsquo;m concerned there is not one good .Net blogging solution available.</p> <p>Anyway so far I&rsquo;m happy with the move.</p> I love clean client IDs - especially with .Net 2.0! 2010-12-26T00:00:00-08:00 http://www.philliphaydon.com/2010/12/i-love-clean-client-ids-especially-with-net-2-0/ <p>ASP.Net 4.0 got a brand spanking new feature. Clean ClientID&rsquo;s! ABOUT BLOODY TIME&hellip; Only, I&rsquo;m working on a legacy application which can&rsquo;t be migrated to 4.0 :(</p> <p>So why do we need Nice Readable, predictable ClientID&rsquo;s? I can think of two main reasons, outside of that, I would assume you&rsquo;re doing it wrong.</p> <ol> <li>JavaScript, to find elements&hellip;</li> <li>JavaScript in external files where you can&rsquo;t write spaghetti code.</li> </ol> <p>What do I mean by spaghetti code? I mean this stuff:</p> <pre><code>&lt;%= txtUserName.ClientID %&gt; &lt;script type="text/javascript"&gt; var element = $('#&lt;%= txtUserName.ClientID %&gt;'); var textbox = document.getElementById('&lt;%= txtUserName.ClientID %&gt;'); &lt;/script&gt; </code></pre> <p>I absolutely detest seeing this sort of thing. It makes me sick, and worst of all you can&rsquo;t pull this sort of code back to an external js file. In Web Forms, spaghetti coding is NOT your presentation, your server control is your presentation, the spaghetti code is your binding, and this should be in the codebehind.</p> <!--excerpt--> <p>Right, so what is my solution? Well I basically find all the server controls that are of a particular type, and write the information as a Json array to the HTML doc.</p> <p>I&rsquo;ve put the project on codeplex and named it, <a href="http://awesomeclientid.codeplex.com/">Awesome.ClientID</a>, because everything I do is awesome, atleast I like to think so :)</p> <p>There&rsquo;s a few issues and the code is a little messy since I rushed it, but it works.</p> <p>It serializes all the controls and you end up with a piece of JavaScript in the HTML Doc. Assume we had a form like:</p> <pre><code>&lt;fieldset&gt; &lt;ul&gt; &lt;li&gt;&lt;label&gt;Username: &lt;/label&gt; &lt;asp:textbox id="txtUserName" runat="server" /&gt;&lt;/li&gt; &lt;li&gt;&lt;label&gt;Email: &lt;/label&gt; &lt;asp:textbox id="txtEmail" runat="server" /&gt;&lt;/li&gt; &lt;/ul&gt; &lt;asp:button id="btnSubmit" runat="server" text="Submit" /&gt; &lt;/fieldset&gt; </code></pre> <p>This would get put into the HTML Doc like so:</p> <pre><code>&lt;script type="text/javascript"&gt; //&lt;![CDATA[ var controls = { "txtUserName": "ctl00_ContentPlaceHolder1_txtUserName", "txtEmail": "ctl00_ContentPlaceHolder1_txtEmail", "btnSubmit": "ctl00_ContentPlaceHolder1_btnSubmit" }; //]]&gt; &lt;/script&gt; </code></pre> <p>Now when you write your JavaScript, instead of writing spaghetti code, you can write it like:</p> <pre><code>&lt;script type="text/javascript"&gt; //&lt;![CDATA[ var element = document.getElementById(controls.btnSubmit); //]]&gt; &lt;/script&gt; </code></pre> <p>Neat huh? That&rsquo;s not all tho, sometimes you need may need access to a property. For an example, at work we use a JavaScript charting library, and I need to pass in some widths so I can render the chart with the correct number of bars.</p> <p>I have a property I set in my page with an attribute against it &lsquo;CanSerializeProperty&rsquo;, this will now get serialized just like the controls:</p> <pre><code>[CanSerializeProperty] protected int ScheduleWidth { get; set; } &lt;script type="text/javascript"&gt; //&lt;![CDATA[ var properties = { "ScheduleWidth": "50" }; //]]&gt; &lt;/script&gt; </code></pre> <p>Originally intended for just .NET 2.0/3.5, the properties feature is pretty handy for .NET 4.0 also.</p> <p>I&rsquo;ve got some additional features I&rsquo;m going to add, at the moment it serializes for every page, but I&rsquo;m going to add an attribute for pages to turn the feature off. And possibly make a web.config section so you can specify the controls you want to serialize. That way you can easily add controls from libraries such as Telerik without needing to recompile the project.</p> <p><a href="http://awesomeclientid.codeplex.com/">http://awesomeclientid.codeplex.com/</a></p> Moq-Using Params in the Returns 2010-12-06T00:00:00-08:00 http://www.philliphaydon.com/2010/12/moq-using-params-in-the-returns/ <p>Had an interesting scenario to solve today, while I was away a bunch of unit tests got turned off since they broke during some refactoring, I spent the day fixing theses unit tests.</p> <p>The method under test had a dependency on another class, it performed two actions on this class.</p> <ol> <li>to get a list of data</li> <li>to return a DateRange (this is done in a foreach loop)</li> </ol> <p>DateRange is just a class with a start/end property of DateTime. The method is sort of like this (obviously with proper names I just wrote some random code to illustrate the scenario)</p> <pre><code>public IEnumerable&lt;Stuff&gt; GetStuff(DateTime dateList) { var result = new List&lt;Stuff&gt;(); var someService = IoC.Resolve&lt;ISomeService&gt;(); var data = someService.GetData(); foreach (var date in dateList) { var tempDate = date; DateRange range = someService.GetDates(OpenRules, tempDate); //do stuff... } return result; } </code></pre> <p>So the same service is called twice, the issue is when iterating over the dateList, it needs to be filtered based on a DateRange during the day. So say, 8am till 10pm. Removing the stuff outside of that time period during that day.</p> <!--excerpt--> <p>The method GetDates would take some rules and based on the date, create the the DateRange for the filter.</p> <p>To test this method we needed to get some data, and filter it,and check the list had the correct data after being filtered.</p> <p>We mocked ISomeService,using Moq:</p> <pre><code>var mockService = new Mock&lt;ISomeService&gt;(); mockService.Setup(x =&gt; x.GetData()).Returns(FakeData()); IoC.Register&lt;ISomeService&gt;(mockService.Object); </code></pre> <p>The issue is now in the foreach, I couldn&rsquo;t just mock a return because it would be the same value and I wouldn&rsquo;t be testing the actual foreach. I ended up writing something along the lines of:</p> <pre><code>mockService.Setup(x =&gt; x.GetDates(It.IsAny&lt;OpenCloseRule&gt;(), It.IsAny&lt;DateTime&gt;())) .Returns( (OpenCloseRule openRules, DateTime, startDate) =&gt; //Some logic return new DateRange(start, end); ); </code></pre> <p>This worked great, except, if the implementation of GetDates changes, would result in false positives or false negatives, or something.</p> <p>So I ended up changing it to:</p> <pre><code>mockService.Setup(x =&gt; x.GetDates(It.IsAny&lt;OpenCloseRule&gt;(), It.IsAny&lt;DateTime&gt;())) .Returns( (OpenCloseRule openRules, DateTime, startDate) =&gt; return (new SomeService()).GetDates(openRules, startDate); ); </code></pre> <p>That way if the implantation changes, the test will break or, work. Personally I don&rsquo;t like this cos I&rsquo;m testing two things instead of one. But at least I can test the original method works correctly.</p> <p>So what I actually learnt was that the returns method on the mock can actually use the parameters that were passed in. That&rsquo;s pretty awesome. Bed time, it&rsquo;s late.</p> Yay for NHibernate 3.0 2010-12-05T00:00:00-08:00 http://www.philliphaydon.com/2010/12/yay-for-nhibernate-3-0/ <p>So happy. NHibernate 3.0 just got released.</p> <p><a href="http://nhforge.org/blogs/nhibernate/archive/2010/12/05/nhibernate-3-0-released.aspx">http://nhforge.org/blogs/nhibernate/archive/2010/12/05/nhibernate-3-0-released.aspx</a></p> <p>Now to wait for Fluent to be updated and a repository to be shoved on NuGet.</p> Sydney Alt.Net with Udi Dahan and NServiceBus Commercial Support 2010-12-01T00:00:00-08:00 http://www.philliphaydon.com/2010/12/sydney-alt-net-with-udi-dahan-and-nservicebus-commercial-support/ <p><span class="note"><strong>Note:</strong> Update 31-12-2012 &ndash; This is a really old post and the licensing described in here no longer applies. Please visit <a href="http://nservicebus.com/">http://nservicebus.com/</a></span></p> <p>Last night I attended the <a href="http://sydney.ozalt.net/">Sydney Alt.Net</a> user group since <a href="http://www.udidahan.com/">Udi Dahan</a> was attending. There was no specific topic, it was an open questions/answers session with Udi. If you&rsquo;re interested you can watch it <a href="http://sydney.ozalt.net/2010/11/november-meeting-recorded-for-your.html">here</a>.</p> <p>The thing that interested me most was to do with <a href="http://www.nservicebus.com/">NServiceBus</a> commercial support (<em>1 hour 23 minutes in the video if you want to skip ahead</em>). Initially I thought that it was going from Open Source to requiring a license, a license I wouldn&rsquo;t be able to afford for my hobby projects, however someone asked about the licensing.</p> <!--excerpt--> <p>As it turns out NServiceBus is still completely Open Source and Free, you can download the source code, compile it, and use it with no restrictions. However you must support it yourself, and use the community for support/help. While the paid licensing model is to allow companies to download stable tested binaries with commercial support.</p> <p>Great news, now I can download it and play around with the latest trunk and look at integrating it into one of my projects. Learning is funs :)</p> Mentally Drained by Udi Dahan. 2010-11-27T00:00:00-08:00 http://www.philliphaydon.com/2010/11/mentally-drained-by-udi-dahan/ <p>I&rsquo;m on my first day of recovery after attending <a href="http://www.udidahan.com/">Udi Dahan&rsquo;s</a> <a href="http://www.udidahan.com/training/#Advanced_Distributed_System_Design">Advanced Distributed Systems Design using SOA &amp; DDD</a>. Needless to say I think I&rsquo;m still in shock.</p> <p>Udi must be one of the best presenters I&rsquo;ve come across, I always thought he talked a little slow when watching videos of him presenting, but it&rsquo;s an entirely different experience when you&rsquo;re sitting in a room listening to him.</p> <p>He really makes sure you follow and understand, at no point did I feel like I was left behind. Something that intrigued me however, was there was not one question he could not answer&hellip; He must have heard every possible question because people started trying to catch him out with some weird example or scenario, and he was able to answer it.</p> <!--excerpt--> <p>I thought a there was a few people who struggled a little bit because they spent a lot of time trying to apply what they were learning to their current projects or applications like it was something they could slap on the side and benefit from, or they would think about the entities involved and how it would map to a database schema. Thinking like this makes the concepts really to understand.</p> <p>The course is amazing, Udi is a wealth of knowledge and 5 days just isn&rsquo;t enough time to download all the information in his head, but that 5 days is like 5 years worth of experience. All that"s left is to take what I&rsquo;ve learnt and put it into practice.</p> <p>I highly recommend going to this course even if you have to take unpaid leave and pay for the course out of your own pocket, it&rsquo;s well worth every cent.</p> <p>100/10!</p> <p><a href="http://www.udidahan.com/training/#Advanced_Distributed_System_Design">http://www.udidahan.com/training/#Advanced_Distributed_System_Design</a></p> Failware... aka,MSN 2010-10-28T00:00:00-07:00 http://www.philliphaydon.com/2010/10/failware-aka-msn/ <p>Microsoft recently pushed out a Windows Update for their Windows Live Essentials, in this update came Windows Live Messenger.</p> <p>Wow&hellip; what was the Windows Live team thinking when they wrote this? It&rsquo;s the biggest pile of crap ever.</p> <p>The progression of MSN was fine, sure it was becoming slight bloatware, has some annoying advertising, and some silly features. But it worked well and looked nice.</p> <p>My biggest pet hate?</p> <p>If I sent a link to an image, I&rsquo;m sending a god damn LINK. If I wanted to send an image, I would send an image. But I&rsquo;m not, I&rsquo;m sending a LINK.</p> <!--excerpt--> <p>The windows live team thought &ldquo;you know what, we will help users by getting the actual image and sending it to the user for them so they don&rsquo;t need to click on the link!&rdquo;.</p> <p>Great.</p> <p>BUT ATLEAST LET ME TURN THE DAMN FEATURE OFF!</p> <p>/rant</p> <p>It does have one really nice feature I like.</p> <p><img src="/images/msn-sucks-1.png" alt="" /></p> <p>It automatically creates link&rsquo;s for searchable things on Bing. People and Places seem to be what&rsquo;s most commonly converted, I&rsquo;ve seen some food&rsquo;s converted to links too.</p> <p>It&rsquo;s handy for when you don&rsquo;t have any idea what the hell your friend&rsquo;s are talking about.</p> Using HiLo with FluentNHibernate 2010-10-24T00:00:00-07:00 http://www.philliphaydon.com/2010/10/using-hilo-with-fluentnhibernate/ <p>I spend ages trying to find some documentation or tutorial on how to use HiLo with FluentNHibernate after reading:</p> <ul> <li><a href="http://ayende.com/Blog/archive/2009/03/20/nhibernate-avoid-identity-generator-when-possible.aspx">NHibernate: Avoid identity generator when possible</a></li> <li><a href="https://connect.microsoft.com/SQLServer/feedback/details/328811/scope-identity-sometimes-returns-incorrect-value">SCOPE_IDENTITY() sometimes returns incorrect value</a></li> <li><a href="http://nhforge.org/blogs/nhibernate/archive/2009/03/20/nhibernate-poid-generators-revealed.aspx">NHibernate POID Generators revealed</a></li> <li><a href="http://fabiomaulo.blogspot.com/2008/12/identity-never-ending-story.html">Identity: The never ending story</a> &ndash; BTW they are <a href="http://www.imdb.com/title/tt1386664/">remaking</a> <a href="http://www.imdb.com/title/tt0088323/">The NeverEnding Story</a>. Bastards!!!</li> </ul> <p>As it turns out, it&rsquo;s really easy to setup. I figured out two ways of doing it, the HiLo table having a single row, with each column for each table &lsquo;Hi&rsquo;. Or a row for each table.</p> <p>I setup a really simple example with the following table.</p> <p><img src="/images/nhibernate-hilo-1.png" alt="" /></p> <p>&lsquo;ProductId&rsquo; is set to be int/primary key, but identity is false, since we don&rsquo;t want the database generating the id.</p> <!--excerpt--> <p>The two HiLo tables are like so:</p> <h3>Row Per Table</h3> <p><img src="/images/nhibernate-hilo-2.png" alt="" /></p> <h3>Column Per Table</h3> <p>(shows only a single column, but for each table you would add a new column)</p> <p><img src="/images/nhibernate-hilo-3.png" alt="" /></p> <p>Then all you need to do is setup the Fluent Mappings.</p> <h2>Row Per Table</h2> <p>So for Row Per Table, the mapping for Product would look like this:</p> <pre><code>public class ProductMap : ClassMap&lt;Product&gt; { public ProductMap() { Id(x =&gt; x.Id).Column("ProductId") .GeneratedBy .HiLo("NH_HiLo", "NextHi", "1000", "TableKey = ''Product''"); Map(x =&gt; x.Name); } } </code></pre> <p>HiLo takes the parameters (TableName, ColumnName, MaxLo, Where). Where is an override that we will use since we need to specify the row to return. So if we insert a single row into our table:</p> <p><img src="/images/nhibernate-hilo-4.png" alt="" /></p> <p>We pass in our where clause as <code>TableKey = "Product"</code>, so that it knows which row to get the NextHi from.</p> <p>For each new table we would just add a new row and a default NextHi value. Every time the SessionFactory is created it would grab the NextHi value and increment it by 1.</p> <h2>Column Per Table</h2> <p>Column Per Table is very similar, except we don&rsquo;t need the where parameter, we only need to specify the column to look at. Assuming we were using the Column Per Table with the HiLo2 table, our mapping would look like this:</p> <pre><code>public class ProductMap : ClassMap&lt;Product&gt; { public ProductMap() { Id(x =&gt; x.Id).Column("ProductId") .GeneratedBy .HiLo("NH_HiLo2", "Product_NextHi", "1000"); Map(x =&gt; x.Name); } } </code></pre> <p>We would need to add a single row to our table like so:</p> <p><img src="/images/nhibernate-hilo-5.png" alt="" /></p> Google is fail 2010-10-15T00:00:00-07:00 http://www.philliphaydon.com/2010/10/google-is-fail/ <p>No longer is Microsoft the evil empire, for Google is the new emerging evil empire. Seriously, Google is the new M$ of the 90&rsquo;s.</p> <p>It&rsquo;s always bugged me that I use Opera browser for my primary browser, a browser which follows W3 Standards more strictly than any other browser out there.</p> <p>Yet so many sites fail to support Opera&hellip; I had to use IE for years just to do internet banking with ANZ bank, until Opera 9.5 came out, simply because they blocked it. Many other sites seem to suggest using a &lsquo;supported&rsquo; browser, even tho the site works 100% in Opera anyway&hellip;</p> <p>In comes Google, they always hold back on Opera. Google Wave? Gmail? Analytics, all had their issues over the years, and now we have this new super duper feature Google Instant, and their new fancy Image Search.</p> <p>Except, neither work in Opera&hellip;</p> <p><img src="/images/google-fail-1.png" alt="" /></p> <p>Except&hellip; It actually does work,infact both Google Instant and their fancy Image Search work in Opera.</p> <!--excerpt--> <p>If you right click and go to &lsquo;Edit Site Preferences&rsquo; and set it to &lsquo;Identify as Firefox&rsquo;,then refresh the page.</p> <p><img src="/images/google-fail-2.png" alt="" /></p> <p>You end up with:</p> <p><img src="/images/google-fail-3.png" alt="" /></p> <p><img src="/images/google-fail-4.png" alt="" /></p> <p>So clearly, Google fails.</p> <p>I hope in the future they get their act together and start supporting all browsers instead of picking and choosing.</p> QueryOver with NHibernate 3... Lovin it! 2010-09-28T00:00:00-07:00 http://www.philliphaydon.com/2010/09/queryover-with-nhibernate-3-lovin-it/ <p>Working on an old website I built back in 2004, back then I coded all the data access by hand, wrote stored products and populated the data into objects, lazy loaded relationships etc. 2005 roles around and I migrated it to .Net 2.0, but with all the old data access stuff intact.</p> <p>Move forward 6 years and I have to make some changes, so I figured I would update the data access to use NH3.0 so I could play around with it.</p> <p>One of the thing&rsquo;s I just wrote was a sub query using exists. If I wrote the SQL it would probably look something along the lines of:</p> <pre><code>SELECT * FROM ProductType WHERE EXISTS (SELECT 1 FROM Product WHERE Active = 1 AND ProductTypeID = ProductType.ProductTypeID) </code></pre> <p>With some more criteria, since the data comes from MYOB it&rsquo;s sometimes out of date, I check for status, active, quantity,price,etc.</p> <p>Originally this stuff was in a stored procedure, and I needed to write this using QueryOver.</p> <!--excerpt--> <p>I broken the query into two pieces, the query against the Product with criteria, and the query against the ProductType, using the Product query as a Subquery for the ProductType criteria.</p> <pre><code>var products = QueryOver.Of&lt;Product&gt;() .Where(x =&gt; x.RetailPrice &gt; 0) .And(x =&gt; x.Quantity &gt; 0) .And(x =&gt; x.Active) .And(x =&gt; x.LastUpdate &gt; DateTime.Now.AddDays(-3)) .WhereRestrictionOn(x =&gt; x.StatusId).IsIn(new int[] {1, 2, 9}) .Select(x =&gt; x.ProductType.Id); var result = Session.QueryOver&lt;ProductType&gt;() .Where(x =&gt; x.Active) .WithSubquery.WhereProperty(x =&gt; x.Id).In(products) .List(); return result; </code></pre> <p>Running profiler aga&hellip; SQL Profiler (not NHProf, tho that would be handy if i could afford it) produces the following:</p> <p><em>image missing &ndash; old post</em></p> <pre><code>SELECT this_.ProductTypeID as ProductT1_3_0_, this_.Name as Name3_0_, this_.Active as Active3_0_ FROM [ProductType] this_ WHERE this_.Active = @p0 and this_.ProductTypeID in ( SELECT this_0_.ProductTypeId as y0_ FROM [Product] this_0_ WHERE this_0_.RetailPrice &gt; @p1 and this_0_.Quantity &gt; @p2 and this_0_.Active = @p3 and this_0_.LastUpdate &gt; @p4 and this_0_.StatusId in (@p5, @p6, @p7)) </code></pre> <p>I removed the parameters since you don&rsquo;t need those :) but it achieves the same thing my old stored proc query did. And it&rsquo;s much easier to maintain too! No more hunting around in stored procs to update queries when columns are dropped or added.</p> <p>So far I&rsquo;m loving the QueryOver syntax.</p> Getting back into it :( 2010-09-28T00:00:00-07:00 http://www.philliphaydon.com/2010/09/getting-back-into-it/ <p>Earlier this year I changed hosting provider, had a new VSlice with Windows Server 2008 R2, SQL and all the wizz bang stuff. But within 3 weeks of setting everything up, everything went down, and I lost everything. Apparently the VM corrupted and couldn&rsquo;t be recovered. Not only that I made the mistake of thinking &ldquo;hey, you know what, nothing bad will happen for a while, I&rsquo;ll setup backups next month&rdquo;. Only something bad did happen.</p> <p>I&rsquo;ve since moved host again, and am now hosted with MammothVPS with proper backups. So hopefully it doesn&rsquo;t die again.</p> <p>It&rsquo;s pretty depressing to lose everything, I lost a couple of projects I had spent a couple of years building that had only been live a month or so. So depressing it put me off wanting to blog anything. So hopefully I can get back into it again.</p> jQuery Serialize a Fieldset 2009-07-11T00:00:00-07:00 http://www.philliphaydon.com/2009/07/jquery-serialize-a-fieldset/ <p>I&rsquo;m really not a fan of <a href="http://ajax.asp.net/">ASP.Net Ajax</a> and would prefer to use jQuery where ever I can. So for anything public facing I tend to use jQuery and HTTPHandlers.</p> <p>jQuery has this nifty little function called <a href="http://docs.jquery.com/Ajax/serialize">serialize</a> for serializing form data for Ajax. So if we have the following HTML.</p> <pre><code>&lt;body&gt; &lt;form id="aspNetForm" runat="server"&gt; &lt;div&gt; &lt;fieldset class="fsLoginForm"&gt; &lt;legend&gt;Login Fieldset&lt;/legend&gt; &lt;ul&gt; &lt;li&gt;Email: &lt;input type="text" name="txtEmail" /&gt;&lt;/li&gt; &lt;li&gt;Password: &lt;input type="text" name="txtPassword" /&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/fieldset&gt; &lt;fieldset class="fsName"&gt; &lt;legend&gt;Name Fieldset&lt;/legend&gt; &lt;ul&gt; &lt;li&gt;My Name: &lt;input type="text" name="email" /&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/fieldset&gt; &lt;fieldset class="fsColour"&gt; &lt;legend&gt;Colour Fieldset&lt;/legend&gt; &lt;ul&gt; &lt;li&gt;Colour: &lt;input type="text" name="colour" /&gt;&lt;/li&gt; &lt;/ul&gt; &lt;/fieldset&gt; &lt;input type="button" value="Submit Form" onclick="SubmitForm();" /&gt; &lt;/div&gt; &lt;/form&gt; &lt;/body&gt; </code></pre> <p>And a basic alert method that shows us the result of the form serialized:</p> <pre><code>function SubmitForm() { alert($('form').serialize()); } </code></pre> <!--excerpt--> <p>We end up with a result like:</p> <p><em>image missing</em></p> <p>This is great, however we may not want to submit the entire form&hellip; and unfortunately when using ASP.Net Web Forms, your limited to one form element.</p> <p>jQuery only allows you to serialize a form element, so I came up with a little work around for submitting only the elements you want. The example is done using fieldsets, however you could group them using div&rsquo;s, tables, or what ever you want.</p> <p>Basically I add a new form, and clone the fieldset into the form,then serialize the new form.</p> <p>So I&rsquo;ve added some new buttons for this example:</p> <pre><code>&lt;input type="button" value="Submit Login" onclick="SubmitFieldset('.fsLoginForm');" /&gt; &lt;input type="button" value="Submit Name" onclick="SubmitFieldset('.fsName');" /&gt; &lt;input type="button" value="Submit Name &amp;amp; Colour" onclick="SubmitFieldset('.fsName, .fsColour');" /&gt; </code></pre> <p>And the JavaScript:</p> <pre><code>function SubmitFieldset(fieldsetName) { //Add a new form and hide it. $('body').append('&lt;form id="form-to-submit" style="visibility:hidden;"&gt;&lt;/form&gt;'); //Clone the fieldset into the new form. $('#form-to-submit').html($(fieldsetName).clone()); //Serialize the data var data = $('#form-to-submit').serialize(); //Remove the form $('#form-to-submit').remove(); //Alert to see the data, this is where you would do your ajaxy stuff :) alert(data); } </code></pre> <p>Now when I press &lsquo;Submit Login&rsquo; the result I get is:</p> <p><em>image missing</em></p> <p>I only get the elements in the login fieldset. If I want to submit more than one fieldset I can specify them all in the selector by using the specifying multiple arguments in the selector. <a href="http://docs.jquery.com/Selectors/multiple#selector1selector2selectorN">http://docs.jquery.com/Selectors/multiple#selector1selector2selectorN</a></p> <p>So by passing in <code>.fsName, .fsColour</code> I end up with:</p> <p><em>image missing</em></p> <p>Now I can submit only the data I need to submit, and not all of it :)</p>