<?xml version="1.0" encoding="UTF-8"?> <rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" ><channel><title>Rex Flex</title> <atom:link href="http://rexflex.net/feed/" rel="self" type="application/rss+xml" /><link>http://rexflex.net</link> <description>Rants of a software developer</description> <lastBuildDate>Fri, 02 Sep 2011 16:54:18 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=3.3.1</generator> <item><title>Scratching the Itch</title><link>http://rexflex.net/2011/09/scratching-the-itch/</link> <comments>http://rexflex.net/2011/09/scratching-the-itch/#comments</comments> <pubDate>Fri, 02 Sep 2011 04:49:39 +0000</pubDate> <dc:creator>Rex Morgan</dc:creator> <category><![CDATA[C#]]></category> <category><![CDATA[Programming]]></category><guid isPermaLink="false">http://rexflex.net/?p=501</guid> <description><![CDATA[A couple of weeks ago I found an article by Ryan Day about implementing the Nasdaq ITCH protocol in python. I was really excited about this because I had always thought the barriers to entry for writing a program relating to the stock market would be very high. Turns out writing an application for stock [...]]]></description> <content:encoded><![CDATA[<p>A couple of weeks ago I found an article by Ryan Day about implementing the <a href="http://www.ryanday.net/?p=573">Nasdaq ITCH</a> <a href="http://lostechies.com/josharnold/">protocol in python</a>. I was really excited about this because I had always thought the barriers to entry for writing a program relating to the stock market would be very high. Turns out writing an application for stock markets is not the barrier, it&#8217;s getting the live data needed to be able to make money with it.</p><p>I wanted to use <a href="http://www.rabbitmq.com/">RabbitMQ</a> because I&#8217;ve been hearing a lot of great things about it. It has a really nice web interface you can use to check on the status of your queues and see how many messages are passing through. Also, since I had used <a href="http://masstransit-project.com/">MassTransit</a> in the past with MSMQ, and MassTransit now support RabbitMQ, I figured it&#8217;d be a breeze to setup.</p><p>RabbitMQ was very easy to get up and running, along with the plugin for the web interface. It turns out I don&#8217;t remember as much as I thought I did about MassTransit, but <a href="http://lostechies.com/josharnold/">Joshua Arnold</a> was able to help me get setup pretty quick and I had messages flowing through RabbitMQ in what seemed like no time at all.</p><p>The message rate is very slow&#8230; I realized that I&#8217;m only able to publish about 3,000 messages per second to the message queue. After taking MassTransit out of the mix and publishing directly to RabbitMQ, that number raises to about 10,000 messages per second. If I don&#8217;t publish any messages at all and only parse the data from the file, I can parse about 450,000 messages per second. So, RabbitMQ and MassTransit are causing a bottleneck.</p><p>Consuming messages is even slower. I got MassTransit to pull messages off the queue at a top speed of about 1,200 messages per second. Way too slow to keep up with a trading day, where I think I would need to be able to handle at least 20,000 messages per second in order to keep up with bursts of traffic.</p><p>After doing a little digging, I found a <a href="http://mikehadlow.blogspot.com/2011/04/message-queue-shootout.html">nice comparison</a> of some different queues. It sounds to me like <a href="http://www.zeromq.org/">ZeroMQ</a> would be a perfect fit for this project. If I have some free time I&#8217;m going to give it a shot and see if it performs as well as they say.</p><p>Take a look at the code and let me know what you think: <a href="http://github.com/RexMorgan/Itch">http://github.com/RexMorgan/Itch</a></p> ]]></content:encoded> <wfw:commentRss>http://rexflex.net/2011/09/scratching-the-itch/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>FubuMVC: Redirect and Transfer</title><link>http://rexflex.net/2011/07/fubumvc-fubucontinuation/</link> <comments>http://rexflex.net/2011/07/fubumvc-fubucontinuation/#comments</comments> <pubDate>Tue, 19 Jul 2011 17:42:16 +0000</pubDate> <dc:creator>Rex Morgan</dc:creator> <category><![CDATA[C#]]></category> <category><![CDATA[FubuMVC]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[Web Development]]></category><guid isPermaLink="false">http://rexflex.net/?p=445</guid> <description><![CDATA[Note: As with everything in an open source project (and especially one which is pre-1.0), things may change. I&#8217;ll attempt to keep this article up to date or link to updated articles if things change with the usage of FubuContinuation. Sometimes instead of simply rendering a view from your action, I need to redirect the user to another [...]]]></description> <content:encoded><![CDATA[<p><em>Note: As with everything in an open source project (and especially one which is pre-1.0), <a href="https://groups.google.com/d/topic/fubumvc-devel/2Wx4iKwnp0A/discussion">things may change</a>. I&#8217;ll attempt to keep this article up to date or link to updated articles if things change with the usage of FubuContinuation.</em></p><p>Sometimes instead of simply rendering a view from your action, I need to redirect the user to another URL, or call another action.</p><p>In this post I&#8217;m going to explain how FubuMVC allows you to perform these actions. In a multi-tenant application I&#8217;m working on, I handle all default requests to many domains with a single action in my FubuMVC application. I want to choose which behavior chain to run, depending on the URL that the user has browsed to.</p><p>An example of this, just to make sure I&#8217;m explaining this properly, is Tumblr. Browsing to tumblr.com should display the home page for Tumblr (sign up form, information about why Tumblr is great, etc). However, browsing to {username}.tumblr.com should display the posts by that particular user. <em>(I honestly don&#8217;t know if this is handled by a single piece of code on Tumblr, but I&#8217;d like to mimic this, with a single piece of code, in my project.)</em></p><p>To start, I&#8217;m going to create a FrontLoaderEnpoint that all default requests will go through.</p><p>In my FrontLoaderEndpoint, I need to check what URL the user is coming from. In order to do this, I have a property called <a href="http://groups.google.com/group/fubumvc-devel/msg/9c1091e92ed53b7c">HTTP_HOST on my input model</a>. FubuMVC will automatically fill in the information from the <a href="http://msdn.microsoft.com/en-us/library/system.web.httprequest.servervariables.aspx">ServerVariables collection</a>.<em> (I hate to just leave it as this &#8220;just works&#8221;, but model binding will be the topic of another blog post.)</em></p><p>Now I&#8217;m taking the HTTP_HOST from the input model and attempting to look up the user that the domain belongs to.</p><p>If there is a user that is using the domain, then I&#8217;m going to go ahead and transfer the request to the endpoint that handles the user specific domains. I tell FubuMVC that I want to transfer the user by returning FubuContinuation.TransferTo. The TransferTo method takes in the input model of the action that you want to call.</p><p>If there&#8217;s not a user found for the domain, I&#8217;m going to redirect the user to the home page (which allows new users to sign up, etc). To redirect the user I return FubuContinuation.RedirectTo and, just like the TransferTo method, pass in the input model of the action I want to redirect the user to.</p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-1074452\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">FrontLoaderRequestModel<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC3\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"kt\">string<\/span> <span class=\"n\">HTTP_HOST<\/span> <span class=\"p\">{<\/span> <span class=\"k\">get<\/span><span class=\"p\">;<\/span> <span class=\"k\">set<\/span><span class=\"p\">;<\/span> <span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC4\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/1074452/16efe1ef44be46334d41fe099fdee1d6c0daff1f/FrontLoaderRequestModel.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/1074452#file_front_loader_request_model.cs\" style=\"float:right;margin-right:10px;color:#666\">FrontLoaderRequestModel.cs<\/a>\n            <a href=\"https://gist.github.com/1074452\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/1074452/FrontLoaderRequestModel.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-1074452\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">FrontLoaderEndpoint<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC3\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">private<\/span> <span class=\"k\">readonly<\/span> <span class=\"n\">IUserRepository<\/span> <span class=\"n\">_userRepository<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC4\'><br/><\/div><div class=\'line\' id=\'LC5\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"nf\">FrontLoaderEndpoint<\/span><span class=\"p\">(<\/span><span class=\"n\">IUserRepository<\/span> <span class=\"n\">userRepository<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC6\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC7\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">_userRepository<\/span> <span class=\"p\">=<\/span> <span class=\"n\">userRepository<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC8\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC9\'><br/><\/div><div class=\'line\' id=\'LC10\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"n\">FubuContinuation<\/span> <span class=\"nf\">Get<\/span><span class=\"p\">(<\/span><span class=\"n\">FrontLoaderRequestModel<\/span> <span class=\"n\">input<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC11\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC12\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">var<\/span> <span class=\"n\">user<\/span> <span class=\"p\">=<\/span> <span class=\"n\">_userRepository<\/span><span class=\"p\">.<\/span><span class=\"n\">GetByDomain<\/span><span class=\"p\">(<\/span><span class=\"n\">input<\/span><span class=\"p\">.<\/span><span class=\"n\">HTTP_HOST<\/span><span class=\"p\">);<\/span><\/div><div class=\'line\' id=\'LC13\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/div><div class=\'line\' id=\'LC14\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">if<\/span><span class=\"p\">(<\/span><span class=\"n\">user<\/span> <span class=\"p\">!=<\/span> <span class=\"k\">null<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC15\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC16\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">return<\/span> <span class=\"n\">FubuContinuation<\/span><span class=\"p\">.<\/span><span class=\"n\">TransferTo<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">UserSpecificIndexRequestModel<\/span><\/div><div class=\'line\' id=\'LC17\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC18\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">User<\/span> <span class=\"p\">=<\/span> <span class=\"n\">user<\/span><\/div><div class=\'line\' id=\'LC19\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">});<\/span><\/div><div class=\'line\' id=\'LC20\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC21\'><br/><\/div><div class=\'line\' id=\'LC22\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">return<\/span> <span class=\"n\">FubuContinuation<\/span><span class=\"p\">.<\/span><span class=\"n\">RedirectTo<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">HomeRequestModel<\/span><span class=\"p\">());<\/span><\/div><div class=\'line\' id=\'LC23\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC24\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/1074452/72248a04afef40ad9f60354bb93aacfa421b65aa/FrontLoaderEndpoint.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/1074452#file_front_loader_endpoint.cs\" style=\"float:right;margin-right:10px;color:#666\">FrontLoaderEndpoint.cs<\/a>\n            <a href=\"https://gist.github.com/1074452\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/1074452/FrontLoaderEndpoint.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><h4>How does it work?<span> </span></h4><p>The way this works is RedirectTo and TransferTo are both static methods on the FubuContinuation class, which return a FubuContinuation object. In the constructor of the FubuContinuation object, it takes in the ContinuationType (Redirect, Transfer, or NextBehavior) and an action that should be called on the IContinuationDirector.</p><p>The IContinuationDirector is what actually does all of the work, by calling RedirectToUrl on the IOutputWriter if you&#8217;re doing a redirect <em>(just like I did in Step 2 of <a href="http://rexflex.net/2011/07/fubumvc-authentication/">FubuMVC: Authentication</a>.)</em>, or building a partial from the IPartialFactory and invoking it, if you&#8217;re doing a transfer. The action to call is resolved using the input model that you provided when you called FubuContinuation.RedirectTo / FubuContinuation.TransferTo. Since we&#8217;re using the <a href="http://rexflex.net/2011/07/fubumvc-one-model-in-one-model-out/">thunderdome pattern</a>, each of our actions are uniquely defined by the type of the input model.</p><p>Internally, FubuMVC has a built-in convention which gets run. This convention checks for any actions that have a FubuContinuation as an output type. If it finds one, it adds an internal behavior called ContinuationHandler directly after the action call.</p><p>When the ContinuationHandler gets called, it pulls the FubuContinuation that was set in my action call from the IFubuRequest and calls Process on it, passing into it, &#8220;this&#8221; <em>(the ContinuationHandler being called.)</em> The Process method calls the action that was passed into the FubuContinuation constructor and passes int he ContinuationHandler that&#8217;s being run. <em>(Note: ContinuationHandler implements IContinuationDirector.)</em></p><h4>Bonus!</h4><p>If you want to redirect the user to a URL of an outside site, just pass the URL directly into FubuContinuation.RedirectTo. The ContinuationHandler has a mechanism in place to redirect directly to a URL if it&#8217;s provided as a string.</p> ]]></content:encoded> <wfw:commentRss>http://rexflex.net/2011/07/fubumvc-fubucontinuation/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>FubuMVC: One Model In, One Model Out</title><link>http://rexflex.net/2011/07/fubumvc-one-model-in-one-model-out/</link> <comments>http://rexflex.net/2011/07/fubumvc-one-model-in-one-model-out/#comments</comments> <pubDate>Thu, 14 Jul 2011 20:01:12 +0000</pubDate> <dc:creator>Rex Morgan</dc:creator> <category><![CDATA[C#]]></category> <category><![CDATA[FubuMVC]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[Web Development]]></category><guid isPermaLink="false">http://rexflex.net/?p=466</guid> <description><![CDATA[A pattern that&#8217;s regularly used with FubuMVC is the one model in, one model out pattern. This is also known as OMIOMO and, my personal favorite, the &#8221;thunderdome&#8221; pattern. It took me a little while to understand why this pattern is in place and seems to be a gotcha when I come back to FubuMVC after [...]]]></description> <content:encoded><![CDATA[<p>A pattern that&#8217;s regularly used with FubuMVC is the one model in, one model out pattern. This is also known as OMIOMO and, my personal favorite, the &#8221;<a href="http://codebetter.com/jeremymiller/2008/10/23/our-opinions-on-the-asp-net-mvc-introducing-the-thunderdome-principle/">thunderdome</a>&#8221; pattern. It took me a little while to understand why this pattern is in place and seems to be a gotcha when I come back to FubuMVC after an extended period of time. I&#8217;m going to write about why I use this pattern, to document it for both others, and my future self.</p><h4>Origins</h4><p>From the articles I can find online, the thunderdome pattern was created as a way to increase testability of your actions. By only allowing a single model in, it&#8217;s very easy to setup the context of the test. It also removes the need to rely on the <a href="http://msdn.microsoft.com/en-us/library/system.web.httpcontext.aspx">HttpContext</a> inside the actions. In FubuMVC, if information is needed from the HttpContext, a property can be added to the input model and it&#8217;s the responsibility of model binding to set that property to the corresponding value in the HttpContext.<em> (Model Binding will be the topic of another post.)</em></p><h4>Benefits</h4><p>Once you decide to use the thunderdome pattern, it&#8217;s not a big step to make each of the actions take a unique input model. If each behavior chain has a unique input model, then each behavior chain can be identified by its input type. This is a great way, in my opinion, to take advantage of static typing and make it work for you.</p><p>In FubuMVC, this is the most common way to identify behavior chains. Since each behavior chain is associated to a route, it&#8217;s the most common way to build URLs, also.</p><h4>Other Patterns</h4><p>It&#8217;s important to note that the thunderdome pattern is not the only way to use FubuMVC. All of the combinations of One/Zero model in One/Zero model out patterns are supported. I can see using a one model in, zero model out for use of services where you only care about the HTTP Response code. <em>(If you want to do this with the thunderdome pattern, you can just return an <a href="http://msdn.microsoft.com/en-us/library/system.net.httpstatuscode.aspx">HttpStatusCode</a> from your action. There&#8217;s a <a href="https://github.com/DarthFubuMVC/fubumvc/blob/master/src/FubuMVC.Core/Behaviors/RenderStatusCodeBehavior.cs">built</a> in <a href="https://github.com/DarthFubuMVC/fubumvc/blob/master/src/FubuMVC.Core/FubuRegistry.DefaultConventions.cs#L41">convention</a> in FubuMVC to handle this return type.)</em></p><p>I don&#8217;t use either of the patterns which do not have an input model. If I have an action that doesn&#8217;t have any input, then I typically have it accept an empty &#8220;marker&#8221; input model, anyway. This gives me the ability to uniquely identify it if I ever need to create a link to it, or for any other reason.</p> ]]></content:encoded> <wfw:commentRss>http://rexflex.net/2011/07/fubumvc-one-model-in-one-model-out/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>FubuMVC: Authorization</title><link>http://rexflex.net/2011/07/fubumvc-authorization/</link> <comments>http://rexflex.net/2011/07/fubumvc-authorization/#comments</comments> <pubDate>Sat, 09 Jul 2011 04:34:01 +0000</pubDate> <dc:creator>Rex Morgan</dc:creator> <category><![CDATA[C#]]></category> <category><![CDATA[FubuMVC]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[Web Development]]></category><guid isPermaLink="false">http://rexflex.net/?p=397</guid> <description><![CDATA[When it comes to authorization, FubuMVC is very powerful in letting you setup extremely customizable rules for deciding who has access to what. Luckily, Joshua Arnold was able to help me get these rules setup and I&#8217;d like to document the process for everyone else. In this post, I&#8217;ll be going over how to write [...]]]></description> <content:encoded><![CDATA[<p>When it comes to authorization, FubuMVC is very powerful in letting you setup extremely customizable rules for deciding who has access to what. Luckily, <a href="http://lostechies.com/josharnold/">Joshua Arnold</a> was able to help me get these rules setup and I&#8217;d like to document the process for everyone else.</p><p>In this post, I&#8217;ll be going over how to write a custom authorization rule to keep users from being able to edit another user&#8217;s blog post in a simple blogging application. I&#8217;ll do this by plugging into the authorization facilities built into FubuMVC.</p><h4>Overview</h4><ol><li>Come up with a convention to identify which action calls need authorization, and how to access the information we need from the input models</li><li>Do the heavy lifting by writing an authorization policy to check and see if the user is authorized to do what they&#8217;re trying to do</li><li>Teach FubuMVC about the convention</li><li>Tell FubuMVC to use the convention</li></ol><h4>Step 1: Come up with a convention</h4><p>In order to figure out which routes/action calls need authorization, I&#8217;m going to implement an interface on my input models. This will not only mark them so I can look them up later, but also provide me with a generic way of accessing the properties that I&#8217;m going to be running my authorization code against. In this case, all I need from the models are the post id, so that&#8217;s all that&#8217;s required on the interface. It&#8217;s also worth noting here that I have two input models. I use EditPostRequestModel for the http get action call (to get the post in order to display it for the user to edit), and the EditPostInputModel for the http post action call (which handles the saving of the post after it&#8217;s been edited by the user.)</p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-1073216\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">interface<\/span> <span class=\"n\">IPostModel<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC3\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"kt\">int<\/span> <span class=\"n\">PostId<\/span> <span class=\"p\">{<\/span> <span class=\"k\">get<\/span><span class=\"p\">;<\/span> <span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC4\'><span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC5\'><br/><\/div><div class=\'line\' id=\'LC6\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">EditPostInputModel<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IPostModel<\/span><\/div><div class=\'line\' id=\'LC7\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC8\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"n\">PostId<\/span> <span class=\"p\">{<\/span> <span class=\"k\">get<\/span><span class=\"p\">;<\/span> <span class=\"k\">set<\/span><span class=\"p\">;<\/span> <span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC9\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"kt\">string<\/span> <span class=\"n\">Title<\/span> <span class=\"p\">{<\/span> <span class=\"k\">get<\/span><span class=\"p\">;<\/span> <span class=\"k\">set<\/span><span class=\"p\">;<\/span> <span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC10\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"kt\">string<\/span> <span class=\"n\">Body<\/span> <span class=\"p\">{<\/span> <span class=\"k\">get<\/span><span class=\"p\">;<\/span> <span class=\"k\">set<\/span><span class=\"p\">;<\/span> <span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC11\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"kt\">string<\/span> <span class=\"n\">Slug<\/span> <span class=\"p\">{<\/span> <span class=\"k\">get<\/span><span class=\"p\">;<\/span> <span class=\"k\">set<\/span><span class=\"p\">;<\/span> <span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC12\'><span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC13\'><br/><\/div><div class=\'line\' id=\'LC14\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">EditPostRequestModel<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IPostModel<\/span><\/div><div class=\'line\' id=\'LC15\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC16\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"kt\">int<\/span> <span class=\"n\">PostId<\/span> <span class=\"p\">{<\/span> <span class=\"k\">get<\/span><span class=\"p\">;<\/span> <span class=\"k\">set<\/span><span class=\"p\">;<\/span> <span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC17\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"kt\">string<\/span> <span class=\"n\">Title<\/span> <span class=\"p\">{<\/span> <span class=\"k\">get<\/span><span class=\"p\">;<\/span> <span class=\"k\">set<\/span><span class=\"p\">;<\/span> <span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC18\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"kt\">string<\/span> <span class=\"n\">Body<\/span> <span class=\"p\">{<\/span> <span class=\"k\">get<\/span><span class=\"p\">;<\/span> <span class=\"k\">set<\/span><span class=\"p\">;<\/span> <span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC19\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"kt\">string<\/span> <span class=\"n\">Slug<\/span> <span class=\"p\">{<\/span> <span class=\"k\">get<\/span><span class=\"p\">;<\/span> <span class=\"k\">set<\/span><span class=\"p\">;<\/span> <span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC20\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/1073216/6642f1fa06e1c4012cfeee1c20f071455b26f605/EditBlogInputModel.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/1073216#file_edit_blog_input_model.cs\" style=\"float:right;margin-right:10px;color:#666\">EditBlogInputModel.cs<\/a>\n            <a href=\"https://gist.github.com/1073216\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/1073216/EditBlogInputModel.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><h4>Step 2: Do the heavy lifting</h4><p>Now that I&#8217;ve marked which actions need authorization, I&#8217;m going to write an authorization policy so I can specify how that authorization needs to be done. In this case I want to verify that the post being requested belongs to the user that is requesting it. This is a simple example, but you can do any sort of complex checking here that you wanted (e.g. If it were possible that your users could be editors and edit other user&#8217;s posts, that check would go here.)</p><p>For my simple case, we can just check that the user property on the requested post, is the same user as the user that&#8217;s currently logged in. The CurrentUser dependency is what I use to get the currently logged in user. Use whatever your convention is to do that here, instead.</p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-1073216\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">PostAuthorizationPolicy<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">TModel<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IAuthorizationPolicy<\/span><\/div><div class=\'line\' id=\'LC2\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">where<\/span> <span class=\"n\">TModel<\/span> <span class=\"p\">:<\/span> <span class=\"n\">class<\/span><span class=\"p\">,<\/span> <span class=\"n\">IPostModel<\/span><\/div><div class=\'line\' id=\'LC3\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">private<\/span> <span class=\"k\">readonly<\/span> <span class=\"n\">IPostRepository<\/span> <span class=\"n\">_postRepository<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC5\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">private<\/span> <span class=\"k\">readonly<\/span> <span class=\"n\">CurrentUser<\/span> <span class=\"n\">_currentUser<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC6\'><br/><\/div><div class=\'line\' id=\'LC7\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"nf\">PostAuthorizationPolicy<\/span><span class=\"p\">(<\/span><span class=\"n\">IPostRepository<\/span> <span class=\"n\">postRepository<\/span><span class=\"p\">,<\/span> <span class=\"n\">CurrentUser<\/span> <span class=\"n\">currentUser<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC8\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC9\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">_postRepository<\/span> <span class=\"p\">=<\/span> <span class=\"n\">postRepository<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC10\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">_currentUser<\/span> <span class=\"p\">=<\/span> <span class=\"n\">currentUser<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC11\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC12\'><br/><\/div><div class=\'line\' id=\'LC13\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"n\">AuthorizationRight<\/span> <span class=\"nf\">RightsFor<\/span><span class=\"p\">(<\/span><span class=\"n\">IFubuRequest<\/span> <span class=\"n\">request<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC14\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC15\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">var<\/span> <span class=\"n\">model<\/span> <span class=\"p\">=<\/span> <span class=\"n\">request<\/span><span class=\"p\">.<\/span><span class=\"n\">Get<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">TModel<\/span><span class=\"p\">&gt;();<\/span><\/div><div class=\'line\' id=\'LC16\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"n\">model<\/span> <span class=\"p\">==<\/span> <span class=\"k\">null<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC17\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC18\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">return<\/span> <span class=\"n\">AuthorizationRight<\/span><span class=\"p\">.<\/span><span class=\"n\">Deny<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC19\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC20\'><br/><\/div><div class=\'line\' id=\'LC21\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">var<\/span> <span class=\"n\">post<\/span> <span class=\"p\">=<\/span> <span class=\"n\">_postRepository<\/span><span class=\"p\">.<\/span><span class=\"n\">GetById<\/span><span class=\"p\">(<\/span><span class=\"n\">model<\/span><span class=\"p\">.<\/span><span class=\"n\">PostId<\/span><span class=\"p\">);<\/span><\/div><div class=\'line\' id=\'LC22\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"n\">post<\/span> <span class=\"p\">==<\/span> <span class=\"k\">null<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC23\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC24\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">return<\/span> <span class=\"n\">AuthorizationRight<\/span><span class=\"p\">.<\/span><span class=\"n\">Deny<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC25\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC26\'><br/><\/div><div class=\'line\' id=\'LC27\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">return<\/span> <span class=\"n\">post<\/span><span class=\"p\">.<\/span><span class=\"n\">User<\/span><span class=\"p\">.<\/span><span class=\"n\">Id<\/span> <span class=\"p\">==<\/span> <span class=\"n\">_currentUser<\/span><span class=\"p\">.<\/span><span class=\"n\">UserId<\/span><\/div><div class=\'line\' id=\'LC28\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">?<\/span> <span class=\"n\">AuthorizationRight<\/span><span class=\"p\">.<\/span><span class=\"n\">Allow<\/span><\/div><div class=\'line\' id=\'LC29\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">:<\/span> <span class=\"n\">AuthorizationRight<\/span><span class=\"p\">.<\/span><span class=\"n\">Deny<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC30\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC31\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/1073216/a4c1d02d940aa5d05dbeaa0038c728c4a535ce77/PostAuthorizationPolicy.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/1073216#file_post_authorization_policy.cs\" style=\"float:right;margin-right:10px;color:#666\">PostAuthorizationPolicy.cs<\/a>\n            <a href=\"https://gist.github.com/1073216\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/1073216/PostAuthorizationPolicy.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><h4>Step 3: Teach FubuMVC about the convention</h4><p>So, I have my action calls setup that need authorization, and I&#8217;ve created a way to do that authorization, the next step is to tie the two together and tell FubuMVC how to apply my authorization policy.</p><p>FubuMVC has a DSL to do this, which can be accessed through the Authorization property on the behavior chain. The way this works is inside FubuMVC, <strong>after</strong> it has applied all of your conventions, it will check to see if there have been any policies added to the Authorization property on the behavior chain. If it finds that there has been, it will wrap the chain with an internal behavior called AuthorizationBehavior.</p><p>The way the AuthorizationBehavior works is by calling the authorization policies for the behavior and checking the return value of them. If <em>any</em> of the policies return AuthorizationRight.Deny, then the chain is stopped and IAuthorizationFailureHandler is called on to handle the erred request.</p><p>It&#8217;s very important that FubuMVC sets this convention up <strong>after</strong> it sets up all of the custom conventions. This ensures that the AuthenticationBehavior gets run before anything else in the behavior chain.</p><p>What I want to do is add a policy to the Authorization property for all action calls which have an input type that implements my IPostModel interface.</p><p>Since I made the policy an open generic, I&#8217;ll close that generic with the type that the action call is using. This is what allows the authorization policy to get the model out of the IFubuRequest (since things are keyed by type), which means I can check values specific to that particular request.</p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-1073216\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">PostAuthorizationConvention<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IConfigurationAction<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC3\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"k\">void<\/span> <span class=\"nf\">Configure<\/span><span class=\"p\">(<\/span><span class=\"n\">BehaviorGraph<\/span> <span class=\"n\">graph<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC5\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">graph<\/span><\/div><div class=\'line\' id=\'LC6\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">.<\/span><span class=\"n\">Behaviors<\/span><\/div><div class=\'line\' id=\'LC7\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">.<\/span><span class=\"n\">Where<\/span><span class=\"p\">(<\/span><span class=\"n\">c<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"k\">typeof<\/span> <span class=\"p\">(<\/span><span class=\"n\">IPostModel<\/span><span class=\"p\">).<\/span><span class=\"n\">IsAssignableFrom<\/span><span class=\"p\">(<\/span><span class=\"n\">c<\/span><span class=\"p\">.<\/span><span class=\"n\">InputType<\/span><span class=\"p\">()))<\/span><\/div><div class=\'line\' id=\'LC8\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">.<\/span><span class=\"n\">Each<\/span><span class=\"p\">(<\/span><span class=\"n\">chain<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"n\">chain<\/span><\/div><div class=\'line\' id=\'LC9\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">.<\/span><span class=\"n\">Authorization<\/span><\/div><div class=\'line\' id=\'LC10\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">.<\/span><span class=\"n\">AddPolicy<\/span><span class=\"p\">(<\/span><span class=\"k\">typeof<\/span> <span class=\"p\">(<\/span><span class=\"n\">PostAuthorizationPolicy<\/span><span class=\"p\">&lt;&gt;).<\/span><span class=\"n\">MakeGenericType<\/span><span class=\"p\">(<\/span><span class=\"n\">chain<\/span><span class=\"p\">.<\/span><span class=\"n\">InputType<\/span><span class=\"p\">())));<\/span><\/div><div class=\'line\' id=\'LC11\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC12\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/1073216/b05b460ecb3e63c5e0b59928455e4ed6c5ce5b47/PostAuthorizationConvention.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/1073216#file_post_authorization_convention.cs\" style=\"float:right;margin-right:10px;color:#666\">PostAuthorizationConvention.cs<\/a>\n            <a href=\"https://gist.github.com/1073216\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/1073216/PostAuthorizationConvention.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><h4>Step 4: Tell FubuMVC to use the convention</h4><p>Now that everything is all setup and I&#8217;ve defined how my convention works, I just have to tell FubuMVC to use the convention. To do this, in my FubuRegistry, I just add the following line.</p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-1073216\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"n\">Policies<\/span><span class=\"p\">.<\/span><span class=\"n\">Add<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">PostAuthorizationConvention<\/span><span class=\"p\">&gt;();<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/1073216/f72e6e35fe248d1f9756c08b428b211f1eb22da3/FubuRegistry.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/1073216#file_fubu_registry.cs\" style=\"float:right;margin-right:10px;color:#666\">FubuRegistry.cs<\/a>\n            <a href=\"https://gist.github.com/1073216\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/1073216/FubuRegistry.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><p>Now when I start up the application and browse to /post/edit/:id, I get a 403 forbidden message if the id is for a post that isn&#8217;t mine. If the post is mine, I&#8217;m allowed to pass right through to the rest of the chain.</p><h4>Bonus!</h4><p><em>What if I don&#8217;t want to return a 403 forbidden message? I want to do something unique and special!</em></p><p>Remember when I said that the AuthorizationBehavior will call on IAuthorizationFailureHandler if any of the policies go wrong in order to handle the authorization error? Well, all you have to do is implement your own IAuthorizationFailureHandler and tell FubuMVC to replace the default implementation with your custom one, in your FubuRegistry.</p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-1073216\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">CustomAuthorizationFailureHandler<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IAuthorizationFailureHandler<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC3\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">private<\/span> <span class=\"k\">readonly<\/span> <span class=\"n\">IOutputWriter<\/span> <span class=\"n\">_writer<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">private<\/span> <span class=\"k\">readonly<\/span> <span class=\"n\">IUrlRegistry<\/span> <span class=\"n\">_urlRegistry<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC5\'><br/><\/div><div class=\'line\' id=\'LC6\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"nf\">CustomAuthorizationFailureHandler<\/span><span class=\"p\">(<\/span><span class=\"n\">IOutputWriter<\/span> <span class=\"n\">writer<\/span><span class=\"p\">,<\/span> <span class=\"n\">IUrlRegistry<\/span> <span class=\"n\">urlRegistry<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC7\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC8\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">_writer<\/span> <span class=\"p\">=<\/span> <span class=\"n\">writer<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC9\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">_urlRegistry<\/span> <span class=\"p\">=<\/span> <span class=\"n\">urlRegistry<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC10\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC11\'><br/><\/div><div class=\'line\' id=\'LC12\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"k\">void<\/span> <span class=\"nf\">Handle<\/span><span class=\"p\">()<\/span><\/div><div class=\'line\' id=\'LC13\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC14\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"c1\">// Get the url to the login page, and redirect the user there!<\/span><\/div><div class=\'line\' id=\'LC15\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">var<\/span> <span class=\"n\">url<\/span> <span class=\"p\">=<\/span> <span class=\"n\">_urlRegistry<\/span><span class=\"p\">.<\/span><span class=\"n\">UrlFor<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">LoginRequestModel<\/span><span class=\"p\">());<\/span><\/div><div class=\'line\' id=\'LC16\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">_writer<\/span><span class=\"p\">.<\/span><span class=\"n\">RedirectToUrl<\/span><span class=\"p\">(<\/span><span class=\"n\">url<\/span><span class=\"p\">);<\/span><\/div><div class=\'line\' id=\'LC17\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC18\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/1073216/977c779008957040ce3940b93238e2753b036a77/CustomAuthorizationFailureHandler.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/1073216#file_custom_authorization_failure_handler.cs\" style=\"float:right;margin-right:10px;color:#666\">CustomAuthorizationFailureHandler.cs<\/a>\n            <a href=\"https://gist.github.com/1073216\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/1073216/CustomAuthorizationFailureHandler.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-1073216\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"n\">Services<\/span><span class=\"p\">(<\/span><span class=\"n\">x<\/span> <span class=\"p\">=&gt;<\/span><\/div><div class=\'line\' id=\'LC2\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC3\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">x<\/span><span class=\"p\">.<\/span><span class=\"n\">ReplaceService<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">IAuthorizationFailureHandler<\/span><span class=\"p\">,<\/span> <span class=\"n\">CustomAuthorizationFailureHandler<\/span><span class=\"p\">&gt;();<\/span><\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">});<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/1073216/649775eff34393f2a030b460cb57c1c40bdb36c0/CustomFubuRegistry.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/1073216#file_custom_fubu_registry.cs\" style=\"float:right;margin-right:10px;color:#666\">CustomFubuRegistry.cs<\/a>\n            <a href=\"https://gist.github.com/1073216\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/1073216/CustomFubuRegistry.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><p>Now when I attempt to browse to /post/edit/:id, if I don&#8217;t own the post, I get redirected to the login screen.</p> ]]></content:encoded> <wfw:commentRss>http://rexflex.net/2011/07/fubumvc-authorization/feed/</wfw:commentRss> <slash:comments>7</slash:comments> </item> <item><title>FubuMVC: Authentication</title><link>http://rexflex.net/2011/07/fubumvc-authentication/</link> <comments>http://rexflex.net/2011/07/fubumvc-authentication/#comments</comments> <pubDate>Fri, 08 Jul 2011 02:34:59 +0000</pubDate> <dc:creator>Rex Morgan</dc:creator> <category><![CDATA[C#]]></category> <category><![CDATA[FubuMVC]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[Web Development]]></category><guid isPermaLink="false">http://rexflex.net/?p=378</guid> <description><![CDATA[If you&#8217;re using FubuMVC and your site requires users to login, you&#8217;ll probably want to use the built in authentication facilities that FubuMVC provides. In this post, I&#8217;ll attempt to explain how this works. I&#8217;m going to write an authentication convention to block access to certain actions from unauthenticated users. Overview Come up with a [...]]]></description> <content:encoded><![CDATA[<p>If you&#8217;re using FubuMVC and your site requires users to login, you&#8217;ll probably want to use the built in authentication facilities that FubuMVC provides. In this post, I&#8217;ll attempt to explain how this works.</p><p>I&#8217;m going to write an authentication convention to block access to certain actions from unauthenticated users.</p><h4>Overview</h4><ol><li><span>Come up with a convention to determine which action calls require the user to be authenticated</span></li><li><span>Write a behavior to redirect a user if they&#8217;re not authenticated</span></li><li><span>Teach FubuMVC about the convention</span></li><li><span>Tell FubuMVC to use the convention</span></li><li><span>Let FubuMVC know when someone has logged in or out</span></li></ol><h4>Step 1: Come up with a convention</h4><p>For this example, my convention is going to be any action call marked with a [Secured] attribute, will require an authenticated user in order to execute. As you&#8217;ll see, this can be adapted to match whatever convention you want to use.</p><p>To start, I&#8217;ll just create a simple marker attribute and throw it on the action calls that I want to be secured.<br /><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-1070895\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">SecuredAttribute<\/span> <span class=\"p\">:<\/span> <span class=\"n\">Attribute<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC3\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/1070895/a39587fef00afcdf644e701fe670a6f6400ef2a9/SecuredAttribute.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/1070895#file_secured_attribute.cs\" style=\"float:right;margin-right:10px;color:#666\">SecuredAttribute.cs<\/a>\n            <a href=\"https://gist.github.com/1070895\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/1070895/SecuredAttribute.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div></p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-1070895\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">DashboardEndpoint<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC3\'><span class=\"na\">    [Secured]<\/span><\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"n\">DashboardRequestModel<\/span> <span class=\"nf\">Get<\/span><span class=\"p\">(<\/span><span class=\"n\">DashboardRequestModel<\/span> <span class=\"n\">input<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC5\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC6\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nf\">DashboardRequestModel<\/span><span class=\"p\">();<\/span><\/div><div class=\'line\' id=\'LC7\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC8\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/1070895/a75881959ddbf50058e97a0f3b9ca0b688d7bc38/DashboardEndpoint.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/1070895#file_dashboard_endpoint.cs\" style=\"float:right;margin-right:10px;color:#666\">DashboardEndpoint.cs<\/a>\n            <a href=\"https://gist.github.com/1070895\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/1070895/DashboardEndpoint.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><p>Since we&#8217;ve marked the action calls that we want to secure, we&#8217;ll be able to pick them out later when we want to teach FubuMVC about our convention.</p><h4>Step 2: Write a behavior</h4><p>In order to do the actual work of checking to see if the user is logged in, and redirecting them if they&#8217;re not, I&#8217;ll need to create a behavior. If you&#8217;re unfamiliar with behaviors, I&#8217;d highly recommend reading <a href="http://lostechies.com/chadmyers/2011/06/23/cool-stuff-in-fubumvc-no-1-behaviors/">these articles</a> <a href="http://guides.fubumvc.com/advanced_behaviors.html">about</a> <a href="http://murrayon.net/2011/06/fubumvc-behavior-chains-bmvc-pattern.html">them</a>.</p><p>The behavior will depend on the ISecurityContext provided by FubuMVC, so I can check if the user has been authenticated. If the user has not been authenticated, I&#8217;ll just redirect them to the login page.</p><p>It&#8217;s important to note that, by default, the ISecurityContext is a wrapper around the current HttpContext. This means that FubuMVC is really just using standard ASP.NET forms authentication.</p><p>When FubuMVC calls the behavior, it will look at the result coming from the performInvoke() method. If the method returns DoNext.Continue, then the next behavior in the chain will be called. However, if it returns DoNext.Stop, then it will not call the next behavior in the chain and execution of the request stops. <em>(It actually doesn&#8217;t just stop, if you&#8217;ve been through any behaviors that wrap the authentication behavior, you will begin to start calling the afterInsideBehavior method on these.</em></p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-1070895\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">AuthenticationRequiredBehavior<\/span> <span class=\"p\">:<\/span> <span class=\"n\">BasicBehavior<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC3\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">private<\/span> <span class=\"k\">readonly<\/span> <span class=\"n\">ISecurityContext<\/span> <span class=\"n\">_securityContext<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">private<\/span> <span class=\"k\">readonly<\/span> <span class=\"n\">IUrlRegistry<\/span> <span class=\"n\">_urlRegistry<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC5\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">private<\/span> <span class=\"k\">readonly<\/span> <span class=\"n\">IOutputWriter<\/span> <span class=\"n\">_outputWriter<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC6\'><br/><\/div><div class=\'line\' id=\'LC7\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"nf\">AuthenticationRequiredBehavior<\/span><span class=\"p\">(<\/span><span class=\"n\">ISecurityContext<\/span> <span class=\"n\">securityContext<\/span><span class=\"p\">,<\/span> <span class=\"n\">IUrlRegistry<\/span> <span class=\"n\">urlRegistry<\/span><span class=\"p\">,<\/span> <span class=\"n\">IOutputWriter<\/span> <span class=\"n\">outputWriter<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC8\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">:<\/span> <span class=\"k\">base<\/span><span class=\"p\">(<\/span><span class=\"n\">PartialBehavior<\/span><span class=\"p\">.<\/span><span class=\"n\">Ignored<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC9\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC10\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">_securityContext<\/span> <span class=\"p\">=<\/span> <span class=\"n\">securityContext<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC11\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">_urlRegistry<\/span> <span class=\"p\">=<\/span> <span class=\"n\">urlRegistry<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC12\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">_outputWriter<\/span> <span class=\"p\">=<\/span> <span class=\"n\">outputWriter<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC13\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC14\'><br/><\/div><div class=\'line\' id=\'LC15\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">protected<\/span> <span class=\"k\">override<\/span> <span class=\"n\">DoNext<\/span> <span class=\"nf\">performInvoke<\/span><span class=\"p\">()<\/span><\/div><div class=\'line\' id=\'LC16\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC17\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">if<\/span><span class=\"p\">(<\/span><span class=\"n\">_securityContext<\/span><span class=\"p\">.<\/span><span class=\"n\">IsAuthenticated<\/span><span class=\"p\">())<\/span><\/div><div class=\'line\' id=\'LC18\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC19\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">return<\/span> <span class=\"n\">DoNext<\/span><span class=\"p\">.<\/span><span class=\"n\">Continue<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC20\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC21\'><br/><\/div><div class=\'line\' id=\'LC22\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">var<\/span> <span class=\"n\">url<\/span> <span class=\"p\">=<\/span> <span class=\"n\">_urlRegistry<\/span><span class=\"p\">.<\/span><span class=\"n\">UrlFor<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">LoginRequestModel<\/span><span class=\"p\">());<\/span><\/div><div class=\'line\' id=\'LC23\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">_outputWriter<\/span><span class=\"p\">.<\/span><span class=\"n\">RedirectToUrl<\/span><span class=\"p\">(<\/span><span class=\"n\">url<\/span><span class=\"p\">);<\/span><\/div><div class=\'line\' id=\'LC24\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">return<\/span> <span class=\"n\">DoNext<\/span><span class=\"p\">.<\/span><span class=\"n\">Stop<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC25\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC26\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/1070895/c8301d9052c28bd72558bd4285cba4bd4a7c51e2/AuthenticationRequiredBehavior.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/1070895#file_authentication_required_behavior.cs\" style=\"float:right;margin-right:10px;color:#666\">AuthenticationRequiredBehavior.cs<\/a>\n            <a href=\"https://gist.github.com/1070895\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/1070895/AuthenticationRequiredBehavior.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><h4>Step 3: Teach FubuMVC about the convention</h4><p>So I&#8217;ve setup our action calls to use the convention and the behavior to kick unauthorized people out. Now I just need to teach FubuMVC what that convention is, and how it should be implemented. In order to do that, I&#8217;ll need to create an implementation of the IConfigurationAction interface <em>(these are typically called conventions.)</em> My convention will modify the graph and wrap all action calls that have the Secured attribute with our behavior.</p><p>In the convention, I have access to all of the Actions that FubuMVC knows about. I&#8217;m able to filter those actions to only get those which implement the SecuredAttribute, and then wrap those with the behavior I just created.</p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-1070895\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">AuthenticationConvention<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IConfigurationAction<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC3\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"k\">void<\/span> <span class=\"nf\">Configure<\/span><span class=\"p\">(<\/span><span class=\"n\">BehaviorGraph<\/span> <span class=\"n\">graph<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC5\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">graph<\/span><\/div><div class=\'line\' id=\'LC6\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">.<\/span><span class=\"n\">Actions<\/span><span class=\"p\">()<\/span><\/div><div class=\'line\' id=\'LC7\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">.<\/span><span class=\"n\">Where<\/span><span class=\"p\">(<\/span><span class=\"n\">c<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"n\">c<\/span><span class=\"p\">.<\/span><span class=\"n\">HasAttribute<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">SecuredAttribute<\/span><span class=\"p\">&gt;())<\/span><\/div><div class=\'line\' id=\'LC8\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">.<\/span><span class=\"n\">Each<\/span><span class=\"p\">(<\/span><span class=\"n\">c<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"n\">c<\/span><span class=\"p\">.<\/span><span class=\"n\">WrapWith<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">AuthenticationRequiredBehavior<\/span><span class=\"p\">&gt;());<\/span><\/div><div class=\'line\' id=\'LC9\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC10\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/1070895/0ae1bbb071c44bd559f20ab8f9e723086fc25866/AuthenticationConvention.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/1070895#file_authentication_convention.cs\" style=\"float:right;margin-right:10px;color:#666\">AuthenticationConvention.cs<\/a>\n            <a href=\"https://gist.github.com/1070895\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/1070895/AuthenticationConvention.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><p>This is where I could change it up and use another convention if I wanted to. Instead of filtering the actions based on attributes, I can check for anything. If I wanted to filter for all actions with an input type that starts with &#8220;Add&#8221; or &#8220;Edit&#8221;, that&#8217;s possible by using this convention.<br /><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-1070895\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"n\">graph<\/span><\/div><div class=\'line\' id=\'LC2\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">.<\/span><span class=\"n\">Actions<\/span><span class=\"p\">()<\/span><\/div><div class=\'line\' id=\'LC3\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">.<\/span><span class=\"n\">Where<\/span><span class=\"p\">(<\/span><span class=\"n\">c<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"n\">c<\/span><span class=\"p\">.<\/span><span class=\"n\">HasInput<\/span> <span class=\"p\">&amp;&amp;<\/span> <span class=\"n\">c<\/span><span class=\"p\">.<\/span><span class=\"n\">InputType<\/span><span class=\"p\">().<\/span><span class=\"n\">Name<\/span><span class=\"p\">.<\/span><span class=\"n\">StartsWith<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;Add&quot;<\/span><span class=\"p\">)<\/span> <span class=\"p\">||<\/span> <span class=\"n\">c<\/span><span class=\"p\">.<\/span><span class=\"n\">InputType<\/span><span class=\"p\">().<\/span><span class=\"n\">Name<\/span><span class=\"p\">.<\/span><span class=\"n\">StartsWith<\/span><span class=\"p\">(<\/span><span class=\"s\">&quot;Edit&quot;<\/span><span class=\"p\">))<\/span><\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">.<\/span><span class=\"n\">Each<\/span><span class=\"p\">(<\/span><span class=\"n\">c<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"n\">c<\/span><span class=\"p\">.<\/span><span class=\"n\">WrapWith<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">AuthenticationRequiredBehavior<\/span><span class=\"p\">&gt;());<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/1070895/91a04e602a34c6e6044eb27b352a83db48768621/AlternateConvention.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/1070895#file_alternate_convention.cs\" style=\"float:right;margin-right:10px;color:#666\">AlternateConvention.cs<\/a>\n            <a href=\"https://gist.github.com/1070895\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/1070895/AlternateConvention.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div></p><h4>Step 4: Tell FubuMVC to use the convention</h4><p>In order to tell FubuMVC to apply the convention, I need to call this method from the FubuRegistry.<br /><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-1070895\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"n\">ApplyConvention<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">AuthenticationConvention<\/span><span class=\"p\">&gt;();<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/1070895/f6803f9ef3fabb14790d047f86fd41a9a89d96c8/FubuRegistry.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/1070895#file_fubu_registry.cs\" style=\"float:right;margin-right:10px;color:#666\">FubuRegistry.cs<\/a>\n            <a href=\"https://gist.github.com/1070895\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/1070895/FubuRegistry.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div></p><p>Now, if I run my project and attempt to browse to an action that has been locked down, I get redirected to the login page, which is exactly what I wanted it to do.</p><h4>Step 5: Let FubuMVC know when someone has logged in or out</h4><p>In order to tell FubuMVC that a user has been logged in, I need to depend on IAuthenticationContext in the action that logs users in. Once I&#8217;ve verified the user&#8217;s credentials are correct, I can call the ThisUserHasBeenAuthenticated method on IAuthenticationContext to let FubuMVC know.</p><p>When I want to log a user out, call SignOut on the IAuthenticationContext interface.</p><h4>Gotcha!</h4><p>As I stated earlier, the default authentication in FubuMVC is really just a wrapper for forms authentication in ASP.NET. So, in order to use the ISecurityContext, you&#8217;ll need to turn on forms authentication in your web.config, otherwise the ISecurityContext will always say that the user is authenticated.<br /><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-1070895\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'>&lt;system.web&gt;<\/div><div class=\'line\' id=\'LC2\'>&nbsp;&nbsp;&lt;authentication mode=&quot;Forms&quot;&gt;<\/div><div class=\'line\' id=\'LC3\'>&nbsp;&nbsp;&nbsp;&nbsp;&lt;forms loginUrl=&quot;~/login&quot; timeout=&quot;25&quot; slidingExpiration=&quot;true&quot; /&gt;<\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&lt;/authentication&gt;<\/div><div class=\'line\' id=\'LC5\'>&lt;/system.web&gt;<\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/1070895/5e45d6f6bd274f73dcaa70a551b522a116dde25c/Web.config\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/1070895#file_web.config\" style=\"float:right;margin-right:10px;color:#666\">Web.config<\/a>\n            <a href=\"https://gist.github.com/1070895\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/1070895/Web.config&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div></p> ]]></content:encoded> <wfw:commentRss>http://rexflex.net/2011/07/fubumvc-authentication/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> <item><title>Sony Cares A LOT</title><link>http://rexflex.net/2011/05/sony-cares-a-lot/</link> <comments>http://rexflex.net/2011/05/sony-cares-a-lot/#comments</comments> <pubDate>Mon, 09 May 2011 16:43:57 +0000</pubDate> <dc:creator>Rex Morgan</dc:creator> <category><![CDATA[Upsetting]]></category><guid isPermaLink="false">http://rexflex.net/?p=349</guid> <description><![CDATA[I rebooted my computer this morning when I got into work and it was running pretty sluggish. I checked my processes and found the &#8220;VAIO Care&#8221; application was using almost 3GB of memory&#8230; Thanks a lot Sony, for caring so much.]]></description> <content:encoded><![CDATA[<p><a href="http://c520208.r8.cf2.rackcdn.com/wp-content/uploads/2011/05/vaioCare.png"><img class="alignleft size-thumbnail wp-image-350" title="Sony Cares" src="http://c520208.r8.cf2.rackcdn.com/wp-content/uploads/2011/05/vaioCare-150x123.png" alt="Wow, thanks for caring so much, Sony" width="150" height="123" /></a>I rebooted my computer this morning when I got into work and it was running pretty sluggish. I checked my processes and found the &#8220;VAIO Care&#8221; application was using almost 3GB of memory&#8230; Thanks a lot Sony, for caring so much.</p> ]]></content:encoded> <wfw:commentRss>http://rexflex.net/2011/05/sony-cares-a-lot/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Possible Shortcomings of Groupon</title><link>http://rexflex.net/2011/05/possible-shortcomings-of-groupon/</link> <comments>http://rexflex.net/2011/05/possible-shortcomings-of-groupon/#comments</comments> <pubDate>Wed, 04 May 2011 18:30:00 +0000</pubDate> <dc:creator>Rex Morgan</dc:creator> <category><![CDATA[Marketing]]></category><guid isPermaLink="false">http://rexflex.net/?p=255</guid> <description><![CDATA[The other day I was reading an article titled Grouponed to death? at The CX Rx. It hit a lot of points that I&#8217;ve always thought about these deal sites like Groupon, Living Social, and the 100&#8242;s of other clones that have been popping up. To put the rest of the article into context, it&#8217;s [...]]]></description> <content:encoded><![CDATA[<p>The other day I was reading an article titled <a href="http://thecxrx.wordpress.com/2011/03/28/grouponed-to-death/">Grouponed to death?</a> at The CX Rx. It hit a lot of points that I&#8217;ve always thought about these deal sites like Groupon, Living Social, and the 100&#8242;s of other clones that have been popping up.</p><p><em>To put the rest of the article into context, it&#8217;s important to know that Groupon works by selling coupons for a business&#8217;s service. The business agrees to give a discount of at least 50% and also agrees to give Groupon 50% of the revenue they take in from the coupons. This means that the business gets 25% of the list price for their product or service. At least, that&#8217;s how I understand it.</em></p><p>I&#8217;m not a business owner, but it&#8217;s hard for me to rationalize why any business would give up 50% of their, already cut in half revenue, providing their product or service for 25¢ on the dollar of their normal prices.</p><p>It&#8217;s hard to believe that you would actually turn over loyal customers and instead it seems like you&#8217;d get plenty of people coming to get a good deal, then never coming back. As <a href="http://themarketingspot.com/2010/12/email-coupons-way-kill-your-business.html">Jay Ehret</a> puts it:</p><blockquote><p>The thought process goes like this: I get a new customer by giving them a discount: 50% off. They will appreciate the discount, see how great we are, and become a new customer. But that’s not how the customer thinks. They get their coupon, buy your stuff, and they like it. Then you ask them to buy again, but now you’ve doubled the price!</p></blockquote><p>At the same time, you&#8217;re alienating your current customers by giving deep discounts to new customers, and offering nothing to the loyal customers that have been keeping you in business up until then.</p><p>I&#8217;m sure this isn&#8217;t a new idea, but I would like to see tools that allow your current customers to tap into their own social network. Reward both the current customer and the new customers they&#8217;re able to bring to your business. Provide coupons to both. If you&#8217;re not giving a middle-man 50% of the reduced profits, you might even be able to offer discounts comparable to Groupon, without going out of business.</p> ]]></content:encoded> <wfw:commentRss>http://rexflex.net/2011/05/possible-shortcomings-of-groupon/feed/</wfw:commentRss> <slash:comments>8</slash:comments> </item> <item><title>Blogging again&#8230; ?</title><link>http://rexflex.net/2011/04/blogging-again/</link> <comments>http://rexflex.net/2011/04/blogging-again/#comments</comments> <pubDate>Sat, 16 Apr 2011 14:30:00 +0000</pubDate> <dc:creator>Rex Morgan</dc:creator> <category><![CDATA[Blogging]]></category><guid isPermaLink="false">http://rexflex.net/?p=274</guid> <description><![CDATA[Every year or so I seem to have a post claiming that I&#8217;m going to start blogging again. Normally it coincides with my yearly hosting bill being due. This is another one of those posts, except this time I think it&#8217;s for real. Maybe? I hope so. More to come.]]></description> <content:encoded><![CDATA[<p>Every year or so I seem to have a post claiming that I&#8217;m going to start blogging again. Normally it coincides with my yearly hosting bill being due. This is another one of those posts, except this time I think it&#8217;s for real. Maybe? I hope so. More to come.</p> ]]></content:encoded> <wfw:commentRss>http://rexflex.net/2011/04/blogging-again/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Working with Partials in FubuMVC</title><link>http://rexflex.net/2010/11/working-with-partials-in-fubumvc/</link> <comments>http://rexflex.net/2010/11/working-with-partials-in-fubumvc/#comments</comments> <pubDate>Thu, 04 Nov 2010 17:10:54 +0000</pubDate> <dc:creator>Rex Morgan</dc:creator> <category><![CDATA[C#]]></category> <category><![CDATA[FubuMVC]]></category> <category><![CDATA[Programming]]></category> <category><![CDATA[Web Development]]></category> <category><![CDATA[partial views]]></category><guid isPermaLink="false">http://rexflex.net/?p=216</guid> <description><![CDATA[Today I was working on getting a partial view working properly in FubuMVC and started trying stumbling through it, very unsuccessfully. I ended up reaching out to Joshua Arnold for help with it. I&#8217;d like to share it with everyone that might be having trouble with them. The way we&#8217;re going to be doing our [...]]]></description> <content:encoded><![CDATA[<p>Today I was working on getting a partial view working properly in FubuMVC and started trying stumbling through it, very unsuccessfully. I ended up reaching out to <a href="http://twitter.com/jmarnold">Joshua Arnold</a> for help with it. I&#8217;d like to share it with everyone that might be having trouble with them.</p><p>The way we&#8217;re going to be doing our partials is by having the concept of an action extension which can be called by our partial action. It&#8217;s a little difficult to explain, so let&#8217;s get right into the code. I&#8217;ll be <em>emphasizing</em> all of the gotchas that I ran into, to hopefully help explain things a little better.</p><p><em>With all of the generics, things can get a little confusing. The generic parameter in all of these classes is going to be the model that you&#8217;re working with. What we&#8217;re really building here is a very maintainable &quot;model modifier&quot;.</em></p><p>To start off, let&#8217;s create our partial action. We&#8217;ll be using a generic action that we&#8217;re calling PartialAction. <em>It is important to note that this is the action that&#8217;s going to get called when you call your partials. Since it&#8217;s generic, we&#8217;re going be calling it for <strong>all</strong> of our partial views.</em></p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-661992\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">PartialAction<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">T<\/span><span class=\"p\">&gt;<\/span><\/div><div class=\'line\' id=\'LC2\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">where<\/span> <span class=\"n\">T<\/span> <span class=\"p\">:<\/span> <span class=\"k\">class<\/span><\/div><div class=\'line\' id=\'LC3\'><span class=\"err\">{<\/span><\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">private<\/span> <span class=\"k\">readonly<\/span> <span class=\"n\">IPartialActionExtensionGraph<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">T<\/span><span class=\"p\">&gt;<\/span> <span class=\"n\">_graph<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC5\'><br/><\/div><div class=\'line\' id=\'LC6\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"nf\">PartialAction<\/span><span class=\"p\">(<\/span><span class=\"n\">IPartialActionExtensionGraph<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">T<\/span><span class=\"p\">&gt;<\/span> <span class=\"n\">graph<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC7\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC8\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">_graph<\/span> <span class=\"p\">=<\/span> <span class=\"n\">graph<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC9\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC10\'><br/><\/div><div class=\'line\' id=\'LC11\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"n\">T<\/span> <span class=\"nf\">Execute<\/span><span class=\"p\">(<\/span><span class=\"n\">T<\/span> <span class=\"n\">input<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC12\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC13\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">return<\/span> <span class=\"n\">_graph<\/span><span class=\"p\">.<\/span><span class=\"n\">Modify<\/span><span class=\"p\">(<\/span><span class=\"n\">input<\/span><span class=\"p\">);<\/span><\/div><div class=\'line\' id=\'LC14\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC15\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/661992/35c29514f99d36be0ca8aac58397474cb1e5d564/PartialAction.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/661992#file_partial_action.cs\" style=\"float:right;margin-right:10px;color:#666\">PartialAction.cs<\/a>\n            <a href=\"https://gist.github.com/661992\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/661992/PartialAction.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><p>As you can see, we have a dependency on and IPartialActionExtensionGraph. That&#8217;s a simple interface that has a single method, Modify. Since we&#8217;re going to be calling Modify on our Graph the same way as we call Modify on a single action extension, they share a common interface.</p><p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-661992\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">interface<\/span> <span class=\"n\">IPartialActionExtensionGraph<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">T<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IPartialActionExtension<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">T<\/span><span class=\"p\">&gt;<\/span><\/div><div class=\'line\' id=\'LC2\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">where<\/span> <span class=\"n\">T<\/span> <span class=\"p\">:<\/span> <span class=\"k\">class<\/span><\/div><div class=\'line\' id=\'LC3\'><span class=\"err\">{<\/span><\/div><div class=\'line\' id=\'LC4\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/661992/7880c8b2e89a3a78b8ecc254eb3f86d43f1b67dd/IPartialActionExtensionGraph.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/661992#file_i_partial_action_extension_graph.cs\" style=\"float:right;margin-right:10px;color:#666\">IPartialActionExtensionGraph.cs<\/a>\n            <a href=\"https://gist.github.com/661992\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/661992/IPartialActionExtensionGraph.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><br /><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-661992\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">interface<\/span> <span class=\"n\">IPartialActionExtension<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">T<\/span><span class=\"p\">&gt;<\/span><\/div><div class=\'line\' id=\'LC2\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">where<\/span> <span class=\"n\">T<\/span> <span class=\"p\">:<\/span> <span class=\"k\">class<\/span><\/div><div class=\'line\' id=\'LC3\'><span class=\"err\">{<\/span><\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">T<\/span> <span class=\"nf\">Modify<\/span><span class=\"p\">(<\/span><span class=\"n\">T<\/span> <span class=\"n\">model<\/span><span class=\"p\">);<\/span><\/div><div class=\'line\' id=\'LC5\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/661992/16bf31f4a02e735dda0056687f157f65d9c156c1/IPartialActionExtension.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/661992#file_i_partial_action_extension.cs\" style=\"float:right;margin-right:10px;color:#666\">IPartialActionExtension.cs<\/a>\n            <a href=\"https://gist.github.com/661992\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/661992/IPartialActionExtension.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div></p><p>Now we&#8217;re going to create a generic implementation for the action extension graph. We&#8217;ll want to call the Modify method on all of the action extensions that close the interface with the same type. We&#8217;re going to use our IoC container to keep track of all our implementations, in this case we&#8217;re using StructureMap, but you could probably use this with any dependency injection tool.</p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-661992\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">PartialActionExtensionGraph<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">T<\/span><span class=\"p\">&gt;<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IPartialActionExtensionGraph<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">T<\/span><span class=\"p\">&gt;<\/span><\/div><div class=\'line\' id=\'LC2\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">where<\/span> <span class=\"n\">T<\/span> <span class=\"p\">:<\/span> <span class=\"k\">class<\/span><\/div><div class=\'line\' id=\'LC3\'><span class=\"err\">{<\/span><\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">private<\/span> <span class=\"k\">readonly<\/span> <span class=\"n\">IContainer<\/span> <span class=\"n\">_container<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC5\'><br/><\/div><div class=\'line\' id=\'LC6\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"nf\">PartialActionExtensionGraph<\/span><span class=\"p\">(<\/span><span class=\"n\">IContainer<\/span> <span class=\"n\">container<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC7\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC8\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">_container<\/span> <span class=\"p\">=<\/span> <span class=\"n\">container<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC9\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC10\'><br/><\/div><div class=\'line\' id=\'LC11\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"n\">T<\/span> <span class=\"nf\">Modify<\/span><span class=\"p\">(<\/span><span class=\"n\">T<\/span> <span class=\"n\">model<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC12\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC13\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">_container<\/span><span class=\"p\">.<\/span><span class=\"n\">GetAllInstances<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">IPartialActionExtension<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">T<\/span><span class=\"p\">&gt;&gt;()<\/span><\/div><div class=\'line\' id=\'LC14\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">.<\/span><span class=\"n\">Each<\/span><span class=\"p\">(<\/span><span class=\"n\">extension<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"n\">model<\/span> <span class=\"p\">=<\/span> <span class=\"n\">extension<\/span><span class=\"p\">.<\/span><span class=\"n\">Modify<\/span><span class=\"p\">(<\/span><span class=\"n\">model<\/span><span class=\"p\">));<\/span><\/div><div class=\'line\' id=\'LC15\'><br/><\/div><div class=\'line\' id=\'LC16\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">return<\/span> <span class=\"n\">model<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC17\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC18\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/661992/57cb4212fbfd5d9860cc584b979fd56dc50110ca/PartialActionExtensionGraph.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/661992#file_partial_action_extension_graph.cs\" style=\"float:right;margin-right:10px;color:#666\">PartialActionExtensionGraph.cs<\/a>\n            <a href=\"https://gist.github.com/661992\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/661992/PartialActionExtensionGraph.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><p>To load up StructureMap with all our action extensions, we&#8217;ll want to use this registry &amp; registry convention while we bootstrap StructureMap. This awesome piece of code is from Josh, so please go thank him. It will search through our entire assembly and find any types that close the interface IPartialActionExtension&lt;&gt;, that is not an interface, and is not abstract. <em>Please note that the Closes and FindInterfaceThatCloses extension methods are part of FubuCore.</em></p><p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-661484\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">PartialActionExtensionsRegistry<\/span> <span class=\"p\">:<\/span> <span class=\"n\">Registry<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC3\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"nf\">PartialActionExtensionsRegistry<\/span><span class=\"p\">()<\/span><\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC5\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">Scan<\/span><span class=\"p\">(<\/span><span class=\"n\">x<\/span> <span class=\"p\">=&gt;<\/span><\/div><div class=\'line\' id=\'LC6\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC7\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">x<\/span><span class=\"p\">.<\/span><span class=\"n\">TheCallingAssembly<\/span><span class=\"p\">();<\/span><\/div><div class=\'line\' id=\'LC8\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">x<\/span><span class=\"p\">.<\/span><span class=\"n\">Include<\/span><span class=\"p\">(<\/span><span class=\"n\">type<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"n\">type<\/span><span class=\"p\">.<\/span><span class=\"n\">Closes<\/span><span class=\"p\">(<\/span><span class=\"k\">typeof<\/span><span class=\"p\">(<\/span><span class=\"n\">IPartialActionExtension<\/span><span class=\"p\">&lt;&gt;)));<\/span><\/div><div class=\'line\' id=\'LC9\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">x<\/span><span class=\"p\">.<\/span><span class=\"n\">Exclude<\/span><span class=\"p\">(<\/span><span class=\"n\">type<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"n\">type<\/span><span class=\"p\">.<\/span><span class=\"n\">IsInterface<\/span><span class=\"p\">);<\/span><\/div><div class=\'line\' id=\'LC10\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">x<\/span><span class=\"p\">.<\/span><span class=\"n\">Exclude<\/span><span class=\"p\">(<\/span><span class=\"n\">type<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"n\">type<\/span><span class=\"p\">.<\/span><span class=\"n\">IsAbstract<\/span><span class=\"p\">);<\/span><\/div><div class=\'line\' id=\'LC11\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">x<\/span><span class=\"p\">.<\/span><span class=\"n\">With<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">PartialActionExtensionsConvention<\/span><span class=\"p\">());<\/span><\/div><div class=\'line\' id=\'LC12\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">});<\/span><\/div><div class=\'line\' id=\'LC13\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC14\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/661484/cda31963477f4766853f77a2dd90eca82039c9dd/PartialActionExtensionsRegistry.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/661484#file_partial_action_extensions_registry.cs\" style=\"float:right;margin-right:10px;color:#666\">PartialActionExtensionsRegistry.cs<\/a>\n            <a href=\"https://gist.github.com/661484\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/661484/PartialActionExtensionsRegistry.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><br /><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-661484\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">PartialActionExtensionsConvention<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IRegistrationConvention<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC3\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"k\">void<\/span> <span class=\"nf\">Process<\/span><span class=\"p\">(<\/span><span class=\"n\">Type<\/span> <span class=\"n\">type<\/span><span class=\"p\">,<\/span> <span class=\"n\">Registry<\/span> <span class=\"n\">registry<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC5\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">var<\/span> <span class=\"n\">extensionType<\/span> <span class=\"p\">=<\/span> <span class=\"n\">type<\/span><span class=\"p\">.<\/span><span class=\"n\">FindInterfaceThatCloses<\/span><span class=\"p\">(<\/span><span class=\"k\">typeof<\/span><span class=\"p\">(<\/span><span class=\"n\">IPartialActionExtension<\/span><span class=\"p\">&lt;&gt;));<\/span><\/div><div class=\'line\' id=\'LC6\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">if<\/span><span class=\"p\">(<\/span><span class=\"n\">extensionType<\/span> <span class=\"p\">==<\/span> <span class=\"k\">null<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC7\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC8\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">return<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC9\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC10\'><br/><\/div><div class=\'line\' id=\'LC11\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">registry<\/span><\/div><div class=\'line\' id=\'LC12\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">.<\/span><span class=\"n\">For<\/span><span class=\"p\">(<\/span><span class=\"n\">extensionType<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC13\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">.<\/span><span class=\"n\">Add<\/span><span class=\"p\">(<\/span><span class=\"n\">type<\/span><span class=\"p\">);<\/span><\/div><div class=\'line\' id=\'LC14\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC15\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/661484/a94954b7a351b852c0e99a41e4a1becbc373686a/PartialActionExtensionsConvention.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/661484#file_partial_action_extensions_convention.cs\" style=\"float:right;margin-right:10px;color:#666\">PartialActionExtensionsConvention.cs<\/a>\n            <a href=\"https://gist.github.com/661484\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/661484/PartialActionExtensionsConvention.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div></p><p>Now that our action is setup, we&#8217;ll build our model. Until this point, we&#8217;ve been dealing with the plumbing to get the partial views to work. So I&#8217;ll explain what we&#8217;re about to write. On our master page, we want to see either a &quot;Login&quot; link if the user has not logged in, yet or a &quot;Logout&quot; link if the user is already logged in. Pretty simple. <em>As you can see from the PartialAction class, our input and output model will be the same. So we just need to write the model that will be used by the view.</em></p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-661992\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"na\">[PartialModel]<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">MasterLoginLogoutModel<\/span><\/div><div class=\'line\' id=\'LC3\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"kt\">bool<\/span> <span class=\"n\">IsAuthenticated<\/span> <span class=\"p\">{<\/span> <span class=\"k\">get<\/span><span class=\"p\">;<\/span> <span class=\"k\">set<\/span><span class=\"p\">;<\/span> <span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC5\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/661992/5913d48b7656e462bee2318a6ac73f515aa8c92c/MasterLoginLogoutModel.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/661992#file_master_login_logout_model.cs\" style=\"float:right;margin-right:10px;color:#666\">MasterLoginLogoutModel.cs<\/a>\n            <a href=\"https://gist.github.com/661992\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/661992/MasterLoginLogoutModel.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><p>Note the PartialModel attribute. This is very important, because this is what we&#8217;ll use to tell FubuMVC to link it up to the PartialAction class.</p><p>In order for FubuMVC to know what to do, we&#8217;ll need to setup our behavior chains for the input model that we just built. This is where things get a little more complicated, but we&#8217;ll go through it step-by-step. We need to create action calls for each of our models, so let&#8217;s create an action source.</p><p>Our action source will be fairly simple. We&#8217;ll find all our classes that are marked with the PartialModel attribute, close the PartialAction&lt;&gt; action with this type, and create an action call for it. <em>Please note that the GetExecuteMethod method is a Type extension method which just returns a MethodInfo instance of the method to call. In this case it will be the Execute method.</em></p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-661992\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">PartialActionsSource<\/span><span class=\"p\">:<\/span> <span class=\"n\">IActionSource<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC3\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"n\">IEnumerable<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">ActionCall<\/span><span class=\"p\">&gt;<\/span> <span class=\"n\">FindActions<\/span><span class=\"p\">(<\/span><span class=\"n\">TypePool<\/span> <span class=\"n\">types<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC5\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">return<\/span> <span class=\"n\">types<\/span><\/div><div class=\'line\' id=\'LC6\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">.<\/span><span class=\"n\">TypesMatching<\/span><span class=\"p\">(<\/span><span class=\"n\">t<\/span> <span class=\"p\">=&gt;<\/span> <span class=\"n\">t<\/span><span class=\"p\">.<\/span><span class=\"n\">HasAttribute<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">PartialModelAttribute<\/span><span class=\"p\">&gt;())<\/span><\/div><div class=\'line\' id=\'LC7\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">.<\/span><span class=\"n\">Select<\/span><span class=\"p\">(<\/span><span class=\"n\">m<\/span> <span class=\"p\">=&gt;<\/span><\/div><div class=\'line\' id=\'LC8\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC9\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">var<\/span> <span class=\"n\">actionType<\/span> <span class=\"p\">=<\/span> <span class=\"k\">typeof<\/span><span class=\"p\">(<\/span><span class=\"n\">PartialAction<\/span><span class=\"p\">&lt;&gt;).<\/span><span class=\"n\">MakeGenericType<\/span><span class=\"p\">(<\/span><span class=\"n\">m<\/span><span class=\"p\">);<\/span><\/div><div class=\'line\' id=\'LC10\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">return<\/span> <span class=\"k\">new<\/span> <span class=\"nf\">ActionCall<\/span><span class=\"p\">(<\/span><span class=\"n\">actionType<\/span><span class=\"p\">,<\/span> <span class=\"n\">actionType<\/span><span class=\"p\">.<\/span><span class=\"n\">GetExecuteMethod<\/span><span class=\"p\">());<\/span><\/div><div class=\'line\' id=\'LC11\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">});<\/span><\/div><div class=\'line\' id=\'LC12\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC13\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/661992/6a1b82f5196c6d909e66834797cfc51fdf9ed791/PartialActionsSource.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/661992#file_partial_actions_source.cs\" style=\"float:right;margin-right:10px;color:#666\">PartialActionsSource.cs<\/a>\n            <a href=\"https://gist.github.com/661992\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/661992/PartialActionsSource.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><p>We&#8217;ll create the view real quick, nothing too fancy about it.</p><p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-661992\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"nt\">&lt;%@<\/span> <span class=\"n\">Page<\/span> <span class=\"n\">Language<\/span><span class=\"o\">=<\/span><span class=\"s\">&quot;C#&quot;<\/span> <span class=\"n\">CodeBehind<\/span><span class=\"o\">=<\/span><span class=\"s\">&quot;MasterLoginLogout.aspx.cs&quot;<\/span> <span class=\"k\">Inherits<\/span><span class=\"o\">=<\/span><span class=\"s\">&quot;Project.Web.Shared.Partials.Views.MasterLoginLogout&quot;<\/span> <span class=\"nt\">%&gt;<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"nt\">&lt;%@<\/span> <span class=\"n\">Import<\/span> <span class=\"n\">Namespace<\/span><span class=\"o\">=<\/span><span class=\"s\">&quot;Project.Web.Models.Users&quot;<\/span> <span class=\"nt\">%&gt;<\/span><\/div><div class=\'line\' id=\'LC3\'><span class=\"nt\">&lt;%<\/span> <span class=\"k\">if<\/span> <span class=\"p\">(<\/span><span class=\"n\">Model<\/span><span class=\"p\">.<\/span><span class=\"n\">IsAuthenticated<\/span><span class=\"p\">)<\/span> <span class=\"p\">{<\/span><span class=\"nt\">%&gt;<\/span><\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nt\">&lt;a<\/span> <span class=\"na\">href=<\/span><span class=\"s\">&quot;<\/span><span class=\"nt\">&lt;%=<\/span><span class=\"n\">Urls<\/span><span class=\"p\">.<\/span><span class=\"n\">UrlFor<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">UserLogoutGetModel<\/span><span class=\"p\">())<\/span><span class=\"nt\">%&gt;<\/span>&quot;&gt;Logout<span class=\"nt\">&lt;/a&gt;<\/span><\/div><div class=\'line\' id=\'LC5\'><span class=\"nt\">&lt;%<\/span> <span class=\"p\">}<\/span> <span class=\"k\">else<\/span> <span class=\"p\">{<\/span> <span class=\"nt\">%&gt;<\/span><\/div><div class=\'line\' id=\'LC6\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"nt\">&lt;a<\/span> <span class=\"na\">href=<\/span><span class=\"s\">&quot;<\/span><span class=\"nt\">&lt;%=<\/span> <span class=\"n\">Urls<\/span><span class=\"p\">.<\/span><span class=\"n\">UrlFor<\/span><span class=\"p\">(<\/span><span class=\"k\">new<\/span> <span class=\"n\">UserLoginGetModel<\/span><span class=\"p\">())<\/span> <span class=\"nt\">%&gt;<\/span>&quot;&gt;Login<span class=\"nt\">&lt;/a&gt;<\/span><\/div><div class=\'line\' id=\'LC7\'><span class=\"nt\">&lt;%<\/span><span class=\"p\">}<\/span> <span class=\"nt\">%&gt;<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/661992/84e5f7dc670571b5e925ff77a424f42299e86cba/MasterLoginLogout.aspx\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/661992#file_master_login_logout.aspx\" style=\"float:right;margin-right:10px;color:#666\">MasterLoginLogout.aspx<\/a>\n            <a href=\"https://gist.github.com/661992\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/661992/MasterLoginLogout.aspx&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><br /><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-661992\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">MasterLoginLogout<\/span> <span class=\"p\">:<\/span> <span class=\"n\">FubuPage<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">MasterLoginLogoutModel<\/span><span class=\"p\">&gt;<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC3\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/661992/a167741efab0bfbce93e62a825346571d4beceae/MasterLoginLogout.aspx.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/661992#file_master_login_logout.aspx.cs\" style=\"float:right;margin-right:10px;color:#666\">MasterLoginLogout.aspx.cs<\/a>\n            <a href=\"https://gist.github.com/661992\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/661992/MasterLoginLogout.aspx.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div></p><p>Now, we can call the partial view from our master page very easily. It will look something like this.</p><p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-661992\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'>&lt;%@ Master Language=&quot;C#&quot; AutoEventWireup=&quot;true&quot; CodeBehind=&quot;Site.master.cs&quot; Inherits=&quot;Project.Web.Shared.Master.Site&quot; %&gt;<\/div><div class=\'line\' id=\'LC2\'>&lt;%@ Import Namespace=&quot;FubuCore&quot; %&gt;<\/div><div class=\'line\' id=\'LC3\'>&lt;%@ Import Namespace=&quot;Project.Web.Shared.Partials.Models&quot; %&gt;<\/div><div class=\'line\' id=\'LC4\'><br/><\/div><div class=\'line\' id=\'LC5\'>&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Transitional//EN&quot; &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd&quot;&gt;<\/div><div class=\'line\' id=\'LC6\'>&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot;&gt;<\/div><div class=\'line\' id=\'LC7\'>&nbsp;&nbsp;&nbsp;&nbsp;&lt;head&gt;<\/div><div class=\'line\' id=\'LC8\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;title&gt;Project Master Page&lt;/title&gt;<\/div><div class=\'line\' id=\'LC9\'>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/head&gt;<\/div><div class=\'line\' id=\'LC10\'>&nbsp;&nbsp;&nbsp;&nbsp;&lt;body&gt;<\/div><div class=\'line\' id=\'LC11\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt;% this.Partial&lt;MasterLoginLogoutModel&gt;(); %&gt;<\/div><div class=\'line\' id=\'LC12\'>&nbsp;&nbsp;&nbsp;&nbsp;&lt;/body&gt;<\/div><div class=\'line\' id=\'LC13\'>&lt;/html&gt;<\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/661992/db712cbb4d0da5c067c1d9cfe20f424c3e694b2a/Site.master\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/661992#file_site.master\" style=\"float:right;margin-right:10px;color:#666\">Site.master<\/a>\n            <a href=\"https://gist.github.com/661992\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/661992/Site.master&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><br /><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-662035\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">Site<\/span> <span class=\"p\">:<\/span> <span class=\"n\">FubuMasterPage<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC3\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/662035/bf1ad11b907e3bc43348d769a9a76f10430db93a/Site.master.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/662035#file_site.master.cs\" style=\"float:right;margin-right:10px;color:#666\">Site.master.cs<\/a>\n            <a href=\"https://gist.github.com/662035\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/662035/Site.master.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div></p><p>When we call our page, we&#8217;ll see that it almost works. It&#8217;s just that it will always say &quot;Login&quot; because we never set the IsAuthenticated property on our model. To do this, we just want to create an action extension (remember that base interface we made way up there?).</p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-661992\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">MasterLoginLogoutPartialActionExtension<\/span> <span class=\"p\">:<\/span> <span class=\"n\">IPartialActionExtension<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">MasterLoginLogoutModel<\/span><span class=\"p\">&gt;<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC3\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">private<\/span> <span class=\"k\">readonly<\/span> <span class=\"n\">IAuthenticationManager<\/span> <span class=\"n\">_authenticationManager<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC4\'><br/><\/div><div class=\'line\' id=\'LC5\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"nf\">MasterLoginLogoutPartialActionExtension<\/span><span class=\"p\">(<\/span><span class=\"n\">IAuthenticationManager<\/span> <span class=\"n\">authenticationManager<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC6\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC7\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">_authenticationManager<\/span> <span class=\"p\">=<\/span> <span class=\"n\">authenticationManager<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC8\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC9\'><br/><\/div><div class=\'line\' id=\'LC10\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"n\">MasterLoginLogoutModel<\/span> <span class=\"nf\">Modify<\/span><span class=\"p\">(<\/span><span class=\"n\">MasterLoginLogoutModel<\/span> <span class=\"n\">model<\/span><span class=\"p\">)<\/span><\/div><div class=\'line\' id=\'LC11\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC12\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">model<\/span><span class=\"p\">.<\/span><span class=\"n\">IsAuthenticated<\/span> <span class=\"p\">=<\/span> <span class=\"n\">_authenticationManager<\/span><span class=\"p\">.<\/span><span class=\"n\">LoggedIn<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC13\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/div><div class=\'line\' id=\'LC14\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">return<\/span> <span class=\"n\">model<\/span><span class=\"p\">;<\/span><\/div><div class=\'line\' id=\'LC15\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC16\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/661992/08b955026104174f36e059c810259021e02b7e80/MasterLoginLogoutPartialActionExtension.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/661992#file_master_login_logout_partial_action_extension.cs\" style=\"float:right;margin-right:10px;color:#666\">MasterLoginLogoutPartialActionExtension.cs<\/a>\n            <a href=\"https://gist.github.com/661992\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/661992/MasterLoginLogoutPartialActionExtension.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><p>Also, just for completeness, here are the parts of our FubuMVC Registry which pertains to these partials.</p><script>/*<![CDATA[*/document.write('<link rel="stylesheet" href="https://gist.github.com/stylesheets/gist/embed.css"/>')
document.write('<div id=\"gist-662035\" class=\"gist\">\n\n        <div class=\"gist-file\">\n          <div class=\"gist-data gist-syntax\">\n              <div class=\"gist-highlight\"><pre><div class=\'line\' id=\'LC1\'><span class=\"k\">public<\/span> <span class=\"k\">class<\/span> <span class=\"nc\">ProjectFubuRegistry<\/span> <span class=\"p\">:<\/span> <span class=\"n\">FubuRegistry<\/span><\/div><div class=\'line\' id=\'LC2\'><span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC3\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"k\">public<\/span> <span class=\"nf\">ProjectFubuRegistry<\/span><span class=\"p\">()<\/span><\/div><div class=\'line\' id=\'LC4\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC5\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">Applies<\/span><span class=\"p\">.<\/span><span class=\"n\">ToThisAssembly<\/span><span class=\"p\">();<\/span><\/div><div class=\'line\' id=\'LC6\'><br/><\/div><div class=\'line\' id=\'LC7\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">Actions<\/span><span class=\"p\">.<\/span><span class=\"n\">FindWith<\/span><span class=\"p\">&lt;<\/span><span class=\"n\">PartialActionsSource<\/span><span class=\"p\">&gt;();<\/span><\/div><div class=\'line\' id=\'LC8\'><br/><\/div><div class=\'line\' id=\'LC9\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">Views<\/span><span class=\"p\">.<\/span><span class=\"n\">TryToAttach<\/span><span class=\"p\">(<\/span><span class=\"n\">findViews<\/span> <span class=\"p\">=&gt;<\/span><\/div><div class=\'line\' id=\'LC10\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">{<\/span><\/div><div class=\'line\' id=\'LC11\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">findViews<\/span><span class=\"p\">.<\/span><span class=\"n\">by_ViewModel_and_Namespace_and_MethodName<\/span><span class=\"p\">();<\/span><\/div><div class=\'line\' id=\'LC12\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">findViews<\/span><span class=\"p\">.<\/span><span class=\"n\">by_ViewModel_and_Namespace<\/span><span class=\"p\">();<\/span><\/div><div class=\'line\' id=\'LC13\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"n\">findViews<\/span><span class=\"p\">.<\/span><span class=\"n\">by_ViewModel<\/span><span class=\"p\">();<\/span><\/div><div class=\'line\' id=\'LC14\'>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC15\'>&nbsp;&nbsp;&nbsp;&nbsp;<span class=\"p\">}<\/span><\/div><div class=\'line\' id=\'LC16\'><span class=\"p\">}<\/span><\/div><\/pre><\/div>\n          <\/div>\n\n          <div class=\"gist-meta\">\n            <a href=\"https://gist.github.com/raw/662035/f55fbf56b56fc1baf61384733743d1e4122910c1/ProjectFubuRegistry.cs\" style=\"float:right;\">view raw<\/a>\n            <a href=\"https://gist.github.com/662035#file_project_fubu_registry.cs\" style=\"float:right;margin-right:10px;color:#666\">ProjectFubuRegistry.cs<\/a>\n            <a href=\"https://gist.github.com/662035\">This Gist<\/a> brought to you by <a href=\"http://github.com\">GitHub<\/a>.\n          <\/div>\n        <\/div>\n<\/div>\n')/*]]>*/</script><div style='margin-bottom:1em;padding:0;'><noscript><code><pre style='overflow:auto;margin:0;padding:0;border:1px solid #DDD;'>&lt;html&gt;&lt;body&gt;You are being &lt;a href=&quot;https://raw.github.com/gist/662035/ProjectFubuRegistry.cs&quot;&gt;redirected&lt;/a&gt;.&lt;/body&gt;&lt;/html&gt;</pre></code></noscript></div><p>Step-by-step, what happens when we call the partial from the master page?</p><ol><li>FubuMVC looks for the action call setup to accept that input type.</li><li>FubuMVC then calls the action call and passes a blank model to the PartialAction&#8217;s Execute method that was created while bootstrapping. In this case, it&#8217;s an instance of PartialAction, closed with MasterLoginLogoutModel.</li><li>When this instance of PartialAction is instantiated, it depends on an IPartialActionExtensionGraph&lt;MasterLoginLogoutModel&gt;. When we call Modify on this, StructureMap will have already found our MasterLoginLogoutPartialActionExtension class <em>(since it implements IPartialActionExtension and closes it with MasterLoginLogoutModel)</em>, and we will have a graph with this single action extension. If you had two classes that close this interface with MasterLoginLogoutModel, then they would both be in the graph.</li><li>The PartialAction, then calls modify on the graph, which loops through all of the action extensions and calls the Modify method, resetting the model to the return value for each call.</li><li>The model is then returned from the PartialAction, and is passed to the view.</li></ol><p>Now, whenever we want to create a new partial view, we can just follow these steps:</p><ol><li>Create the model for the view, <em>be sure to mark it with the PartialModel attribute</em>.</li><li>Create as many implementations of IPartialActionExtension as we need (normally only one). Be sure it closes the interface with the model we&#8217;ve just setup.</li><li>Create a view that uses the model. FubuMVC will be smart enough to figure out that&#8217;s the view we want to use, as long as we tell FubuMVC to match views by view models.</li></ol><p>It&#8217;s my understanding that most of this plumbing will be in a future release of FubuMVC. Until then, you can do this, instead. I&#8217;ll write another post when these features are native to Fubu.</p> ]]></content:encoded> <wfw:commentRss>http://rexflex.net/2010/11/working-with-partials-in-fubumvc/feed/</wfw:commentRss> <slash:comments>1</slash:comments> </item> <item><title>Nine Months Later&#8230;</title><link>http://rexflex.net/2009/05/nine-months-later/</link> <comments>http://rexflex.net/2009/05/nine-months-later/#comments</comments> <pubDate>Sat, 30 May 2009 06:14:26 +0000</pubDate> <dc:creator>Rex Morgan</dc:creator> <category><![CDATA[General]]></category> <category><![CDATA[Heart]]></category> <category><![CDATA[Software]]></category><guid isPermaLink="false">http://www.rexflex.net/?p=155</guid> <description><![CDATA[It&#8217;s going on nine months since my last update&#8230; I&#8217;m horrible about keeping my blog up to date.  Since I haven&#8217;t come up with a New Year&#8217;s Resolution, I&#8217;m going to go ahead and make this blog it.  Keeping it up to date and gaining readers.  &#8221;But&#8230; we&#8217;re already five months into the year&#8230;&#8221; you [...]]]></description> <content:encoded><![CDATA[<p>It&#8217;s going on nine months since my last update&#8230; I&#8217;m horrible about keeping my blog up to date.  Since I haven&#8217;t come up with a New Year&#8217;s Resolution, I&#8217;m going to go ahead and make this blog it.  Keeping it up to date and gaining readers.  &#8221;But&#8230; we&#8217;re already five months into the year&#8230;&#8221; you might say.  Shut up, I&#8217;ll do what I want, is my response.</p><p>So, what have I been up to for the past nine months?  I got a twitter account, and you should probably <a href="http://twitter.com/rexmorgan">follow me</a>!  I&#8217;ve also been working, quite a bit.  Back in October we got a new project and it&#8217;s been quite an experience to get it finished, however it should be done in the next couple of weeks.  I had a chance to use some new things in this project, the different things we used are:</p><ul><li><a href="http://www.orm.net/">ORM</a></li><li>.NET 3.5</li><li>LINQ</li><li>WCF/JSON/<a href="http://www.jquery.com/">jQuery</a></li><li><a href="http://www.codesmithtools.com/">CodeSmith </a>with <a href="http://nettiers.com/">.netTiers</a></li><li>SQL Server 2005</li><li><a href="http://www.snapdragonfx.net/">SnapDragon Framework</a></li></ul><p>I&#8217;ve had a few people ask me about one of my <a href="http://www.rexflex.net/archives/2008/04/07/21-going-on-72/">earlier blog posts about some heart problems</a> I was having.  I&#8217;d like to go ahead and update everyone.  I haven&#8217;t had a heart palpitation in over a year, things are going really well since I started staying away from caffeine.</p><p>I&#8217;ve signed up for a <a href="https://www.thinkorswim.com/tos/displayPage.tos?webpage=paperMoney">paperMoney</a> account at <a href="https://www.thinkorswim.com/tos/client/index.jsp">thinkorswim</a> and I&#8217;ve been playing around in the stock markets.  It&#8217;s only a simulation, but it&#8217;s pretty fun to keep up with.  So far I&#8217;ve managed to turn $100,000 into $116,500, too bad that&#8217;s not real money.  I&#8217;ve been thinking about putting some real money down on the line, but I don&#8217;t want to start until I have a somewhat decent amount to start with.  I&#8217;ve met <a href="http://www.davianletter.com/">Anthony Davian</a>, a hedge fund manager in Akron, Ohio, through <a href="http://www.twitter.com/">twitter</a>.  <a href="http://www.twitter.com/hedgieguy">Anthony</a> and <a href="http://twitter.com/kb_fin_rstar">Keith Barna</a> host a <a href="http://thedlshappyhour.blip.tv/">happy hour show</a> every week where they sample beers and talk about the markets.  It&#8217;s very interesting to attend and learn new things.  There&#8217;s also a newsletter that you can subscribe to for a monthly fee which will provide you with different trades that you can look at and see what they&#8217;re currently buying/selling.  If I were to actually go into the markets, I&#8217;d probably subscribe to that so that it&#8217;s not just me out there calling the shots, there&#8217;s someone else doing all the research and I just get to piggyback for profits!</p> ]]></content:encoded> <wfw:commentRss>http://rexflex.net/2009/05/nine-months-later/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> </channel> </rss>
<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using disk: basic
Page Caching using disk: enhanced
Object Caching 648/749 objects using disk: basic
Content Delivery Network via Rackspace Cloud Files: c520208.r8.cf2.rackcdn.com

Served from: rexflex.net @ 2012-02-07 12:09:58 -->
