<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://weblogs.asp.net/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Melvyn Harbour : ASP.NET</title><link>http://weblogs.asp.net/melvynharbour/archive/tags/ASP.NET/default.aspx</link><description>Tags: ASP.NET</description><dc:language>en</dc:language><generator>CommunityServer 2007 SP1 (Build: 20510.895)</generator><item><title>Combining ASP.NET MVC and ASP.NET Charting Controls</title><link>http://weblogs.asp.net/melvynharbour/archive/2008/11/25/combining-asp-net-mvc-and-asp-net-charting-controls.aspx</link><pubDate>Tue, 25 Nov 2008 16:22:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6753768</guid><dc:creator>MelvynHarbour</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/rsscomments.aspx?PostID=6753768</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/commentapi.aspx?PostID=6753768</wfw:comment><comments>http://weblogs.asp.net/melvynharbour/archive/2008/11/25/combining-asp-net-mvc-and-asp-net-charting-controls.aspx#comments</comments><description>&lt;P&gt;As ScottGu recently posted &lt;A href="http://weblogs.asp.net/scottgu/archive/2008/11/24/new-asp-net-charting-control-lt-asp-chart-runat-quot-server-quot-gt.aspx" mce_href="http://weblogs.asp.net/scottgu/archive/2008/11/24/new-asp-net-charting-control-lt-asp-chart-runat-quot-server-quot-gt.aspx"&gt;on his blog&lt;/A&gt;, Microsoft have recently released a set of charting components. Several people followed up with comments on his post asking whether it was possible to use them with ASP.NET MVC. The good news is that it certainly is, if you are using ASP.NET as the View engine (the default). And there's actually relatively little that you have to do. This post outlines the steps you'll need to take to get it up and running.&lt;/P&gt;
&lt;P&gt;You'll need to first add the references to the appropriate assemblies (System.Web.DataVisualization and System.Web.DataVisualization.Design if you want design support). You also need to add a couple of lines to your Web.Config file. In the &amp;lt;controls&amp;gt; section, you will need to add:&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BACKGROUND-COLOR: #f4f4f4"&gt;
&lt;DIV style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   1:&lt;/SPAN&gt; &amp;lt;add tagPrefix=&lt;SPAN style="COLOR: #006080"&gt;"asp"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;namespace&lt;/SPAN&gt;=&lt;SPAN style="COLOR: #006080"&gt;"System.Web.UI.DataVisualization.Charting"&lt;/SPAN&gt; assembly=&lt;SPAN style="COLOR: #006080"&gt;"System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"&lt;/SPAN&gt;/&amp;gt;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   2:&lt;/SPAN&gt;&amp;nbsp; &lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;You'll also need to add a new line to the httpHandlers section:&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BACKGROUND-COLOR: #f4f4f4"&gt;
&lt;DIV style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   1:&lt;/SPAN&gt; &amp;lt;add path=&lt;SPAN style="COLOR: #006080"&gt;"ChartImg.axd"&lt;/SPAN&gt; verb=&lt;SPAN style="COLOR: #006080"&gt;"GET,HEAD"&lt;/SPAN&gt; type=&lt;SPAN style="COLOR: #006080"&gt;"System.Web.UI.DataVisualization.Charting.ChartHttpHandler, System.Web.DataVisualization, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"&lt;/SPAN&gt; validate=&lt;SPAN style="COLOR: #006080"&gt;"false"&lt;/SPAN&gt;/&amp;gt;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   2:&lt;/SPAN&gt;&amp;nbsp; &lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;It's then pretty much simplicity itself to add a chart to a view page - you just drop it on as a server control exactly as in the examples in the sample project linked for Scott's post. You'll obviously need to call the code to insert the DataPoint objects into an appropriate Series, and this will probably lead to a few lines of code in the code behind file, but given that the data-transfer objects between the controller and the view are generally reasonably well structured, this code should be both readable, and fairly short, so I don't think that it's really a problem.&lt;/P&gt;
&lt;P&gt;I think the best approach if you are interested in doing this is to simply have a go and see how it gets on. I think it's a nice simple solution myself and certainly doesn't represent a great deal of overhead to get the result out.&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6753768" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/MVC/default.aspx">MVC</category><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/Charting/default.aspx">Charting</category></item><item><title>MVC ModelBinder and Localization</title><link>http://weblogs.asp.net/melvynharbour/archive/2008/11/21/mvc-modelbinder-and-localization.aspx</link><pubDate>Fri, 21 Nov 2008 11:13:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6749256</guid><dc:creator>MelvynHarbour</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/rsscomments.aspx?PostID=6749256</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/commentapi.aspx?PostID=6749256</wfw:comment><comments>http://weblogs.asp.net/melvynharbour/archive/2008/11/21/mvc-modelbinder-and-localization.aspx#comments</comments><description>&lt;P&gt;One of the great things about the way in which the Microsoft ASP.NET MVC Framework is being developed is the fact that the team are publishing the source code as they go along. This makes it very simple to dig into the framework when something slightly surprising is happening and figure out exactly how it is &lt;EM&gt;supposed&lt;/EM&gt; to work. A good example of this cropped up for us yesterday when looking at a form posting scenario using DateTimes. We were dealing with an Action Method that looked something like this:&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BACKGROUND-COLOR: #f4f4f4"&gt;
&lt;DIV style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   1:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; ActionResult DoSomething(DateTime theDate)&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   2:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   3:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; View();&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   4:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;And using the automatic model binding infrastructure to set the method parameter from a form. Naturally, being based in England, we were not totally shocked when we ran into localization issues almost immediately with this. It appeared at first glance that the date was being parsed assuming en-US format (mm/dd/yyyy), whereas for the application we were writing, which will be used internally be people who will expect to use en-GB (dd/mm/yyyy), we wanted it to parse in a different format. This prompted some investigation to discover what the framework was using to make its decision about which culture to use. The result turned out to be somewhat more clever than we had first thought, and nicely illustrates the way in which MVC Framework applications should be structured.&lt;/P&gt;
&lt;P&gt;The initially surprising piece of information that it transpires that it actually matters whether you have set the HTTP method to be a GET or a POST. To understand why this is the case, here is a snippet from within the MVC source code. I have removed several lines from the code to make it easier to see what is going on. If you want to see the original, it is within GetValue(string name) of System.Web.Mvc.DefaultValueProvider.&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BACKGROUND-COLOR: #f4f4f4"&gt;
&lt;DIV style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   1:&lt;/SPAN&gt; CultureInfo culture = CultureInfo.InvariantCulture;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   2:&lt;/SPAN&gt;&amp;nbsp; &lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   3:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (request.QueryString != &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   4:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   5:&lt;/SPAN&gt;     rawValue = request.QueryString.GetValues(name);&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   6:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   7:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (rawValue == &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt; &amp;amp;&amp;amp; request.Form != &lt;SPAN style="COLOR: #0000ff"&gt;null&lt;/SPAN&gt;)&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   8:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   9:&lt;/SPAN&gt;     culture = CultureInfo.CurrentCulture;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  10:&lt;/SPAN&gt;     rawValue = request.Form.GetValues(name);&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  11:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;In other words, when looking for the value to parse, the framework looks in a specific order namely:&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;RouteData (&lt;EM&gt;not shown above&lt;/EM&gt;)&lt;/LI&gt;
&lt;LI&gt;URI query string&lt;/LI&gt;
&lt;LI&gt;Request form&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Only the last of these will be culture aware however. There is a very good reason for this, from a localization perspective. Imagine that I have written a web application showing airline flight information that I publish online. I look up flights on a certain date by clicking on a link for that day (perhaps something like http://www.melsflighttimes.com/Flights/2008-11-21), and then want to email that link to my colleague in the US. The only way that we could guarantee that we will both be looking at the same page of data is if the InvariantCulture is used. By contrast, if I'm using a form to book my flight, everything is happening in a tight cycle. The data can respect the CurrentCulture when it is written to the form, and so needs to respect it when coming back from the form.&lt;/P&gt;
&lt;P&gt;But this brings us back to a consideration of the HTTP method that has been used. Remember that if we set the form to be HTTP GET, when the form is submitted the values of the fields in the form will be turned into a query string. So they will be parsed with the InvariantCulture rather than the CurrentCulture, as they would have been if it were an HTTP POST. We can therefore toggle the behaviour of the form (from a localization standpoint) by changing the HTTP method.&lt;/P&gt;
&lt;P&gt;Now to me this seemed slightly surprising at first, but I can certainly see that from the framework authors' perspective, it's the correct way of doing things. It still does leave one loose end, from a technical perspective. Suppose now that out airline flight information application allows the user to type in a date for which they wish to view flight information rather than clicking on a (computer generated) hyperlink. This is not an unreasonable behaviour, and is probably far more realistic of the way that the application would in fact be written. I still want the form to submit via HTTP GET rather than POST, as I want a URL to be generated that my user could email to his colleague. Effectively therefore, I have mandated that the user needs to enter the date using the InvariantCulture, which is hardly very localization friendly! If the application is only going to be used by people in (for example) en-GB (as might be the case for a company internal application), it is very possible that the date format will be known, and specified.&lt;/P&gt;
&lt;P&gt;Help is at hand though! Luckily, the way that the MVC Framework has been written makes it very easy for us to drop in other components to ensure that specific parts of the application such as this run the way that we expect them to. In this instance, what we want to do is register a new ModelBinder that will handle this DateTime to parse it using a specified culture. Writing a new ModelBinder is actually staggeringly simple. All we need to do is implement IModelBinder, and then register the new ModelBinder in Global.asax.cs. A very simple example of a custom ModelBinder to force the binding of DateTimes to always use en-GB is given below.&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BACKGROUND-COLOR: #f4f4f4"&gt;
&lt;DIV style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   1:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;class&lt;/SPAN&gt; MyBinder : IModelBinder&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   2:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   3:&lt;/SPAN&gt;&amp;nbsp; &lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   4:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #cc6633"&gt;#region&lt;/SPAN&gt; IModelBinder Members&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   5:&lt;/SPAN&gt;&amp;nbsp; &lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   6:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; ModelBinderResult BindModel(ModelBindingContext bindingContext)&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   7:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   8:&lt;/SPAN&gt;         &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; theDate = bindingContext.HttpContext.Request.QueryString[&lt;SPAN style="COLOR: #006080"&gt;"theDate"&lt;/SPAN&gt;];&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   9:&lt;/SPAN&gt;         DateTime dt = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; DateTime();&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  10:&lt;/SPAN&gt;         &lt;SPAN style="COLOR: #0000ff"&gt;bool&lt;/SPAN&gt; success = DateTime.TryParse(theDate, CultureInfo.GetCultureInfo(&lt;SPAN style="COLOR: #006080"&gt;"en-GB"&lt;/SPAN&gt;), DateTimeStyles.None, &lt;SPAN style="COLOR: #0000ff"&gt;out&lt;/SPAN&gt; dt);&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  11:&lt;/SPAN&gt;         &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (success)&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  12:&lt;/SPAN&gt;         {&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  13:&lt;/SPAN&gt;             &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; ModelBinderResult(dt);&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  14:&lt;/SPAN&gt;         }&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  15:&lt;/SPAN&gt;         &lt;SPAN style="COLOR: #0000ff"&gt;else&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  16:&lt;/SPAN&gt;         {&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  17:&lt;/SPAN&gt;             &lt;SPAN style="COLOR: #008000"&gt;// Return an appropriate default&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  18:&lt;/SPAN&gt;         }&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  19:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  20:&lt;/SPAN&gt;&amp;nbsp; &lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  21:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #cc6633"&gt;#endregion&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  22:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;We then just need to tell MVC to use the ModelBinder. All this takes is a line in Global.asax saying:&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BACKGROUND-COLOR: #f4f4f4"&gt;
&lt;DIV style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   1:&lt;/SPAN&gt; ModelBinders.Binders.Add(&lt;SPAN style="COLOR: #0000ff"&gt;typeof&lt;/SPAN&gt;(DateTime), &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; MyModelBinder());&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;Of course the custom ModelBinder could be modified to do anything else that you want to, or indeed descend from DefaultModelBinder, and use other properties of the binding to help it determine whether it should use the new behaviour, or leave it up to the original DefaultModelBinder. The above example isn't particularly realistic in that we have mandated that the value of a DateTime will be coming in on a query string parameter of 'theDate'. It would normally be the case that we would use other properties of the ModelBindingContext to be more accurate about the situations we need to override. The ModelBinder could also be specified explicitly using an attribute on the method parameter.&lt;/P&gt;
&lt;P&gt;On a side note, I thought it would be worth linking to an article featuring &lt;A href="http://www.simple-talk.com/community/blogs/redwork/archive/2008/11/20/70552.aspx" mce_href="http://www.simple-talk.com/community/blogs/redwork/archive/2008/11/20/70552.aspx"&gt;Red Gate's biggest fan&lt;/A&gt;!&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6749256" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/MVC/default.aspx">MVC</category><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>How to use the ASP.NET MVC ModelBinder</title><link>http://weblogs.asp.net/melvynharbour/archive/2008/08/29/how-to-use-the-asp-net-mvc-modelbinder.aspx</link><pubDate>Fri, 29 Aug 2008 10:30:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6575268</guid><dc:creator>MelvynHarbour</dc:creator><slash:comments>10</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/rsscomments.aspx?PostID=6575268</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/commentapi.aspx?PostID=6575268</wfw:comment><comments>http://weblogs.asp.net/melvynharbour/archive/2008/08/29/how-to-use-the-asp-net-mvc-modelbinder.aspx#comments</comments><description>&lt;P&gt;One of the new features in the latest build of ASP.NET MVC is the ModelBinder, which is provided to allow Action methods to take complex types as their parameters. Previously, action methods were only able to take simple types such as strings and integers as their parameters. The new ModelBinder provides the facility to build complex types from component parts that (for example) may be part the result of submitting a form with several fields. To see an example of this in action, we will first need a fairly simple class to work with. The following class definition will typically be placed in the Models directory. I have left the &lt;EM&gt;using&lt;/EM&gt; statements at the start of the file as an 'exercise for the reader'!&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BACKGROUND-COLOR: #f4f4f4"&gt;
&lt;DIV style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   1:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;class&lt;/SPAN&gt; MBTest&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   2:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   3:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; Name { get; set; }&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   4:&lt;/SPAN&gt;&amp;nbsp; &lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   5:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; MBTest()&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   6:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   7:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   8:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;All fairly standard stuff. Now let's create a form on our index page that we can use to have a play with one of these objects:&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BACKGROUND-COLOR: #f4f4f4"&gt;
&lt;DIV style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   1:&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR: #ffff00"&gt;&amp;lt;%&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;using&lt;/SPAN&gt; (Html.Form(&lt;SPAN style="COLOR: #006080"&gt;"Home"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #006080"&gt;"About"&lt;/SPAN&gt;)) { &lt;SPAN style="BACKGROUND-COLOR: #ffff00"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   2:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;input&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="text"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;name&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Name"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   3:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;button&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="submit"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;Submit&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;button&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   4:&lt;/SPAN&gt; &lt;SPAN style="BACKGROUND-COLOR: #ffff00"&gt;&amp;lt;%&lt;/SPAN&gt; } &lt;SPAN style="BACKGROUND-COLOR: #ffff00"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;Again, just the relevant form supplied here, and kept as simple as possible for clarity. Nothing in the routing needs to change: that will all happen just fine. Now, the aim is to write an Action Method that looks like the following:&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BACKGROUND-COLOR: #f4f4f4"&gt;
&lt;DIV style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   1:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; ActionResult About(MBTest testItem)&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   2:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   3:&lt;/SPAN&gt;     ViewData[&lt;SPAN style="COLOR: #006080"&gt;"Title"&lt;/SPAN&gt;] = &lt;SPAN style="COLOR: #006080"&gt;"About Page"&lt;/SPAN&gt;;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   4:&lt;/SPAN&gt;&amp;nbsp; &lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   5:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; View();&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   6:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;Admittedly, this method doesn't actually &lt;EM&gt;do&lt;/EM&gt; anything with the testItem object that it creates, but it could quite easily if it wanted to. What we want is that the Name property of testItem is populated with the contents of the text input field in our form. Previously, we would have done this by inserting code into the About method above to parse the results coming back. So here's the new bit. We create a helper class that will carry the knowledge of how to perform the translation from the form to the complex type. This class must implement the new interface IModelBinder.&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BACKGROUND-COLOR: #f4f4f4"&gt;
&lt;DIV style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   1:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;class&lt;/SPAN&gt; MBTestBinder : IModelBinder&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   2:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   3:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #cc6633"&gt;#region&lt;/SPAN&gt; IModelBinder Members&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   4:&lt;/SPAN&gt;&amp;nbsp; &lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   5:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;object&lt;/SPAN&gt; GetValue(ControllerContext controllerContext, &lt;SPAN style="COLOR: #0000ff"&gt;string&lt;/SPAN&gt; modelName, Type modelType, ModelStateDictionary modelState)&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   6:&lt;/SPAN&gt;     {&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   7:&lt;/SPAN&gt;         MBTest instance = &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; MBTest();&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   8:&lt;/SPAN&gt;         instance.Name = controllerContext.HttpContext.Request[&lt;SPAN style="COLOR: #006080"&gt;"Name"&lt;/SPAN&gt;];&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   9:&lt;/SPAN&gt;         &lt;SPAN style="COLOR: #0000ff"&gt;return&lt;/SPAN&gt; instance;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  10:&lt;/SPAN&gt;     }&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  11:&lt;/SPAN&gt;&amp;nbsp; &lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  12:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #cc6633"&gt;#endregion&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;  13:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;Obviously this is a very simple example, and I haven't used most of the information passed to the GetValue method, but the intention of this post is primarily to be a starting point, just to get you 'up and running'. So the MBTestBinder class functions as a bridge, in a similar way to an ADO.NET DataAdapter. There's one final step to getting this all hooked up, and that's to tell the code to use MBTestBinder. This is done by applying the new ModelBinderAttribute to things. There are actually two different places you can use this attribute, with the same effect. The first is by decorating the model class:&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BACKGROUND-COLOR: #f4f4f4"&gt;
&lt;DIV style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   1:&lt;/SPAN&gt; [ModelBinder(&lt;SPAN style="COLOR: #0000ff"&gt;typeof&lt;/SPAN&gt;(MBTestBinder))]&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   2:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;class&lt;/SPAN&gt; MBTest&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;The second is decorating the parameter of your Action Method directly:&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BACKGROUND-COLOR: #f4f4f4"&gt;
&lt;DIV style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   1:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;public&lt;/SPAN&gt; ActionResult About([ModelBinder(&lt;SPAN style="COLOR: #0000ff"&gt;typeof&lt;/SPAN&gt;(MBTestBinder))]MBTest testItem)&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;My guess is that they've left the choice in because the decision about exactly where bridge classes such as MBTestBinder actually lives is not a straightforward one. Others will no doubt contribute much more involved examples and discuss whether this solution to the problem is even the correct one, but hopefully this post explains enough to enable people to get started with experimenting with it and getting a feel for it.&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6575268" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/MVC/default.aspx">MVC</category><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>ASP.NET MVC Codeplex Preview 5</title><link>http://weblogs.asp.net/melvynharbour/archive/2008/08/29/asp-net-mvc-codeplex-preview-5.aspx</link><pubDate>Fri, 29 Aug 2008 08:53:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6575162</guid><dc:creator>MelvynHarbour</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/rsscomments.aspx?PostID=6575162</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/commentapi.aspx?PostID=6575162</wfw:comment><comments>http://weblogs.asp.net/melvynharbour/archive/2008/08/29/asp-net-mvc-codeplex-preview-5.aspx#comments</comments><description>&lt;P mce_keep="true"&gt;ASP.NET MVC Codeplex preview 5 went live last night. Available &lt;A class="" href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=16775" mce_href="http://www.codeplex.com/aspnet/Release/ProjectReleases.aspx?ReleaseId=16775"&gt;here&lt;/A&gt;. I haven't had a dig into it yet to have (just downloading now), but according to the release notes, some of the highlights include:&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;More support for partial view rendering&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Moving AJAX support into its own namespace (System.Web.Mvc.Ajax) to make it easier to swap it out and replace it with your own choice, such as jQuery.&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Complex types as parameters of action methods (some discussion of this already in my post &lt;A href="http://weblogs.asp.net/melvynharbour/archive/2008/07/30/clean-separation-of-concerns-in-mvc.aspx"&gt;http://weblogs.asp.net/melvynharbour/archive/2008/07/30/clean-separation-of-concerns-in-mvc.aspx&lt;/A&gt;&amp;nbsp;and the associated forum thread).&lt;/DIV&gt;&lt;/LI&gt;
&lt;LI&gt;
&lt;DIV mce_keep="true"&gt;Various other tweaks and improvements particularly to helper methods.&lt;/DIV&gt;&lt;/LI&gt;&lt;/UL&gt;
&lt;P mce_keep="true"&gt;The source code apparently follows shortly!&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6575162" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/MVC/default.aspx">MVC</category><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>Clean Separation of Concerns in MVC</title><link>http://weblogs.asp.net/melvynharbour/archive/2008/07/30/clean-separation-of-concerns-in-mvc.aspx</link><pubDate>Wed, 30 Jul 2008 10:39:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6460178</guid><dc:creator>MelvynHarbour</dc:creator><slash:comments>12</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/rsscomments.aspx?PostID=6460178</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/commentapi.aspx?PostID=6460178</wfw:comment><comments>http://weblogs.asp.net/melvynharbour/archive/2008/07/30/clean-separation-of-concerns-in-mvc.aspx#comments</comments><description>&lt;P&gt;One of the main areas that is cited as a benefit of using the new ASP.NET MVC Framework is that you can obtain a 'clean separation of concerns'. But the question is, what does this really mean, how achievable is it in reality, and should we really be interested in doing it?&lt;/P&gt;
&lt;H3&gt;What does it mean?&lt;/H3&gt;
&lt;P&gt;Well, from Wikipedia (&lt;A title=http://en.wikipedia.org/wiki/Separation_of_concerns href="http://en.wikipedia.org/wiki/Separation_of_concerns" mce_href="http://en.wikipedia.org/wiki/Separation_of_concerns"&gt;http://en.wikipedia.org/wiki/Separation_of_concerns&lt;/A&gt;) - 'the process of breaking a computer program into distinct features that overlap in functionality as little as possible'. The article goes on to say that the MVC design pattern aims to separate content from presentation and data-processing from content. This is all well and good, but where do the lines of separation fall. One is reasonably clear - between the data-processing (&lt;EM&gt;Model&lt;/EM&gt;) and the rest of the application. Almost every attempt at writing an MVC Framework web application illustrates this successfully.&lt;/P&gt;
&lt;P&gt;The slightly harder area to tie down the separation for is when you look at &lt;EM&gt;Views&lt;/EM&gt; and &lt;EM&gt;Controllers&lt;/EM&gt;. Where should the separation occur? What is the division of responsibility? Should the two portions be completely independent, or can they have knowledge of each other? At a certain level, it is reasonably easy to provide some definitions: the view takes responsibility for &lt;EM&gt;presentation&lt;/EM&gt;, and the controller takes responsibility for &lt;EM&gt;actions&lt;/EM&gt;. But there is clearly a grey area in the middle. Clearly most actions can be completed without much dependency on the view that is their 'end point', but the reverse is not necessarily true. In a simple 'display' view there is no problem, but by the time we move to 'editors', we are starting to get into the realms of some trickiness of definition. In fact the way the view is set up may have critical importance to the nature of the controller. This is probably best illustrated with an example. Let us say that I have written a appointment diary application. One of the editors in this is used to change the date of an appointment. I could choose to display this date in one text-box (DD/MM/YYYY format), or I could decide that it will be easier to use if I split it and put the day, month and year components of the date in different text-boxes. Either way, I have introduced a link between the way the data was displayed and my controller. If I change one way of displaying the date into another, I may need to change the controller, unless the view takes care of returning the date to the format from which it 'came'.&lt;/P&gt;
&lt;P&gt;But here lies another problem - 'format from which it came'. It's perfectly legitimate in MVC that the View may have fetched the data it is displaying from the Model directly and that the Controller had no knowledge of the original form of the data at all. Either way, we are getting towards the situation where the Controller needs knowledge of at least one of the Model and the View in order to function. The problem really comes from the nature of HTTP. The View is split between what it was on the server, and what is able to be transmitted 'over the wire'.&lt;/P&gt;
&lt;H3&gt;So is full separation achievable?&lt;/H3&gt;
&lt;P&gt;Well, we could remove the requirement that the Controller knows things about the View. It would require something of a rethink to the way the MVC Framework is currently designed though. It would require that Views 'submit back to themselves', that the View can then sort out the data before triggering an appropriate Controller action. But there is a problem. We've essentially introduced a dependency that the View now needs to know about the Controller. So we're back to square one! I therefore don't think that the View and Controller having no knowledge of the structure of each other is practical. They are implicitly linked.&lt;/P&gt;
&lt;H3&gt;Where does that leave us?&lt;/H3&gt;
&lt;P&gt;Well, not all at sea, thankfully! And luckily, I think in considering what we really mean, we come to what really turns out to be a very good way of architecting an MVC web application. I believe that the separation is not a totally strict one of encapsulating all knowledge about the different portions of the code, but rather a clean separation between behaviours and views. Interestingly, this is one of the key points of object oriented design that is often overlooked - designing an application by the behaviours that it must be capable of. The REST-like routing system built into the MVC Framework as it stands takes you even further down this route of considering the application to be much like an object oriented design. Essentially therefore, Controllers can (in some sense) be likened to classes (and indeed this is the language construct they use!), and Action methods are the behaviours of which a Controller is capable. The big advantage of these Action methods being thought of as behaviours is that writing Unit Tests for them becomes a very natural process.&lt;/P&gt;
&lt;P&gt;The conclusion of all of this is that there is going to have to be linking between your Controllers and Views. They can't be written to operate independently. The key point is to see the separation between behaviours and templates. Don't code things that are going to cause a change to the model into your View, and don't code things that are purely a matter of presentation into your Controllers, but expect a certain amount of grey area where the communication between them is concerned.&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6460178" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/MVC/default.aspx">MVC</category><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>MVC AJAX Support</title><link>http://weblogs.asp.net/melvynharbour/archive/2008/07/22/mvc-ajax-support.aspx</link><pubDate>Tue, 22 Jul 2008 09:55:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6430369</guid><dc:creator>MelvynHarbour</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/rsscomments.aspx?PostID=6430369</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/commentapi.aspx?PostID=6430369</wfw:comment><comments>http://weblogs.asp.net/melvynharbour/archive/2008/07/22/mvc-ajax-support.aspx#comments</comments><description>&lt;P mce_keep="true"&gt;In the latest preview of the Microsoft ASP.NET MVC Framework, one of the newly included features is AJAX helper methods. It's going to be interesting to see where they go with these. At the moment, they've added just a couple of tasters. This blog post discusses how to set them up and make use of them if you want to try them out. Currently, there are two helper methods that have been created, Ajax.ActionLink and Ajax.Form. I will discuss both below. They both generate HTML, much in the manner of pre-existing helpers such as Html.Form.&lt;/P&gt;
&lt;P mce_keep="true"&gt;The first thing to look at is how to set a page up to be able to make use of these helper methods. Since they are going to call parts of the JavaScript libraries that are part of the Microsoft AJAX Framework, you need to include them in the head section of your page. There are two files that you need to include. Microsoft are currently shipping them in both debug and release configurations. It doesn't matter whether you have debug or release, but you will need to have both files included, &lt;EM&gt;and included in the correct order&lt;/EM&gt;. This will look something like the following:&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BACKGROUND-COLOR: #f4f4f4"&gt;
&lt;DIV style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   1:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;head&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;runat&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="server"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   2:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;meta&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;http-equiv&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="Content-Type"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;content&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="text/html; charset=iso-8859-1"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   3:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;title&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;AJAX Example&lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;title&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   4:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;link&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;href&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="../../Content/Site.css"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;rel&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="stylesheet"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="text/css"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   5:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;script&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="text/javascript"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;src&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="../../Content/MicrosoftAjax.js"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;script&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   6:&lt;/SPAN&gt;     &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;script&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;type&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="text/javascript"&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;src&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="../../Content/MicrosoftMvcAjax.debug.js"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;script&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   7:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;head&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;Once these have been included, you will be free to use the AJAX tools that have been developed. It is worth a quick aside to briefly discuss the payload size of these Framework helpers. Currently, MicrosoftAjax.js represents about 89KB and MicrosoftMvcAjax.debug.js is about 6KB. These numbers obviously aren't too bad. They're bigger than the equivalent jQuery files, and it will be interesting to see how it matches up as time goes on.&lt;/P&gt;
&lt;P&gt;Having set up the Framework requirements, we can proceed to use the tools supplied. The essence of the helpers that have been created so far is that they allow you to easily make an asynchronous call to a Action Method and to use the response. This essentially makes it possible to create the equivalent of the UpdatePanel from WebForms. This is probably best now illustrated with a simple example, building on top of the standard MVC site that is shipped with the Framework. In the code for the Index view (Index.aspx), we can include something like the following:&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BACKGROUND-COLOR: #f4f4f4"&gt;
&lt;DIV style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   1:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;div&lt;/SPAN&gt; &lt;SPAN style="COLOR: #ff0000"&gt;id&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;="testContainer"&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   2:&lt;/SPAN&gt;     &lt;SPAN style="BACKGROUND-COLOR: #ffff00"&gt;&amp;lt;%=&lt;/SPAN&gt; Ajax.ActionLink(&lt;SPAN style="COLOR: #006080"&gt;"About"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #006080"&gt;"About"&lt;/SPAN&gt;, &lt;SPAN style="COLOR: #0000ff"&gt;new&lt;/SPAN&gt; AjaxOptions { UpdateTargetId = &lt;SPAN style="COLOR: #006080"&gt;"testContainer"&lt;/SPAN&gt; })&lt;/PRE&gt;&lt;SPAN style="BACKGROUND-COLOR: #ffff00"&gt;%&amp;gt;&lt;/SPAN&gt;&lt;PRE&gt;&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   3:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN style="COLOR: #800000"&gt;div&lt;/SPAN&gt;&lt;SPAN style="COLOR: #0000ff"&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;The next stage is to alter the About view (About.aspx) to remove most of the strapping from it. It is not going to need to have a MasterPage for example, or in fact to have anything but some example text.&lt;/P&gt;
&lt;P&gt;So, what is the effect of all this? Well, run it up in a browser and we'll see what happens. As you might expect, running the default page for the site brings up the Home/Index page as normal. Some way down the page, there is a link with the text 'About'. So we click on it. What should happen, all being well, is that the contents of the About view becomes inserted into the page in place of the About link.&lt;/P&gt;
&lt;P&gt;Obviously, there is fairly limited potential in links for passing information back to the controller, so the natural extension is to want to have an 'AJAXified' form. And lo and behold, one exists. Ajax.Form works in a very similar manner to Html.Form (with the exception of needing AjaxOptions just like ActionLink does). And indeed it 'just works' much like you would expect.&lt;/P&gt;
&lt;P&gt;One final aspect of this Framework is worth discussing in this post I believe, and that is controlling what view is selected. Obviously if we have received a request as an AJAX request into the controller it is highly likely that we will want to show a different view to if we had received it as a normal HTTP request. In this case, there is a helper method that is your friend:&lt;/P&gt;
&lt;DIV style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; WIDTH: 97.5%; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BACKGROUND-COLOR: #f4f4f4"&gt;
&lt;DIV style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   1:&lt;/SPAN&gt; &lt;SPAN style="COLOR: #0000ff"&gt;if&lt;/SPAN&gt; (Request.IsMvcAjaxRequest())&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   2:&lt;/SPAN&gt; {&lt;/PRE&gt;&lt;PRE style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; WIDTH: 100%; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: white; BORDER-BOTTOM-STYLE: none"&gt;&lt;SPAN style="COLOR: #606060"&gt;   3:&lt;/SPAN&gt; }&lt;/PRE&gt;&lt;/DIV&gt;&lt;/DIV&gt;
&lt;P&gt;This does exactly what it says on the tin and will tell you from where a request originated. The most obvious use of this is, as mentioned above, in switch which view to use. The fact that a view can be an ascx file just as easily as an aspx file gives us therefore a fairly neat way of providing a page with something that will feel a lot like an UpdatePanel in the centre. Instead of the UpdatePanel, we can make the part of the page that will update an ascx file and then include it as a UserControl in our normal view page. We therefore serve the aspx page the first time (when the request is a normal HTTP request) and can then serve just the ascx file for subsequent MVC AJAX requests.&lt;/P&gt;
&lt;P&gt;I do feel at the moment that this framework offers only fairly coarse grained control compared with what is currently available through something like jQuery. The word on the street (or at least ScottGu's blog) is that they're making this a pluggable part of the process just like every other part of MVC. Certainly for ActionLinks at the moment, I think jQuery represents a better solution (lighter, more flexible and just as powerful). For Ajax.Form, I'm not sure one way or the other yet, but it does look like a relatively neat solution. You can certainly achieve the same functionality using jQuery and cause a form to POST, but it does require a certain amount of duplication of code between the jQuery code and the HTML code to set up the form.&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6430369" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/MVC/default.aspx">MVC</category><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/AJAX/default.aspx">AJAX</category></item><item><title>MVC Preview 4</title><link>http://weblogs.asp.net/melvynharbour/archive/2008/07/14/mvc-preview-4.aspx</link><pubDate>Mon, 14 Jul 2008 11:01:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6399614</guid><dc:creator>MelvynHarbour</dc:creator><slash:comments>0</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/rsscomments.aspx?PostID=6399614</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/commentapi.aspx?PostID=6399614</wfw:comment><comments>http://weblogs.asp.net/melvynharbour/archive/2008/07/14/mvc-preview-4.aspx#comments</comments><description>&lt;P mce_keep="true"&gt;It's been &lt;A class="" href="http://weblogs.asp.net/scottgu/archive/2008/07/14/asp-net-mvc-preview-4-release-part-1.aspx" mce_href="http://weblogs.asp.net/scottgu/archive/2008/07/14/asp-net-mvc-preview-4-release-part-1.aspx"&gt;announced on ScottGu's blog&lt;/A&gt; that MVC Preview 4 is due out later this week. Obviously we'll need to wait and see what it feels like when we get to have a play for real with it, but first impressions from reading down the article is that they seem to have nearly nailed down the core API to create a version that's close to what will go live, and are now busy working on all the bits and pieces that will be necessary for actually using it in a commercial sense. So we're now getting good authorisation, error handling and the like. I'll be getting it as soon as it's released and giving it a good going over to see how the new features play.&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6399614" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/MVC/default.aspx">MVC</category><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item><item><title>MVC training day 2</title><link>http://weblogs.asp.net/melvynharbour/archive/2008/07/09/mvc-training-day-2.aspx</link><pubDate>Wed, 09 Jul 2008 12:37:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6380041</guid><dc:creator>MelvynHarbour</dc:creator><slash:comments>2</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/rsscomments.aspx?PostID=6380041</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/commentapi.aspx?PostID=6380041</wfw:comment><comments>http://weblogs.asp.net/melvynharbour/archive/2008/07/09/mvc-training-day-2.aspx#comments</comments><description>&lt;P mce_keep="true"&gt;Back for more! We started the day with a quick look at Dynamic Data (no more than an overview for those that hadn't seen it before), then moved on to look at unit testing the MVC framework, before finishing off with a look at jQuery and how it works with MVC.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;Unit Testing&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;We looked at unit testing using NUnit and Moq. It was the first time I'd used Moq and it was interesting seeing just how well the approach fits with MVC. Essentially the idea was to be able to simulate the whole HTTP Context outside of a web server, using mock objects. Steven had written a helper class that mocked up the various parts of things like the request that would be needed to let a web application run successfully. This worked very neatly and allows you to push on in a rather succinct way with your testing and write very nicely structured tests that achieve good coverage of your controllers. Obviously, this does not cover unit testing of the views, but that's a slightly different problem.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;jQuery&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;I've used jQuery before on 'Classic' ASP.NET projects, but it's pretty good seeing how easily it fits in with the MVC framework. The tighter control of the HTML output you get with MVC certainly lends itself much more readily to jQuery manipulation. No more worrying about exactly what the ClientID is going to be!&lt;/P&gt;
&lt;P mce_keep="true"&gt;Steven commented that the word on the street was the Microsoft are saying that they're going to be introducing some sort of AJAX compatibility layer before MVC goes RTM, but it's not yet clear what that's going to be.&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6380041" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/MVC/default.aspx">MVC</category><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/C_2300_/default.aspx">C#</category><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/Unit+testing/default.aspx">Unit testing</category><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/jQuery/default.aspx">jQuery</category></item><item><title>MVC training day 1</title><link>http://weblogs.asp.net/melvynharbour/archive/2008/07/08/mvc-training-day-1.aspx</link><pubDate>Tue, 08 Jul 2008 13:47:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6376300</guid><dc:creator>MelvynHarbour</dc:creator><slash:comments>1</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/rsscomments.aspx?PostID=6376300</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/commentapi.aspx?PostID=6376300</wfw:comment><comments>http://weblogs.asp.net/melvynharbour/archive/2008/07/08/mvc-training-day-1.aspx#comments</comments><description>&lt;P mce_keep="true"&gt;We've had the first of our two half days with Steven Sanderson this morning. It was split in half, with the first half covering the new C# 3.0 language features and the second tackling MVC.&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;LINQ&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;We went through some fairly basic examples of LINQ to Objects just to bring everyone up to speed, covering the major language features involved (extension methods, lambdas, generic type inference, automatic properties, anonymous types and the like).&lt;/P&gt;
&lt;P mce_keep="true"&gt;&lt;STRONG&gt;MVC&lt;/STRONG&gt;&lt;/P&gt;
&lt;P mce_keep="true"&gt;Moving on to the real meat of the session now! Steven first covered some of the reasons behind MVC. This includes things like the fact that we have fairly limited control over the rendered HTML with WebForms, a false separation of concerns and that it is fundamentally hard to test. He stressed that WebForms fundamentally does quite a good job of what it was designed to do, namely help people coming from a WinForms background in migrating to writing Web Apps. However it doesn't really 'play nicely' with the way the Internet really works.&lt;/P&gt;
&lt;P mce_keep="true"&gt;We then went through a worked example, building up a sample application. Coming from a Perl/CGI background originally (before I got into ASP.NET) I felt that a lot of what I was seeing was very good and that it stands a chance of removing some of the dirty hacks that start to creep in when you want to do anything more complicated than&amp;nbsp;'My First WebForm'. It's important to recognise that it isn't for everyone however: you need to understand far more about the way the Internet and HTTP really work in order to get the most out of MVC. That said, if you &lt;EM&gt;do&lt;/EM&gt; understand, you're going to be able to push the tech a lot harder before it starts to fight back!&lt;/P&gt;
&lt;P mce_keep="true"&gt;I've watch a few presentations on MVC before, but this was the first time I've actually 'got my hands dirty' with it. I am really excited about the direction it's going. There's no doubt that you are forced to think about your web applications in a very different way when using it compared with WebForms, but I don't think that's necessarily a bad thing. It's certainly a technology that we're going to be exploring here in Red Gate's web division (although obviously you're unlikely to see anything written 'for real' in it until it goes to version 1 - probably some time in Q4 2008).&lt;/P&gt;
&lt;P mce_keep="true"&gt;Tomorrow we've got sessions looking at unit testing and how it fits into MVC, followed by using jQuery and AJAX with it.&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6376300" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/MVC/default.aspx">MVC</category><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/ASP.NET/default.aspx">ASP.NET</category><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/LINQ/default.aspx">LINQ</category><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/C_2300_/default.aspx">C#</category></item><item><title>MVC Training</title><link>http://weblogs.asp.net/melvynharbour/archive/2008/07/07/mvc-training.aspx</link><pubDate>Mon, 07 Jul 2008 10:50:00 GMT</pubDate><guid isPermaLink="false">c06e2b9d-981a-45b4-a55f-ab0d8bbfdc1c:6371305</guid><dc:creator>MelvynHarbour</dc:creator><slash:comments>3</slash:comments><wfw:commentRss xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/rsscomments.aspx?PostID=6371305</wfw:commentRss><wfw:comment xmlns:wfw="http://wellformedweb.org/CommentAPI/">http://weblogs.asp.net/melvynharbour/commentapi.aspx?PostID=6371305</wfw:comment><comments>http://weblogs.asp.net/melvynharbour/archive/2008/07/07/mvc-training.aspx#comments</comments><description>&lt;P mce_keep="true"&gt;Starting tomorrow we've got a couple of training sessions on the new ASP.NET MVC framework&amp;nbsp;lined up here at Red Gate with Steven Sanderson. Steven used to work here, but is currently busy writing one of the books that's going to be an authority on the subject. Check it out &lt;A class="" title="Pro ASP.NET MVC Framework" href="http://www.apress.com/book/view/9781430210078" target=_blank mce_href="http://www.apress.com/book/view/9781430210078"&gt;here&lt;/A&gt;!&lt;/P&gt;
&lt;P mce_keep="true"&gt;In the web team here we're all looking forward to it and hopefully I'll write up some of the more interesting aspects here! If anyone has any specific questions that you'd like me to put to him, leave&amp;nbsp;a comment below and I'll see what I can do.&lt;/P&gt;&lt;img src="http://weblogs.asp.net/aggbug.aspx?PostID=6371305" width="1" height="1"&gt;</description><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/MVC/default.aspx">MVC</category><category domain="http://weblogs.asp.net/melvynharbour/archive/tags/ASP.NET/default.aspx">ASP.NET</category></item></channel></rss>