<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:copyright="http://blogs.law.harvard.edu/tech/rss" xmlns:image="http://purl.org/rss/1.0/modules/image/">
    <channel>
        <title>Will Code 4 Food</title>
        <link>http://wc4f.qsh.es/Default.aspx</link>
        <description>The stories of a nonprofessional software developer</description>
        <language>en-US</language>
        <copyright>Jeffrey Richardson</copyright>
        <generator>Subtext Version 2.1.0.5</generator>
        <image>
            <title>Will Code 4 Food</title>
            <url>http://wc4f.qsh.es/images/RSS2Image.gif</url>
            <link>http://wc4f.qsh.es/Default.aspx</link>
            <width>77</width>
            <height>60</height>
        </image>
        <item>
            <title>ASP.NET MVC 2</title>
            <category>Areas</category>
            <category>ASP.NET MVC</category>
            <category>Templates</category>
            <link>http://wc4f.qsh.es/archive/2009/08/17/12.aspx</link>
            <description>&lt;p&gt;ASP.NET MVC 2 has been announced with the release of ASP.NET MVC 2 Preview 1. After having read through the rather lengthy overview of new features written by &lt;a href="http://weblogs.asp.net/scottgu/archive/2009/07/31/asp-net-mvc-v2-preview-1-released.aspx"&gt;Scott Guthrie&lt;/a&gt;. Many new great features have been listed, but the two that tend to stand out the most is support for areas by project and template helpers for editing and displaying data.&lt;/p&gt;  &lt;p&gt;Project based areas seemed to be an official solution to my categories dilemma.  On further inspection, it becomes apparent that the projects are not logical containers to an area.  The areas implementation is still the original namespace based one, with the projects allowing simple tooling support to keep a consistent namespaces in a defined area, as well as some behind the scene build tasks that allow all content to be merged together.  However, it does appear though that this has lead to some internal support of areas in general, making my category implementation integration more seamless.&lt;/p&gt;  &lt;p&gt;Template helpers appear to be very useful.  I already have a few ideas for including designer (quick preview) support for these, utilizing a control designed to provide similar functionality to the Editor/EditorFor and Display/DisplayFor. These methods return a string, and are used similar to how other HtmlHelper methods are used, such that it could be assumed that the return value would be the markup to send to the client.  Looking into the code, however, shows that these methods return an empty string, while using the ResponseContext to write the markup directly to the response stream.  I believe it’s safe to assume that this was probably a quick port to show off the functionality, and later will return the markup rather than write it.&lt;/p&gt;  &lt;p&gt;One bit of annoyance with regard to extending ASP.NET MVC is that the most useful classes tend to be set internal, such as InputHelper and TemplateHelper.  This makes it difficult to integrate at certain levels, especially in cases where the extensions have already done the work the public interface does or doesn’t need to do the work.  This creates a larger problem in the case the public interface is much more limiting than what the extension is trying to offer.  This situation tends to leave three less than ideal solutions: building the extension directly into the assembly, which requires the entire assembly distributed as standalone, not allowing integration with other some other extensions, including the relevant source directly in the extension, which causes updating to be more difficult, as well as ensuring internal dependencies, or creating a wrapper which reflects the code, which requires much higher privileges, and can’t run medium trust as a result. &lt;/p&gt;  &lt;p&gt;There are a few new features that leave more to be desired.  However, this release, as well as the future planned releases appear to be a great step forward in this technology, to which I look forward to more information.&lt;/p&gt;&lt;img src="http://wc4f.qsh.es/aggbug/12.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeffrey Richardson</dc:creator>
            <guid>http://wc4f.qsh.es/archive/2009/08/17/12.aspx</guid>
            <pubDate>Mon, 17 Aug 2009 17:03:14 GMT</pubDate>
            <wfw:comment>http://wc4f.qsh.es/comments/12.aspx</wfw:comment>
            <comments>http://wc4f.qsh.es/archive/2009/08/17/12.aspx#feedback</comments>
            <wfw:commentRss>http://wc4f.qsh.es/comments/commentRss/12.aspx</wfw:commentRss>
        </item>
        <item>
            <title>A Tale of Two Database Principals, part I: Introduction</title>
            <category>Model</category>
            <category>Microsoft SQL Server</category>
            <category>Security</category>
            <category>Principals</category>
            <link>http://wc4f.qsh.es/archive/2009/07/25/11.aspx</link>
            <description>&lt;p&gt;I have been working on a web application which requires a database backend for the model.  The hosting provider I am using hosts SQL Server 2005 databases, so I decided to setup a database.  To my delight, the hosting provider allows to set up an optional second “read only” set of credentials. Upon setting up the database, I decided to do a little research on what these database principals can do.&lt;/p&gt;  &lt;p&gt;I’ve found that, by default, the full access principal is granted full control of the database,  an extra schema is created with the same name as the read only principal which is then assigned to that principal, and, outside of its own schemas, the read only principal is only granted SELECT and REFERENCES to tables and views , with no access to any other object types.&lt;/p&gt;  &lt;p&gt;On the surface, this allows using the full access principal to create tables and views, as well as populating the tables, which the read only principal can then read without worry for modifying the data. If read only data is too limited, the read only principal can create all object types, as well as insert/update/delete tables as well as execute procedures as long as they are part of a schema assigned to the read only principal. In this rather limited default setup, this allows one to protect certain data that should never be modified or deleted. In later articles, I’ll discuss more powerful setups which can be achieved based on this setup.&lt;/p&gt;&lt;img src="http://wc4f.qsh.es/aggbug/11.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeffrey Richardson</dc:creator>
            <guid>http://wc4f.qsh.es/archive/2009/07/25/11.aspx</guid>
            <pubDate>Sun, 26 Jul 2009 00:52:48 GMT</pubDate>
            <wfw:comment>http://wc4f.qsh.es/comments/11.aspx</wfw:comment>
            <comments>http://wc4f.qsh.es/archive/2009/07/25/11.aspx#feedback</comments>
            <wfw:commentRss>http://wc4f.qsh.es/comments/commentRss/11.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Using Controls with ASP.NET MVC ViewPage</title>
            <category>ASP.NET MVC</category>
            <category>Controls</category>
            <category>Expression Builders</category>
            <category>Web Controls</category>
            <link>http://wc4f.qsh.es/archive/2009/03/07/9.aspx</link>
            <description>&lt;p&gt;For the last few months, I've been attempting to create WebForm controls specifically designed to work well with ASP.NET MVC and the ViewPage (as well as ViewMasterPage and ViewUserControl). Yesterday, as I near finish with my implementation, I find that &lt;a target="_blank" href="http://weblogs.asp.net/leftslipper/archive/2009/03/03/asp-net-mvc-release-candidate-2-i-declare-myself-to-be-declarative.aspx"&gt;Microsoft has already done so themselves&lt;/a&gt;. However, on second look, it's not finished, though does appear to be a great start.  As I debate whether to finish and bugproof my own implementation, choose to use Microsoft's implementation when they finally have time to finish it, or simply derive Microsoft's current implementation to better fit my needs, I'll describe what I've come up with so far, as a form of public comparison.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;First, my implementation exists in the erroneously named "MvcExtras.Expressions" assembly.  This is a historic naming back when I was attempting to implement everything using only expression builders.  While expression builders are still used, some of the work has been relocated to controls.  I've only implemented four controls; however, combined with the provided expression builders, I'm able to express everything that Microsoft's controls can express, with the exception of a repeater and a drop down list, and express many things that Microsoft's implementation yet cannot.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;h4&gt;Controls:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;Input: This control represents the &amp;lt;input /&amp;gt; HTML element, in all it's types.  By utilizing the Data property along with one of the InputExpressionBuilders, data from the ViewData can be easily obtained. &lt;/li&gt;    &lt;li&gt;Form: This control represents the &amp;lt;form&amp;gt; HTML element. This control is of rare use when using the "self post" design model typically used in ASP.NET MVC. This is mainly a workaround to enable using the UrlRouteExpressionBuilder to set the action attribute of a &amp;lt;form&amp;gt; element, as &amp;lt;form runat="server"&amp;gt; creates an HtmlForm and all of it's WebForm magic that is typically undesirable in ASP.NET MVC. &lt;/li&gt;    &lt;li&gt;ValidationMessage: This control represents the HtmlHelper.ValidationMessage methods.  It contains similar implementation, and results in similar or same behaviour. &lt;/li&gt;    &lt;li&gt;ValidationSummary: This control represents the HtmlHelper.ValidationSummary method. See above. &lt;/li&gt; &lt;/ul&gt;  &lt;h4&gt;Expression Builders:&lt;/h4&gt;  &lt;ul&gt;   &lt;li&gt;InputIdExpressionBuilder: Sets the id, name, and value of an Input control based on the name specified in the expression.  Also, styles the Input control if an error exists in the ModelState. &lt;/li&gt;    &lt;li&gt;CheckIdExpressionBuilder: Sets the id and name of the 'checkbox' type Input control, and specified if the checkbox should be checked. &lt;/li&gt;    &lt;li&gt;InputNameExpressionBuilder, CheckNameExpressionBuilder: Same as above, except the id is not set. &lt;/li&gt;    &lt;li&gt;RadioExpressionBuilder: Sets the name and value of the 'radio' type Input control, and determines from the ViewData if the radio should be checked. &lt;/li&gt;    &lt;li&gt;UrlRouteExpressionBuilder: Generates a URL based on route values specified. &lt;/li&gt;    &lt;li&gt;UrlRouteWithCategoryExpressionBuilder: Same as above, but copies over the "category" route value along with the "controller" and "action" if not explicitly specified. &lt;/li&gt;    &lt;li&gt;ViewDataExpressionBuilder: Represents the ViewData.Eval method. This expression builder is a simple frontend to the ViewData.Eval method. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;These controls and expression builders do not rely on any external code to work, and the expression builders were built with no-compile pages in mind. Usage is simple as well: the InputData based expression builders simply are assigned to the Input.Data property, while all the others can be used on any property of a string type.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;h4&gt;Example:&lt;/h4&gt;  &lt;p&gt; &lt;/p&gt;  &lt;div style="font-family: consolas; background: white; color: black; font-size: 10pt"&gt;   &lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;asp&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;Literal&lt;/span&gt; &lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;="server"&lt;/span&gt; &lt;span style="color: red"&gt;Mode&lt;/span&gt;&lt;span style="color: blue"&gt;="Encode"&lt;/span&gt; &lt;span style="color: red"&gt;Text&lt;/span&gt;&lt;span style="color: blue"&gt;="&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;$ViewData: Title &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;"&lt;/span&gt; &lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;mvc&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;ValidationSummary&lt;/span&gt; &lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;="server"&lt;/span&gt; &lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;mvc&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;Input&lt;/span&gt; &lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;="server"&lt;/span&gt; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="text"&lt;/span&gt; &lt;span style="color: red"&gt;Data&lt;/span&gt;&lt;span style="color: blue"&gt;="&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;$Id: username &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;"&lt;/span&gt; &lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;mvc&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;ValidationMessage&lt;/span&gt; &lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;="server"&lt;/span&gt; &lt;span style="color: red"&gt;Field&lt;/span&gt;&lt;span style="color: blue"&gt;="username"&amp;gt;&lt;/span&gt;Username is invalid&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;mvc&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;ValidationMessage&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;mvc&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;Input&lt;/span&gt; &lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;="server"&lt;/span&gt; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="password"&lt;/span&gt; &lt;span style="color: red"&gt;Data&lt;/span&gt;&lt;span style="color: blue"&gt;="&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;$Id: password &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;"&lt;/span&gt; &lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;mvc&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;Input&lt;/span&gt; &lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;="server"&lt;/span&gt; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="checkbox"&lt;/span&gt; &lt;span style="color: red"&gt;Data&lt;/span&gt;&lt;span style="color: blue"&gt;="&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;$Check: rememberMe &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;"&lt;/span&gt; &lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;mvc&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;Input&lt;/span&gt; &lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;="server"&lt;/span&gt; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="radio"&lt;/span&gt; &lt;span style="color: red"&gt;Data&lt;/span&gt;&lt;span style="color: blue"&gt;="&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;$Radio: status, invisible &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;"&lt;/span&gt; &lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;mvc&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;Input&lt;/span&gt; &lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;="server"&lt;/span&gt; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="radio"&lt;/span&gt; &lt;span style="color: red"&gt;Data&lt;/span&gt;&lt;span style="color: blue"&gt;="&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;$Radio: status, away &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;"&lt;/span&gt; &lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;mvc&lt;/span&gt;&lt;span style="color: blue"&gt;:&lt;/span&gt;&lt;span style="color: #a31515"&gt;Input&lt;/span&gt; &lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;="server"&lt;/span&gt; &lt;span style="color: red"&gt;type&lt;/span&gt;&lt;span style="color: blue"&gt;="radio"&lt;/span&gt; &lt;span style="color: red"&gt;Data&lt;/span&gt;&lt;span style="color: blue"&gt;="&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;$Radio: status, online &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;"&lt;/span&gt; &lt;span style="color: blue"&gt;/&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;a&lt;/span&gt; &lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;="server"&lt;/span&gt; &lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;="&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;$Url: action=About &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;"&amp;gt;&lt;/span&gt;About&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;

  &lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #a31515"&gt;a&lt;/span&gt; &lt;span style="color: red"&gt;runat&lt;/span&gt;&lt;span style="color: blue"&gt;="server"&lt;/span&gt; &lt;span style="color: red"&gt;href&lt;/span&gt;&lt;span style="color: blue"&gt;="&lt;/span&gt;&lt;span style="background: #ffee62"&gt;&amp;lt;%&lt;/span&gt;$Url: category=Account, controller=Auth, action=LogOn &lt;span style="background: #ffee62"&gt;%&amp;gt;&lt;/span&gt;&lt;span style="color: blue"&gt;"&amp;gt;&lt;/span&gt;Sign On&lt;span style="color: blue"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #a31515"&gt;a&lt;/span&gt;&lt;span style="color: blue"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;The above is not exactly a real world example one would use, but it should explain how everything fits together.&lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt; &lt;/p&gt;

&lt;p&gt;I would release a binary, but it's in an unfinished state at the moment, a few things I've mentioned above are in a state of half implementation; all the right flags get checked, but some are ignored currently when rendering. In the meantime, if I decide my current implementation is worthy of continuing, I'll plan on finishing it up, as well as providing the binary here for others to use as well.&lt;/p&gt;&lt;img src="http://wc4f.qsh.es/aggbug/9.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeffrey Richardson</dc:creator>
            <guid>http://wc4f.qsh.es/archive/2009/03/07/9.aspx</guid>
            <pubDate>Sat, 07 Mar 2009 10:16:08 GMT</pubDate>
            <wfw:comment>http://wc4f.qsh.es/comments/9.aspx</wfw:comment>
            <comments>http://wc4f.qsh.es/archive/2009/03/07/9.aspx#feedback</comments>
            <wfw:commentRss>http://wc4f.qsh.es/comments/commentRss/9.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Category support in ASP.NET MVC nearly finished</title>
            <category>Areas</category>
            <category>ASP.NET MVC</category>
            <category>Categories</category>
            <link>http://wc4f.qsh.es/archive/2009/02/25/8.aspx</link>
            <description>&lt;p&gt;I've finished implementing support in ASP.NET MVC for processing requests and rendering views using categories.  Only things left now is to add extension methods that simplify the process of using categories, as well as finish implementing discoverability (i.e. SiteMapProvider).&lt;/p&gt;
&lt;p&gt;In the future, I wish to also deal with inline page code.  I find it rather ugly, as well as having no page designer support. Although I do not use the page designer to design my page, I do tend to use it as a "quick preview," as well I tend to work with others who require page designer support.  I've gone through several possible ideas and implementations, but I believe I have settled on a single idea that should work well. I'll have updates later.&lt;/p&gt;
&lt;p&gt;I never specifically planned on releasing any software, but I believe some people out there might be interested in some of the software I talk about, so I've included what work I've done with category support thus far.&lt;/p&gt;
&lt;p&gt; &lt;/p&gt;&lt;img src="http://wc4f.qsh.es/aggbug/8.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeffrey Richardson</dc:creator>
            <guid>http://wc4f.qsh.es/archive/2009/02/25/8.aspx</guid>
            <pubDate>Wed, 25 Feb 2009 20:04:34 GMT</pubDate>
            <wfw:comment>http://wc4f.qsh.es/comments/8.aspx</wfw:comment>
            <comments>http://wc4f.qsh.es/archive/2009/02/25/8.aspx#feedback</comments>
            <wfw:commentRss>http://wc4f.qsh.es/comments/commentRss/8.aspx</wfw:commentRss>
            <enclosure url="http://wc4f.qsh.es/Enclosures/MvcExtras.Categories.dll" length="15872" type="application/x-msdownload" />
        </item>
        <item>
            <title>Another approach to ASP.NET MVC categories</title>
            <category>Areas</category>
            <category>ASP.NET MVC</category>
            <category>Categories</category>
            <link>http://wc4f.qsh.es/archive/2009/02/21/7.aspx</link>
            <description>&lt;p&gt;Last night I had an idea for a different approach for grouping related controllers into a category that made so much sense, I'm surprised I was able to imagine it.  The idea of actions being grouped into a controller parallels a set of methods being grouped into a class. Taking it a step further, grouping a set of controllers into a category would parallel grouping a set of classes into an assembly.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;Under this approach, each category would be created as a separate project, referenced back into the main web application.  This has a few advantages over using attributes.  First, it allows real separation, as opposed to the superficial separation that attributes employ.  Second, it's much easier to cache the controllers into categories, as attribute lookups are no longer required, nor is it required to check that category has been added to the cache (as it can be added the moment the assembly is loaded).  It also enforces a design pattern that is much less fragile than attributes (which itself is much less fragile than current implementations I've found), and doesn't feel too restrictive.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;I plan on keeping both implementations in my framework, as I see they both have advantages over the other.  With many different features being added to my framework, I believe it will be necessary to split it into separate modules.  This will simplify adding needed features, without having to include everything.&lt;/p&gt;&lt;img src="http://wc4f.qsh.es/aggbug/7.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeffrey Richardson</dc:creator>
            <guid>http://wc4f.qsh.es/archive/2009/02/21/7.aspx</guid>
            <pubDate>Sat, 21 Feb 2009 06:07:22 GMT</pubDate>
            <wfw:comment>http://wc4f.qsh.es/comments/7.aspx</wfw:comment>
            <comments>http://wc4f.qsh.es/archive/2009/02/21/7.aspx#feedback</comments>
            <wfw:commentRss>http://wc4f.qsh.es/comments/commentRss/7.aspx</wfw:commentRss>
        </item>
        <item>
            <title>ControllerDescriptor, ActionDescriptor, and ParameterDescriptor in ASP.NET MVC</title>
            <category>ASP.NET MVC</category>
            <category>Reflection</category>
            <link>http://wc4f.qsh.es/archive/2009/02/19/6.aspx</link>
            <description>&lt;p&gt;I was working on a method for making controllers, as well as their categories and actions, discoverable, and noticed a few Descriptor types.  On the surface, they appear to provide a few methods and properties that make it much simpler to query information about Controllers and Actions than using Reflection alone.  Obtaining filters, attributes, and even lists of actions from a controller, or lists of parameters from an action, can be made with a simple method call, rather than the possible many lines of using confusing Reflection methods.  However, this isn't exactly the case; the Descriptor types are abstract, their functionality lies in the corresponding Reflected*Descriptor types.  This means it could be possible to describe Actions and Controllers using methods other than reflection.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;This may be confusing at first; most cases controllers are created by deriving from the Controller base class, which uses reflection to obtain a method to invoke based on the Action and parameters given, as well to process filters present on both the method and class itself.  However, the MVC framework never uses Controller itself, only IController, which only provides on method, Execute.  This method accepts the Action as well as it's parameters, and returns a result.  There is no requirement for Reflection, that is only the default implementation.  However, this means that a class that implements IController directly will not necessarily follow the same Action/Parameter &amp;lt;-&amp;gt; Method mapping that the Controller class does.  Having abstract classes ControllerDescriptor, ActionDescriptor, and ParameterDescriptor allows a controller to be able to describe itself, no matter how it's implemented.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;I plan to use these types in my discoverability framework, so that it will be portable across different controller implementations.  This should better allow it to fit in with the typical "plug in" model that the ASP.NET MVC framework currently employs.&lt;/p&gt;&lt;img src="http://wc4f.qsh.es/aggbug/6.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeffrey Richardson</dc:creator>
            <guid>http://wc4f.qsh.es/archive/2009/02/19/6.aspx</guid>
            <pubDate>Thu, 19 Feb 2009 18:47:04 GMT</pubDate>
            <wfw:comment>http://wc4f.qsh.es/comments/6.aspx</wfw:comment>
            <comments>http://wc4f.qsh.es/archive/2009/02/19/6.aspx#feedback</comments>
            <slash:comments>2</slash:comments>
            <wfw:commentRss>http://wc4f.qsh.es/comments/commentRss/6.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Category support in ASP.NET MVC? Part 2</title>
            <category>Areas</category>
            <category>ASP.NET MVC</category>
            <category>Categories</category>
            <link>http://wc4f.qsh.es/archive/2009/02/09/5.aspx</link>
            <description>&lt;p&gt;In order to support categories of controllers in ASP.NET MVC, one must create a new controller factory.  The IControllerFactory interface defines two methods to implement, CreateController, which passes in the controller name pulled from the route data, as well as the RouteContext itself, and ReleaseController, which occurs at the end of the request, allowing the controller to be freed.  One limitation of CreateController method is that it only gives the controller name, but not the category name.  This isn't much of an issue, it's possible to obtain the category name by calling the GetRequiredString method from RequestContext.RouteData object (this is the same method used to obtain the controller and action name as well).  The question now, how does one obtain a reference to the correct Controller type?  A quick assumption as to how it is done without categories would be to reflect until the correct controller is found, then returning that.  Based on this assumption, one would assuming finding a matching Controller, then checking the attributes to determine that the corresponding attribute is set.&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;However, that's not how the default controller factory works, and for good reason.  It's very poor performance to reflect the entire set of types searching for the correct type.  Instead, the default controller factory creates what is known as a 'ControllerTypeCache' where it reflects through every type to find all matching controller types only once (when the application starts) and saves that list.  It uses a Dictionary&amp;lt;string, ILookup&amp;lt;string, Type&amp;gt;&amp;gt; to store this list.  A Dictionary is a one to one mapping between key and value, whereas a Lookup is a one to many mapping between key and value.  For each controller type that is found, it's name is derived, then that name is used to obtain the Lookup from the Dictionary (or create a new one if necessary).  Then, the namespace is taken from the controller type, and then used as a key to add the type to the Lookup.  So, each controller name is then mapped to one or more namespaces, which is then mapped to one or more types (more than one type with the same namespace and same name can occur if they are defined in separate assemblies).&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;A modified version of this same procedure can be used to support category lookup as well.  In this case, it might be preferable to store in an IDictionary&amp;lt;string, IDictionary&amp;lt;string, Type&amp;gt;&amp;gt;, where each category then maps to one or more controller names, which then map to one type.  The list can be easily generated using the following code:&lt;/p&gt;  &lt;blockquote&gt;   &lt;div style="font-family: consolas; background: white; color: black; font-size: 10pt"&gt;     &lt;pre style="margin: 0px"&gt;&lt;span style="color: blue"&gt;private&lt;/span&gt; &lt;span style="color: blue"&gt;static&lt;/span&gt; &lt;span style="color: #2b91af"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;&amp;gt;&amp;gt; GetAllControllerTypes() {&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;    &lt;span style="color: green"&gt;// Go through all assemblies referenced by the application and search for&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;    &lt;span style="color: green"&gt;// controllers.&lt;/span&gt;&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;    &lt;span style="color: #2b91af"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;&amp;gt;&amp;gt; controllerTypes = &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;IDictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;&amp;gt;&amp;gt;();&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;    &lt;span style="color: #2b91af"&gt;ICollection&lt;/span&gt; assemblies = &lt;span style="color: #2b91af"&gt;BuildManager&lt;/span&gt;.GetReferencedAssemblies();&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;Assembly&lt;/span&gt; assembly &lt;span style="color: blue"&gt;in&lt;/span&gt; assemblies) {&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;        &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;[] typesInAsm;&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;try&lt;/span&gt; {&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;            typesInAsm = assembly.GetTypes();&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;        }&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;catch&lt;/span&gt; (&lt;span style="color: #2b91af"&gt;ReflectionTypeLoadException&lt;/span&gt; ex) {&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;            typesInAsm = ex.Types;&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;        }&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;foreach&lt;/span&gt; (&lt;span style="color: blue"&gt;var&lt;/span&gt; controllerType &lt;span style="color: blue"&gt;in&lt;/span&gt; typesInAsm.Where(IsControllerType)){&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;string&lt;/span&gt; category = GetCategoryName(controllerType);&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;            &lt;span style="color: blue"&gt;if&lt;/span&gt; (!&lt;span style="color: blue"&gt;string&lt;/span&gt;.IsNullOrEmpty(category)){&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;                &lt;span style="color: blue"&gt;if&lt;/span&gt; (!controllerTypes.ContainsKey(category)) controllerTypes.Add(category, &lt;span style="color: blue"&gt;new&lt;/span&gt; &lt;span style="color: #2b91af"&gt;Dictionary&lt;/span&gt;&amp;lt;&lt;span style="color: blue"&gt;string&lt;/span&gt;, &lt;span style="color: #2b91af"&gt;Type&lt;/span&gt;&amp;gt;());&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;                controllerTypes[category].Add(GetControllerName(controllerType), controllerType);&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;            }&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;        }&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;     }&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;return&lt;/span&gt; controllerTypes;&lt;/pre&gt;

    &lt;pre style="margin: 0px"&gt;}&lt;/pre&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;

&lt;p&gt;Types can easily be looked up using the following code:  cache[categoryName][controllerName] (obviously, this is just a simple method demonstrating the structure; in order to prevent a NullReferenceException, you would want to use TryGetValue instead).&lt;/p&gt;&lt;img src="http://wc4f.qsh.es/aggbug/5.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeffrey Richardson</dc:creator>
            <guid>http://wc4f.qsh.es/archive/2009/02/09/5.aspx</guid>
            <pubDate>Mon, 09 Feb 2009 20:04:25 GMT</pubDate>
            <wfw:comment>http://wc4f.qsh.es/comments/5.aspx</wfw:comment>
            <comments>http://wc4f.qsh.es/archive/2009/02/09/5.aspx#feedback</comments>
            <wfw:commentRss>http://wc4f.qsh.es/comments/commentRss/5.aspx</wfw:commentRss>
        </item>
        <item>
            <title>Category support in ASP.NET MVC?</title>
            <category>Areas</category>
            <category>ASP.NET MVC</category>
            <category>Categories</category>
            <link>http://wc4f.qsh.es/archive/2009/02/06/4.aspx</link>
            <description>&lt;p&gt;For some time, I have been desiring a method for grouping a set of related Controllers into categories. A search for such a category style scheme showed me that, in the web MVC world, such a concept is known as areas, and I found a few examples of people implementing such features on top of ASP.NET MVC.&lt;/p&gt;  &lt;br /&gt;  &lt;p&gt;&lt;a href="http://haacked.com/archive/2008/11/04/areas-in-aspnetmvc.aspx"&gt;http://haacked.com/archive/2008/11/04/areas-in-aspnetmvc.aspx&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blog.codeville.net/2008/11/05/app-areas-in-aspnet-mvc-take-2/"&gt;http://blog.codeville.net/2008/11/05/app-areas-in-aspnet-mvc-take-2/&lt;/a&gt;&lt;/p&gt;  &lt;br /&gt;  &lt;p&gt;Both of these are the same implementation, with the former having little flexibility and being very fragile, with the latter adding flexibility at the expense of complexity, while still being as fragile. To add to that, neither solution supports discoverability (something I will get to with a later post).&lt;/p&gt;  &lt;p&gt;My implementation will consist of adding the route name 'category' to the list of required route names, just like 'controller' and 'action'.  Also, the use of an attribute would declare the category of a controller.&lt;/p&gt;  &lt;blockquote&gt;   &lt;div style="font-family: consolas; background: white; color: black; font-size: 12pt"&gt;     &lt;p style="margin: 0px"&gt;[&lt;span style="color: #2b91af"&gt;AttributeUsage&lt;/span&gt;(&lt;span style="color: #2b91af"&gt;AttributeTargets&lt;/span&gt;.Class, AllowMultiple=&lt;span style="color: blue"&gt;false&lt;/span&gt;, Inherited=&lt;span style="color: blue"&gt;false&lt;/span&gt;)]&lt;/p&gt;      &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;abstract&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;CategoryAttribute&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;Attribute&lt;/span&gt; {}&lt;font face="Trebuchet MS"&gt; &lt;/font&gt;&lt;/p&gt;   &lt;/div&gt; &lt;/blockquote&gt;  &lt;p&gt;This will allow one to inherit from CategoryAttribute and decorate their controller class with the corresponding CategoryAttribute.&lt;/p&gt;  &lt;blockquote&gt;   &lt;div style="font-family: consolas; background: white; color: black; font-size: 12pt"&gt;     &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;MainCategoryAttribute&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;CategoryAttribute&lt;/span&gt; { }&lt;/p&gt;      &lt;p style="margin: 0px"&gt; &lt;/p&gt;      &lt;p style="margin: 0px"&gt;[&lt;span style="color: #2b91af"&gt;MainCategory&lt;/span&gt;]&lt;/p&gt;      &lt;p style="margin: 0px"&gt;&lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: blue"&gt;class&lt;/span&gt; &lt;span style="color: #2b91af"&gt;MainController&lt;/span&gt; : &lt;span style="color: #2b91af"&gt;Controller&lt;/span&gt; {&lt;/p&gt;      &lt;p style="margin: 0px"&gt;    &lt;span style="color: blue"&gt;public&lt;/span&gt; &lt;span style="color: #2b91af"&gt;ActionResult&lt;/span&gt; Main() {&lt;/p&gt;      &lt;p style="margin: 0px"&gt;        &lt;span style="color: blue"&gt;return&lt;/span&gt; View();&lt;/p&gt;      &lt;p style="margin: 0px"&gt;    }&lt;/p&gt;      &lt;p style="margin: 0px"&gt;}&lt;/p&gt;   &lt;/div&gt; &lt;/blockquote&gt;  &lt;p&gt;By defining the route using "{category}/{controller}/{action}/{id}" (note, in this example, {id} is not necessary), the following URL will activate the MainController.Main() method:&lt;/p&gt;  &lt;p&gt;Main/Main/Main/&lt;/p&gt;  &lt;p&gt;(I notice the lack of originality with naming the sections, and I apologize; I'm not the best at naming things, especially for example purposes.)&lt;/p&gt;  &lt;p&gt; &lt;/p&gt;  &lt;p&gt;My next article will be more in depth about how this model actually works.&lt;/p&gt;&lt;img src="http://wc4f.qsh.es/aggbug/4.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeffrey Richardson</dc:creator>
            <guid>http://wc4f.qsh.es/archive/2009/02/06/4.aspx</guid>
            <pubDate>Fri, 06 Feb 2009 19:40:49 GMT</pubDate>
            <wfw:comment>http://wc4f.qsh.es/comments/4.aspx</wfw:comment>
            <comments>http://wc4f.qsh.es/archive/2009/02/06/4.aspx#feedback</comments>
            <wfw:commentRss>http://wc4f.qsh.es/comments/commentRss/4.aspx</wfw:commentRss>
        </item>
        <item>
            <title>The beginnings</title>
            <link>http://wc4f.qsh.es/archive/2009/02/04/3.aspx</link>
            <description>&lt;p&gt;Over the times, I've noticed and read from numerous people with their stories and entries about the various problems and situations occurring in their course of developing a piece of software. With all the development I've been doing in the recent weeks, I realized that I have a few interesting sources of information as well.&lt;/p&gt;  &lt;p&gt;In order to be quickly available, I decided to pull an already created website journal software. I plan to replace this with my own once I have the time to spend with it.  Upon "upgrading" to my own software, there is no guarantee that any posts or comments will remain.&lt;/p&gt;  &lt;p&gt;In all, I hope that someone can read one of my entries and find it helpful in his own situation.&lt;/p&gt;&lt;img src="http://wc4f.qsh.es/aggbug/3.aspx" width="1" height="1" /&gt;</description>
            <dc:creator>Jeffrey Richardson</dc:creator>
            <guid>http://wc4f.qsh.es/archive/2009/02/04/3.aspx</guid>
            <pubDate>Wed, 04 Feb 2009 20:04:15 GMT</pubDate>
            <wfw:comment>http://wc4f.qsh.es/comments/3.aspx</wfw:comment>
            <comments>http://wc4f.qsh.es/archive/2009/02/04/3.aspx#feedback</comments>
            <wfw:commentRss>http://wc4f.qsh.es/comments/commentRss/3.aspx</wfw:commentRss>
        </item>
    </channel>
</rss>