<?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>Coding Cockerel &#187; ASP .NET MVC</title>
	<atom:link href="http://codingcockerel.co.uk/category/net/asp-net-mvc/feed/" rel="self" type="application/rss+xml" />
	<link>http://codingcockerel.co.uk</link>
	<description>Getting the job done with .NET</description>
	<lastBuildDate>Sat, 13 Mar 2010 21:10:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Consistent validation with ASP .NET MVC and jQuery</title>
		<link>http://codingcockerel.co.uk/2010/03/06/consistent-validation-with-asp-net-mvc-and-jquery/</link>
		<comments>http://codingcockerel.co.uk/2010/03/06/consistent-validation-with-asp-net-mvc-and-jquery/#comments</comments>
		<pubDate>Sat, 06 Mar 2010 21:53:52 +0000</pubDate>
		<dc:creator>codingcockerel</dc:creator>
				<category><![CDATA[ASP .NET MVC]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://codingcockerel.co.uk/?p=106</guid>
		<description><![CDATA[Recently I have been developing a couple of small web applications with version 1 of ASP .NET MVC, using jQuery&#8217;s validation plugin to provide a better client-side experience. As some of you may be aware, the validation features in the first release of MVC were sparse, although Phil and the team have certainly corrected this [...]]]></description>
			<content:encoded><![CDATA[<p>   Recently I have been developing a couple of small web applications with version 1 of ASP .NET MVC, using jQuery&#8217;s <a title="jQuery validation" href="http://docs.jquery.com/Plugins/Validation">validation plugin</a> to provide a better client-side experience. As some of you may be aware, the validation features in the first release of MVC were sparse, although Phil and the team have certainly corrected this with the recent second version.</p>
<p>   One aim I had with my validation features was to deliver consistent behaviour and appearance between client and server, so that users would get the same experience whether they had scripting turned on or off. It proved a little awkward at first, but I got there in the end, so thought I would post the results to my blog in case anyone else is trying to do the same.</p>
<p>   When creating a strongly-typed view, MVC provides templates for common scenarios, e.g. Create, Edit, Details and so on. This gives the developer a head start and removes the need for a lot of monotonous coding. The server-side markup it generates for each field in the Create and Edit views is similar to the following</p>
<pre class="brush: xml;">
&lt;label for=&quot;FirstName&quot;&gt;FirstName:&lt;/label&gt;
&lt;%= Html.TextBox(&quot;FirstName&quot;) %&gt;
&lt;%= Html.ValidationMessage(&quot;FirstName&quot;)
</pre>
<p>
  As you can see, each property of the model (in this case, the first name of a person) gets a label, an input control for editing its value, and any validation messages linked to the field are shown next to it. When this is rendered to the client, we get HTML like this</p>
<pre class="brush: xml;">
&lt;label for=&quot;FirstName&quot;&gt;FirstName:&lt;/label&gt;
&lt;input class=&quot;input-validation-error&quot; id=&quot;FirstName&quot; name=&quot;FirstName&quot; type=&quot;text&quot; value=&quot;&quot; /&gt;
&lt;span class=&quot;field-validation-error&quot;&gt;First name must be entered.&lt;/span&gt;</pre>
<p>
  Whilst jQuery&#8217;s validation provides similar results straight out of the box, it&#8217;s not quite what I need. For starters, it uses a label to show the error message, whereas MVC uses a span. This is easily corrected by using the errorElement option of the plugin. So the script for the validator now looks like this</p>
<pre class="brush: js;">$().ready(function() {
  $('form').validate({
      errorElement: 'span',
      rules: { FirstName: { required: true } },
      messages: { FirstName: { required: 'Please enter the first name.' } }
  });
});</pre>
<p>
  However that left me with a tricky problem &#8211; the input and error elements don&#8217;t have the correct classes attached to them, so the styling rules are not being applied. As you can see from the earlier markup, MVC applies the <span style="font-size: 10pt; font-family: courier new;">field-validation-error</span> class to the element containing the error message, and the <span style="font-size: 10pt; font-family: courier new;">input-validation-error</span> class to the element containing the invalid value. This is different to the jQuery plugin, which applies the <span style="font-size: 10pt; font-family: courier new;">error</span> class to both elements.</p>
<p>
  Initially I tried playing around with the errorClass option, but could only get one or other of the correct classes applied. In the end I used the highlight and unhighlight functions, which are called when an error message is shown or hidden, respectively. By default, highlight adds the errorClass to the input element, and also removes the validClass. The validClass (<span style="font-size: 10pt; font-family: courier new;">valid</span> by default) allows you to style the element to indicate that it contains valid input. My custom implementation of highlight continues to do this, but adds another couple of lines to apply the correct classes to the input element and the error message span. The JavaScript looks like this</p>
<pre class="brush: js;">
highlight: function(element, errorClass, validClass) {
  $(element).addClass(errorClass).removeClass(validClass);
  $(element).addClass('input-validation-error');
  $(element.form).find('span[for=' + element.id + ']')
    .addClass('field-validation-error');}
</pre>
<p>
  The unhighlight function just does the reverse; I&#8217;ve omitted it for the sake of brevity here. I&#8217;ve been using this code for a while now and it seems to have had the desired effect. This is a great example of how flexible many of jQuery&#8217;s plugins are, as well as providing excellent functionality out of the box.</p>
<p>
  The sample code for this is available <a href="http://codingcockerel.codeplex.com/releases/view/41891" title="CodePlex">here</a>, I&#8217;ve also included a slight change which ensures the validClass is applied correctly if you are targeting styles for it.
</p>
<p>See also: <a href="http://docs.jquery.com/Plugins/Validation/validate#toptions" title="jQuery validation advanced options">jQuery validation advanced options</a>, <a href="http://bassistance.de/jquery-plugins/jquery-plugin-validation/" title="jQuery validation home">jQuery validation home</a></p>
]]></content:encoded>
			<wfw:commentRss>http://codingcockerel.co.uk/2010/03/06/consistent-validation-with-asp-net-mvc-and-jquery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Plugging ELMAH into ASP .NET MVC</title>
		<link>http://codingcockerel.co.uk/2010/01/22/plugging-elmah-into-asp-net-mvc/</link>
		<comments>http://codingcockerel.co.uk/2010/01/22/plugging-elmah-into-asp-net-mvc/#comments</comments>
		<pubDate>Fri, 22 Jan 2010 16:56:07 +0000</pubDate>
		<dc:creator>codingcockerel</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP .NET]]></category>
		<category><![CDATA[ASP .NET MVC]]></category>

		<guid isPermaLink="false">http://codingcockerel.co.uk/?p=102</guid>
		<description><![CDATA[Over the past year or so ELMAH has becoming increasingly popular, and it&#8217;s not hard to see why. It has an excellent set of error logging and reporting features, doesn&#8217;t need to be referenced directly in any application code and is simple to configure. Recently a troublesome ASP .NET application came into my care and [...]]]></description>
			<content:encoded><![CDATA[<p>     Over the past year or so <a href="http://code.google.com/p/elmah/" title="ELMAH">ELMAH</a>     has becoming increasingly popular, and it&#8217;s not hard to see why. It has an excellent     set of error logging and reporting features, doesn&#8217;t need to be referenced directly     in any application code and is simple to configure.</p>
<p>     Recently a troublesome ASP .NET application came into my care and I decided the     first course of action was to plug ELMAH in. At the most basic level, this involves     dropping the ELMAH dll into bin and a few changes to web.config; Scott Hanselman     shows you how to do this on his <a href="http://www.hanselman.com/blog/ELMAHErrorLoggingModulesAndHandlersForASPNETAndMVCToo.aspx" title="ELMAH: Error Logging Modules and Handlers for ASP.NET (and MVC too!)">blog</a>.</p>
<p>     However, because the app was built using ASP .NET MVC, its default HandleError attribute     was intercepting all exceptions thrown by controllers, before ELMAH could got a     look at them. As a result not all exceptions were being logged. To counter this,     I created a custom version of the HandleError attribute, called ElmahHandleErrorAttribute.     Well actually, Atif Aziz, author of ELMAH did, in a post on <a href="http://stackoverflow.com/questions/766610/" title="How to get ELMAH to work with ASP.NET MVC [HandleError] attribute?">Stack       Overflow</a>, I just copied it!</p>
<p>     The last piece of the puzzle is to create a base controller, from which <em>all</em>     controllers in the application inherit, and apply the ElmahHandleErrorAttribute     to it. Now all exceptions in the application will pass through the ELMAH pipleine.</p>
<p>     It&#8217;s important to test that any custom error pages are also shown after ELMAH has     done its bit. To do so, switch customErrors in web.config to on so that those pages     are shown in preference to the traditional yellow screen of death (more information     on customErrors can be found at <a href="http://msdn.microsoft.com/en-us/library/h0hfz6fc.aspx" title="customErrors Element (ASP.NET Settings Schema)">MSDN</a>). If you have     error pages specific to particular HTTP error codes (i.e. one for 404s and one for     the rest) then add these now.</p>
<p>     Next, do something that is guaranteed to throw an exception in the app. Most of     the time a typo in the connection string, if using a database, is a simple but effective     way of doing this. Afterwards, ELMAH will have logged the exception (go to /elmah.axd     to check) and the friendly error page will be rendered.</p>
<p>     The reason I suggest testing these pages is that when developing locally, most of     us run with customErrors off so we get the YSOD in all its glory, stack trace and     all &#8211; and so we should. As a result, if there are any issues with custom error pages     not being shown correctly, they often only come out during formal testing, at which     point it is often more time consuming to fix.</p>
<p>     I&#8217;ve tripped over this myself a couple of times, particularly if the custom error     page accesses the database. Imagine a situation in which the database is offline,     and an exception is thrown. ELMAH logs the details, and ASP .NET MVC tries to render     the custom error page, at which point another attempt is made to connect to the     database! The custom error page will then blow up &#8211; not good at all.</p>
<p>     The lesson here is that custom error pages should be as basic as possible. If they     use the same master page as the rest of the app, and that master page shows a database     value somewhere in the header or footer (e.g. friendly name of the current user,     which is quite common), they are vulnerable to this problem. Far better to have     a separate master page for all error pages which uses the same styles as the rest     of the site but consists of plain, basic markup.</p>
<p>     One last point to make is that ELMAH isn&#8217;t just for web apps, although it works     best there. I recently worked on a solution that had a web front end and a console     application for pumping data into the database. I made use of ELMAH in both apps,     thereby having a central repository for all exception information. I&#8217;ve pointed     my feed reader at ELMAH&#8217;s RSS feed (/elmah.axd/rss) and am notified as soon as any     part of the solution experiences an error.</p>
<p>     So, if you&#8217;re not yet on board the ELMAH bandwagon, now is the time to join in.</p>
]]></content:encoded>
			<wfw:commentRss>http://codingcockerel.co.uk/2010/01/22/plugging-elmah-into-asp-net-mvc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom routing for ASP .NET MVC</title>
		<link>http://codingcockerel.co.uk/2008/05/26/custom-routing-for-asp-net-mvc/</link>
		<comments>http://codingcockerel.co.uk/2008/05/26/custom-routing-for-asp-net-mvc/#comments</comments>
		<pubDate>Mon, 26 May 2008 17:29:36 +0000</pubDate>
		<dc:creator>codingcockerel</dc:creator>
				<category><![CDATA[.NET]]></category>
		<category><![CDATA[ASP .NET]]></category>
		<category><![CDATA[ASP .NET MVC]]></category>

		<guid isPermaLink="false">http://codingcockerel.co.uk/?p=20</guid>
		<description><![CDATA[Those familiar with the MVC framework for ASP .NET will know that one of its primary features is the mapping of URLs to methods on controllers. For example, /Products/Find will cause the ProductsController to be created and have its Find method invoked. It is also possible to pass arguments to methods, for instance /Products/Load/53 would [...]]]></description>
			<content:encoded><![CDATA[<p><img style="margin-right:15px;margin-bottom:5px;float:left;" src="http://codingcockerel.co.uk/wp-content/uploads/2008/05/Routing.jpg" alt="Custom routing for ASP .NET MVC" />
<p>Those familiar with the <a href="http://www.asp.net/mvc/" title="ASP .NET MVC">MVC framework for ASP .NET</a> will know that one of its primary features is the mapping of URLs to methods on controllers. For example, /Products/Find will cause the ProductsController to be created and have its Find method invoked. It is also possible to pass arguments to methods, for instance /Products/Load/53 would call the Load method of the ProductsController, supplying 53 as the argument.</p>
<h3>Organising controllers</h3>
<p>Whilst this allows the developer to structure their code better, keeping presentational logic in the view and application logic in the controller, it isn&#8217;t ideal. To continue the example, as the project grows it will provide an increasing amount of features related to products, all of which will be delivered by the ProductsController. As a result the code for searching for products will end up in the same class as that used to edit products, and so on.</p>
<p>Everyone has their own take on the <a href="http://martinfowler.com/eaaDev/uiArchs.html" title="Martin Fowler - GUI Architectures">MVC</a> pattern and in the past I have tended to use one controller per <em><a href="http://en.wikipedia.org/wiki/Use_case" title="Use Case">use case</a></em>. The use cases in question here are Find Product and Edit Product and as such their functionality would be provided by the FindProductController and EditProductController, rather than living together in a single ProductsController.</p>
<p>A simple way to implement this pattern is to keep the ProductsController and have it delegate all its work. For example, the Load method would simply create an instance of EditProductController and call its Load method, passing any arguments as well. Whilst this is feasible it is more of a workaround than a genuine solution. It would be far better to cut out the ProductsController altogether, and have methods on the two controllers be called directly. The routing engine in ASP .NET MVC is very flexible and, by developing a custom route, it is possible to do this.</p>
<h3>Creating a custom route</h3>
<p>It is the job of a route to take a URL and call the appropriate method of a controller. The default MVC route has a format of {controller}/{action}/{id}, however our use case route will use {useCaseNoun}/{useCaseVerb}/{action}/{id}. The key difference is that the controller token has been replaced with two new tokens, noun and verb. This will allow us to provide the following routes</p>
<table border="1">
<tr>
<td><strong>URL</strong></td>
<td><strong>Controller</strong></td>
<td><strong>Action</strong></td>
<td><strong>Behaviour</strong></td>
</tr>
<tr>
<td>/Product/Find/Search</td>
<td>FindProductController</td>
<td>Search</td>
<td>Execute a search for products and display the results</td>
</tr>
<tr>
<td>/Product/Find/Clear</td>
<td>FindProductController</td>
<td>Clear</td>
<td>Reset all the fields of the search page</td>
</tr>
<tr>
<td>/Product/Find</td>
<td>FindProductController</td>
<td>[default]</td>
<td>Execute the default controller method (more on this shortly)</td>
</tr>
<tr>
<td>/Product/Edit/Load/17</td>
<td>EditProductController</td>
<td>Load(17)</td>
<td>Load the product with ID 17 and display its data for editing</td>
</tr>
<tr>
<td>/Product/Edit/Save/23</td>
<td>EditProductController</td>
<td>Save(23)</td>
<td>Save the supplied data against the product with ID 23</td>
</tr>
<tr>
<td>/Product/Edit/Clear</td>
<td>EditProductController</td>
<td>Clear</td>
<td>Clear out the edit page ready for entering a new product</td>
</tr>
</table>
<p>A fringe benefit of adopting this strategy is that both controllers can have a method of the same name, e.g. Clear, but have the method perform a completely different task. With a single ProductsController there could only be one Clear method.</p>
<p>In order to register the custom route with the MVC framework, some changes need to be made to the Global.asax file. Its Application_Start method calls RegisterRoutes which, using the default MVC project template, will already set up the default route format of {controller}/{action}/{id}. To this method we need to add the following</p>
<pre class="brush: csharp; title: ; notranslate">
routes.Add(new Route(&quot;{useCaseNoun}/{useCaseVerb}/{action}/{id}&quot;, new MvcRouteHandler())
{
Defaults = new RouteValueDictionary(new { action = &quot;Index&quot;, id = &quot;&quot; }),
});
</pre>
<p>Note that the default action is Index so, in the case of the /Product/Find URL in the table above, this would map to the Index method of the FindProductController.</p>
<p>At this point we can use <a href="http://haacked.com" title="Phil Haack">Phil Haack</a>&#8216;s <a href="http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx" title="Url Routing Debugger">Url Routing Debugger</a> to test that our URLs are being correctly routed. To do so we get a reference to Phil&#8217;s RouteDebug.dll and add the following code after RegisterRoutes is called</p>
<pre class="brush: csharp; title: ; notranslate">
RouteDebug.RouteDebugger.RewriteRoutesForTesting(RouteTable.Routes);
</pre>
<p>It is then possible to enter each of URLs into a browser and see which route they match. Check out <a href="http://haacked.com/archive/2008/03/13/url-routing-debugger.aspx" title="Url Routing Debugger">Phil&#8217;s post</a> for further details.</p>
<h3>Creating a handler for the route</h3>
<p>The format of our route is such that the {controller} token is no longer present. As a result the MvcRouteHandler that is associated with the route will <em>not</em> be able to identify which controller to use. Typically it just extracts the value of the controller token, appends &#8220;Controller&#8221; to it, and instantiates an object of that type. To resolve this issue we need to replace MvcRouteHandler with a route handler of our own.</p>
<p>Fredrik Normén produced an excellent blog post, <a href="http://weblogs.asp.net/fredriknormen/archive/2007/11/18/asp-net-mvc-framework-create-your-own-iroutehandler.aspx" title="Create your own IRouteHandler">Create your own IRouteHandler</a>, which describes how to do this. For our route, we need to create two new classes, the first of which implements IRouteHandler, as shown below</p>
<pre class="brush: csharp; title: ; notranslate">
public class UseCaseRouteHandler : IRouteHandler
{
    public IHttpHandler GetHttpHandler(RequestContext requestContext)
    {
        return new UseCaseMvcHandler(requestContext);
    }
}
</pre>
<p>This class, UseCaseRouteHandler, is used in place of MvcRouteHandler, and simply creates a new IHttpHandler which will do the real work. The implementation of IHttpHandler is actually our second class, UseCaseMvcHandler. This inherits from MvcHandler and overrides the ProcessRequest method, during which the correct controller is identified and then created. It is this behaviour that we need to redefine.</p>
<p>To determine how our ProcessRequest should work, I downloaded the source code of the MVC framework itself, which is available from <a href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=12640" title="ASP .NET MVC source code on CodePlex">CodePlex</a>. A quick inspection of <a href="http://www.codeplex.com/aspnet/SourceControl/FileView.aspx?itemId=8295&amp;changeSetId=6256" title="MvcHandler source code">MvcHandler</a>&#8216;s ProcessRequest shows that the GetRequiredString method is used to extract the values of the route&#8217;s tokens. For the default routing this is just a case of getting the controller name, whereas our custom route needs to grab both the {useCaseNoun} and {useCaseVerb} tokens. I moved this logic into a separate function, GetControllerName, which is shown below</p>
<pre class="brush: csharp; title: ; notranslate">
private string GetControllerName()
{
    string noun = this.RequestContext.RouteData.GetRequiredString(&quot;useCaseNoun&quot;);
    string verb = this.RequestContext.RouteData.GetRequiredString(&quot;useCaseVerb&quot;);
    return verb + noun;
}
</pre>
<p>So, if the URL is /Product/Find/Search, this method will extract a noun of &#8220;Product&#8221;, a verb of &#8220;Find&#8221; and return the value &#8220;FindProduct&#8221;.</p>
<p>I then copied MvcHandler&#8217;s ProcessRequest code into UseCaseMvcHandler and replaced the line extracting the controller token value with a call to the GetControllerName function. Simple. Well, almost! Unfortunately the resource strings are not available to inheriting classes, and neither is the ControllerBuilder property. I replaced the former with a hard-wired string, whilst the latter is accessible via the ControllerBuilder class&#8217; static Current property.</p>
<p>At this point the code is almost ready to run. We just need to adjust the code in RegisterRoutes so that our route uses the new UseCaseRouteHandler class. This is done as follows</p>
<pre class="brush: csharp; title: ; notranslate">
routes.Add(new Route(&quot;{useCaseNoun}/{useCaseVerb}/{action}/{id}&quot;, new UseCaseRouteHandler())
{
Defaults = new RouteValueDictionary(new { action = &quot;Index&quot;, id = &quot;&quot; }),
});
</pre>
<h3>Identifying which view to show</h3>
<p>Having commented out the call to the routing debugger, I then browsed to /Product/Edit/Load/17 and&#8230;BANG! An exception with the message,</p>
<blockquote><p>
The RouteData must contain an item named &#8216;controller&#8217; with a non-empty string value
</p></blockquote>
<p>was shown. After some digging through the MVC source, it seems that the code responsible for identifying which view to create (the ViewEngine class does this) was also trying to find a controller token in the URL, in order to work out which subfolder of Views to look in. The Load method of EditProductController calls RenderView, passing &#8220;Edit&#8221; as the viewName argument. By altering this to &#8220;~/Views/Product/Edit.aspx&#8221; I was able to work around this issue.</p>
<p>This was a far from satisfactory solution however. Fully-qualifying all of the view names is a potential maintenance problem in the future, if views are moved or folders renamed. To combat this I introduced a UseCaseControllerBase class, from which EditProductController and FindProductController now inherit. This class overrides RenderView and works out the full path to the view. The following code shows how</p>
<pre class="brush: csharp; title: ; notranslate">
public abstract class UseCaseControllerBase : Controller
{
    protected override void RenderView(string viewName, string masterName, object viewData)
    {
        string noun = this.RouteData.GetRequiredString(&quot;useCaseNoun&quot;);
        string fullViewName = string.Format(&quot;~/Views/{0}/{1}.aspx&quot;, noun, viewName);
        base.RenderView(fullViewName, masterName, viewData);
    }
}
</pre>
<p>The ideal resolution would be to customise the behaviour of the ViewEngine, however that is beyond the scope of this article.</p>
<p>This post demonstrates the flexibility of the routing subsystem provided by ASP .NET. It also shows how to improve the separation of functionality between controllers. If you are interested the sample code is available from <a href="https://www.codeplex.com/Release/ProjectReleases.aspx?ProjectName=codingcockerel&amp;ReleaseId=13768" title="CodePlex">CodePlex</a>.</p>
<p>Technorati tags: <a href="http://technorati.com/tag/.net" rel="tag">.NET</a> <a href="http://technorati.com/tag/asp .net" rel="tag">ASP .NET</a> <a href="http://technorati.com/tag/aspnetmvc" rel="tag">ASP .NET MVC</a></p>
]]></content:encoded>
			<wfw:commentRss>http://codingcockerel.co.uk/2008/05/26/custom-routing-for-asp-net-mvc/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>

