<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="https://www.w3.org/2005/Atom" xmlns:sy="https://purl.org/rss/1.0/modules/syndication/" xmlns:dc="https://purl.org/dc/elements/1.1/" xmlns:content="https://purl.org/rss/1.0/modules/content/" xmlns:wfw="https://wellformedweb.org/CommentAPI/" xmlns:slash="https://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Marcin On ASP.NET</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/marcinon/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/marcinon/feed.xml</link>
    <description>Keeping my eye on the dot</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:23:21 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Optimizing ASP.NET MVC view lookup performance</title>
      <link>https://docs.microsoft.com/archive/blogs/marcinon/optimizing-asp-net-mvc-view-lookup-performance</link>
      <pubDate>Tue, 16 Aug 2011 19:44:00 GMT</pubDate>
      <dc:creator><![CDATA[Marcin Doboz]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/marcinon/2011/08/16/optimizing-asp-net-mvc-view-lookup-performance/</guid>
      <description><![CDATA[Earlier today Sam Saffron from the StackExchange team blogged about the performance of view lookups...]]></description>
      <content:encoded><![CDATA[<p>Earlier today Sam Saffron from the StackExchange team blogged about the <a href="https://samsaffron.com/archive/2011/08/16/Oh+view+where+are+thou+finding+views+in+ASPNET+MVC3+">performance of view lookups in MVC</a>. Specifically, he compared referencing a view by name (i.e. calling something like <code>@Html.Partial("_ProductInfo")</code>) and by path (<code>@Html.Partial("~/Views/Shared/_ProductInfo.cshtml")</code>). His results indicate that in scenarios where a page is composed from many views and partial views (for example, when you are rendering a partial view for each item in a list) it&rsquo;s more efficient to reference your views using the full path instead of just the view name.</p>
<p>I know that bit of code quite well and it seemed strange to me that such a performance difference would exist because view lookups are cached regardless of how you reference them. Specifically, once an application is warmed up both the Razor and WebForms view engines use the lookup parameters to retrieve the cached results. If anything the cache key produced from a view path is usually longer than the one produced from a view name but even that should not have a measurable impact.</p>
<p>While I cannot explain the differences that Sam is seeing (and since I <a href="https://twitter.com/#!/samsaffron/status/103640715019567104">know</a> he is seeing them in production too I&rsquo;m quite sure he has the application configured correctly for performance testing) I thought this would be a good opportunity to present the basics of MVC view lookup optimizations as well as a few additional techniques that people might not be familiar with.</p>
<p>Hopefully you won&rsquo;t go replacing all of your view references with full paths. Using view names is still easier and more maintainable. And before you do any perf-related changes you should always measure your application. It might turn out that it is fast enough for your needs already.</p>
<h1></h1>
<h1>Run in Release mode</h1>
<p>You should always make sure that your application is compiled in Release mode and that your web.config file is configured with <code>&lt;compilation debug="false" /&gt;</code>. That second part is super-important since MVC will not do any view lookup caching if you are running your application in debug mode. This helps when you are developing your application and frequently adding/deleting view files, but it will kill your performance in production.</p>
<p>This might seem like obvious advice, but I have seen even experienced devs get bitten by this.</p>
<h1>Use only the View Engines that you need</h1>
<p>I&rsquo;ve mentioned this <a href="https://blogs.msdn.com/b/marcinon/archive/2011/02/07/mvc-performance-tips.aspx">before</a> but it&rsquo;s worth repeating. The MVC framework supports having multiple view engines configured simultaneously in your application and will query each in turn when it is trying to find a view. The more you have the longer the lookups will take, especially if the view engine you are using is registered last. In MVC 3 we register two view engines by default (WebForms and Razor) and in all versions you might have installed 3rd party view engine such as Spark on nHaml. There is no reason to pay the performance price for something you are not using so make sure you specify only the view engines you need in your Global.asax file:</p>
<pre class="brush: csharp;">protected void Application_Start() {
    ViewEngines.Engines.Clear();
    ViewEngines.Engines.Add(new RazorViewEngine());
    ...
}</pre>
<h1>Customize the view lookup caching</h1>
<p>By default (when running in Release mode, of course) MVC will cache the results of the lookups in the application cache available via <code>HttpContext.Cache</code>. While this cache works great and helps us avoid having to check for view files on disk there is also a cost associated with using it (this includes the cost of a thread-safe lookup as well as all the additional cache management such as updating entry expiration policies and performance counters).</p>
<p>To speed things up you could introduce a faster cache in front of the application cache. Fortunately all view engines deriving from <code>VirtualPathProviderViewEngine</code> (that includes WebForms and Razor) have an extensibility point via the settable <a href="https://msdn.microsoft.com/en-us/library/system.web.mvc.virtualpathproviderviewengine.viewlocationcache(v=VS.98).aspx"><code>ViewLocationCache</code></a> property.</p>
<p>So we can create a new class that implements the <a href="https://msdn.microsoft.com/en-us/library/system.web.mvc.iviewlocationcache(v=VS.98).aspx"><code>IViewLocationCache</code></a> interface:</p>
<pre class="brush: csharp;">public class TwoLevelViewCache : IViewLocationCache {
    private readonly static object s_key = new object();
    private readonly IViewLocationCache _cache;

    public TwoLevelViewCache(IViewLocationCache cache) {
        _cache = cache;
    }

    private static IDictionary&lt;string, string&gt; GetRequestCache(HttpContextBase httpContext) {
        var d = httpContext.Items[s_key] as IDictionary&lt;string, string&gt;;
        if (d == null) {
            d = new Dictionary&lt;string, string&gt;();
            httpContext.Items[s_key] = d;
        }
        return d;
    }

    public string GetViewLocation(HttpContextBase httpContext, string key) {
        var d = GetRequestCache(httpContext);
        string location;
        if (!d.TryGetValue(key, out location)) {
            location = _cache.GetViewLocation(httpContext, key);
            d[key] = location;
        }
        return location;
    }

    public void InsertViewLocation(HttpContextBase httpContext, string key, string virtualPath) {
        _cache.InsertViewLocation(httpContext, key, virtualPath);
    }
}</pre>
<p>and augment our view engine registration in the following way:</p>
<pre class="brush: csharp;">protected void Application_Start() {
    ViewEngines.Engines.Clear();
    var ve = new RazorViewEngine();
    ve.ViewLocationCache = new TwoLevelViewCache(ve.ViewLocationCache);
    ViewEngines.Engines.Add(ve);
    ... 
}</pre>
<p>This TwoLevelViewCache will work best in views that call the same partial multiple times in a single request (and should hopefully have minimum impact on simpler pages).</p>
<p>You could go even further and instead of the simple dictionary stored in httpContext.Items you could use a static instance of ConcurrentDictionary&lt;string, string&gt;. Just remember that if you do that your application might behave incorrectly if you remove or add view files without restarting the app domain.</p>]]></content:encoded>
    </item>
    <item>
      <title>Project Templates and preinstalled NuGet packages</title>
      <link>https://docs.microsoft.com/archive/blogs/marcinon/project-templates-and-preinstalled-nuget-packages</link>
      <pubDate>Fri, 08 Jul 2011 10:00:00 GMT</pubDate>
      <dc:creator><![CDATA[Marcin Doboz]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/marcinon/2011/07/08/project-templates-and-preinstalled-nuget-packages/</guid>
      <description><![CDATA[10/22 Update: This post was written before this feature became a part of NuGet.This feature is now...]]></description>
      <content:encoded><![CDATA[<div class="note">
<p><strong>10/22 Update:</strong> This post was written before this feature became a part of NuGet.<br />This feature is now a part of NuGet and the latest version of this information can be found on the <a title="NuGet docs site" href="https://docs.nuget.org/docs/reference/packages-in-visual-studio-templates">NuGet docs site</a>.<br />There is also a <a title="Sample project repository" href="https://bitbucket.org/marcind/nugetinvstemplates">sample project</a> available.</p>
<p></p>
</div>
<p>Over the last few years the ASP.NET team has been including more and more libraries into the various project templates that we ship with Visual Studio and other products. The latest MVC 3 templates come with jQuery, jQuery UI, jQuery Validation, Modernizr, and Entity Framework. All this built-in functionality is great but one remaining snag is that upgrading all the packages by hand can be a pain. Of course the NuGet package manager is an excellent tool that solves the package upgrade problem but so far having project templates with preinstalled NuGet packages was not possible.</p>
<p>This post describes a new feature that will be shipping in NuGet 1.5: preinstalled NuGet packages. Since it is not documented anywhere at this time the purpose of this post is to describe how to create a VS project template with NuGet packages. If you play around with it please also provide feedback so we can make changes/improvements.</p>
<p>Authoring VS project templates is out of scope of this article but you can read more on how to create a project template&nbsp;<a title="Creating Project Templates" href="https://msdn.microsoft.com/en-us/library/ms247120.aspx">directly using&nbsp;Visual Studio</a> or <a title="Templates for Creating Templates" href="https://msdn.microsoft.com/en-us/library/ff527340.aspx">using the Visual Studio SDK</a>.</p>
<h1>Adding packages to a project templates</h1>
<p>NuGet 1.5 is not out yet but the feature has already been <a href="https://nuget.codeplex.com/SourceControl/changeset/changes/ed914b033a8f">checked in</a> and you can try it out by grabbing a <a title="NuGet CI Server Last Successful build" href="https://ci.nuget.org:8080/viewLog.html?buildTypeId=bt4&amp;buildId=lastSuccessful">recent NuGet preview build</a> and installing the Visual Studio add-in (note that you might have to remove the previous version via the Extension Manager first).</p>
<p>Preinstalled packages work using <a title="How to: Use Wizards with Project Templates" href="https://msdn.microsoft.com/en-us/library/ms185301.aspx">project template wizards</a>. A special wizard gets invoked when the project gets instantiated. The wizard loads the list of packages that need to be installed and passes that information to the appropriate NuGet APIs. The project template needs to specify where to find the package nupkg files. Currently two package repositories are supported:</p>
<ol>
<li>Packages embedded inside of a VSIX package.</li>
<li>Packages embedded inside of the project template itself.</li>
</ol>
<p>A frequent question is why not support downloading the nupkg files directly from <a href="https://nuget.org">https://nuget.org</a>. We decided not to support such an option because users expect project templates to instantiate quickly and downloading files from the internet would slow things down. Also, it would not work on a plane or in other situations where a connection is not available.</p>
<p>To add preinstalled packages to your project template you need to:</p>
<ol>
<li>Edit your vstemplate file and add a reference to the NuGet template wizard by adding a <a href="https://msdn.microsoft.com/en-us/library/ms171411.aspx"><code>WizardExtension</code></a>&nbsp;element:
<pre class="brush: xml;">&lt;WizardExtension&gt;
    &lt;Assembly&gt;NuGet.VisualStudio.Interop, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null&lt;/Assembly&gt;
    &lt;FullClassName&gt;NuGet.VisualStudio.TemplateWizard&lt;/FullClassName&gt;
&lt;/WizardExtension&gt;</pre>
NuGet.VisualStudio.Interop.dll is a new assembly that only contains the TemplateWizard class. This class is a simple wrapper that calls into the actual implementation that lives in NuGet.VisualStudio.dll. The assembly version will never change so that project templates continue to work with new versions of NuGet.</li>
<li>Add the list of packages to install in the project:
<pre class="brush: xml;">&lt;WizardData&gt;
    &lt;packages&gt;
        &lt;package id="jQuery" version="1.4.4" /&gt;
    &lt;/packages&gt;
&lt;/WizardData&gt;</pre>
You can of course add multiple <code>&lt;package&gt;</code> elements. Both the <code>id</code> and <code>version</code> attributes are required. You will notice that this means that a specific version of a package will be installed, even if a newer version is available in the online package feed. We cannot just update to the latest version because a future version of a package might introduce incompatibilities that would break an older version of the project template. It is up to the developer to upgrade using the package manager.</li>
</ol>
<p>The remaining step is to specify the repository where NuGet can find the package files. As mentioned earlier, two package repository modes are supported:</p>
<h2>VSIX package repository</h2>
<p>The approach I recommend for deploying Visual Studio project templates is through a VSIX package (read more about <a title="VSIX Deployment" href="https://msdn.microsoft.com/en-us/library/ff363239.aspx">VSIX deployment here</a>). The VSIX method is preferable because it allows you to package multiple project templates together and allows developers to easily discover your templates using the VS Extension Manager or the <a title="Visual Studio Gallery - Templates" href="https://visualstudiogallery.msdn.microsoft.com/site/search?f%5B0%5D.Type=RootCategory&amp;f%5B0%5D.Value=templates&amp;f%5B0%5D.Text=Templates">Visual Studio Gallery</a>. On top of that you can easily push updates to your users using the <a title="How to: Update a Visual Studio Extension" href="https://msdn.microsoft.com/en-us/library/dd997169.aspx">Extension Manager automatic update mechanism</a>.</p>
<ol>
<li start="3">To specify a VSIX as a package repository you modify the <code>&lt;package&gt;</code>element:
<pre class="brush: xml;">&lt;packages repository="extension"
          repositoryId="MyTemplateExtension.46431780-a0c7-44e0-83c7-5dbd985f8e49"&gt;
    ...
&lt;/packages&gt;</pre>
</li>
</ol>
<p>The <code>repository</code> attribute specifies the type of repository (&ldquo;extension&rdquo;) while <code>repositoryId</code> is the unique identifier of your VSIX (i.e. the value of the <a href="https://msdn.microsoft.com/en-us/library/dd393688.aspx"><code>ID</code> attribute</a> in the extension&rsquo;s vsixmanifest file).</p>
<p>You need to add your nupkg files as <a href="https://msdn.microsoft.com/en-us/library/dd393737.aspx">custom extension content</a> and ensure that they are located under a folder called Packages within the VSIX package. You can place the nupkg files in the same VSIX as your project templates or you can have the packages be located in a separate VSIX if that makes more sense for your scenario (just note that you should not reference VSIXs you do not have control over since they could change in the future and your project templates would break).</p>
<h2></h2>
<h2>Template package repository</h2>
<p>If packaging multiple projects is not important to you (e.g. you&rsquo;re only distributing a single project template), a simpler but also more limited approach is to include the nupgk files in the project template zip file itself.</p>
<p>However, if you are bundling a set of project templates that relate to each other and share NuGet packages (e.g. you are shipping a custom MVC project template with versions for Razor, Web Forms, C#, and VB.NET), we do not recommend adding the NuGet packages directly to each project template zip file. It needlessly increases the size of the project template bundle.</p>
<ol>
<li>To specify the project template as a package repository you modify the <code>&lt;package&gt;</code>element:
<pre class="brush: xml;">&lt;packages repository="template"&gt;
    ...
&lt;/packages&gt;</pre>
</li>
</ol>
<p>The <code>repository</code> attribute now has the value &ldquo;template&rdquo; and the <code>repositoryId</code> attribute is not longer required. The nupkg files need to be placed into the root directory of the project template.</p>]]></content:encoded>
    </item>
    <item>
      <title>ASP.NET MVC Performance Tips</title>
      <link>https://docs.microsoft.com/archive/blogs/marcinon/asp-net-mvc-performance-tips</link>
      <pubDate>Mon, 07 Feb 2011 21:22:00 GMT</pubDate>
      <dc:creator><![CDATA[Marcin Doboz]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/marcinon/2011/02/07/asp-net-mvc-performance-tips/</guid>
      <description><![CDATA[Database access is usually the largest performance bottleneck of web applications. But once...]]></description>
      <content:encoded><![CDATA[<p>Database access is usually the largest performance bottleneck of web applications. But once you&rsquo;ve optimized and cached your database queries as much as possible here are 3 quick tips that might help you squeeze out a few more requests out of your ASP.NET MVC applications and web servers.</p>
<p>Depending on which features you are using they might not always apply to your application and their benefit will not be that significant (a few&nbsp;% points improvement at most - sorry I don't have more specific numbers as I'm writing this from memory). I can't guarantee how much improvement you will see as it depends so much on what your application does.&nbsp;But&nbsp;I hope this will provide some leads&nbsp;for you to investigate.&nbsp;Just remember to always measure for your specific scenario.</p>
<h1>Disable unused view engines</h1>
<p><strong>When</strong>: Your application is using <a href="https://bradwilson.typepad.com/blog/2009/10/aspnet-mvc-2-templates-part-3-default-templates.html">built-in display/editor templates</a> (via the <code>Html.EditorFor</code> or <code>Html.DisplayFor</code> methods) and you are using only one type of view engine.</p>
<p><strong>Why</strong>: ASP.NET MVC is generally very good about caching file lookup hits (views, partials, display/editor templates). However one scenario that is not cached is the use of the built-in (default) display/editor templates (where all file lookups are misses).</p>
<p>Any time you use the <code>Html.EditorFor</code> or <code>Html.DisplayFor</code> methods and you do not have a matching template file MVC will generate the appropriate markup for you based on the model&rsquo;s metadata. However, before that happens it checks all the view engines to find a template file. The more view engines you have registered the longer this will take and since the miss is not cached the process will have to be repeated the next time a page is requested. If you are using only one view engine in your project you should remove the other ones in Global.asax. The easies way to do that is with the following code:</p>
<pre class="brush: csharp;">ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new RazorViewEngine());</pre>
<h1>Avoid passing null models to views</h1>
<p><strong>When</strong>: You pass in a null model to a view that uses strongly-typed html helpers (such as <code>Html.TextBoxFor</code>). This frequently happens in Insert scenarios.</p>
<p><strong>Why</strong>: Strongly-typed html helpers such as <code>Html.TextBoxFor(m =&gt; m.Name)</code> will try to emit the value of the model using the provided expression. However when something along the expression chain is null a NullReferenceException will be thrown when the expression gets evaluated. MVC&rsquo;s expression evaluator catches the exception but on a page with multiple such html helpers the cost of the exception adds up. You can avoid that cost by always passing an instance of the model to the view: </p>
<pre class="brush: csharp;">public ActionResult Insert() {
    // return View(); // here the model instance defaults to null
    return View(new Product());
}</pre>
<h1>Uninstall URL Rewrite if you don&rsquo;t use it</h1>
<p><strong>When</strong>: Your IIS server has the <a href="https://www.iis.net/download/URLRewrite">URL Rewrite module</a> installed but none of the applications on the server are using it and you are running ASP.NET MVC 3.</p>
<p><strong>Why</strong>: When performing URL generation (for example via a method like <code>Html.ActionLink</code>) in some cases MVC checks to see if the currently requested URL has been rewritten by the URL Rewrite module. If that is the case the result is processed so that it correctly matches the URL requested by the client.</p>
<p>The act of checking if a URL has been rewritten has a non-trivial cost (because it involves checking server variables). ASP.NET MVC 3 checks to see if URL Rewrite is turned off and can cache that fact thus avoiding the need to inspect server variables for each request. If URL Rewrite is turned on MVC will have to check server variables even if no rewriting happened for a particular request so if you are not using URL Rewrite you should turn it off (Note that MVC 2 always performs this check so turning URL Rewrite off will not make a difference).</p>]]></content:encoded>
    </item>
    <item>
      <title>ASP.NET MVC 3 Performance – on par with MVC 2</title>
      <link>https://docs.microsoft.com/archive/blogs/marcinon/asp-net-mvc-3-performance-on-par-with-mvc-2</link>
      <pubDate>Mon, 17 Jan 2011 10:40:00 GMT</pubDate>
      <dc:creator><![CDATA[Marcin Doboz]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/marcinon/2011/01/17/asp-net-mvc-3-performance-on-par-with-mvc-2/</guid>
      <description><![CDATA[Now that the final version of MVC 3 has been released I think information about the performance...]]></description>
      <content:encoded><![CDATA[<p>Now that the final version of MVC 3 has been released I think information about the performance characteristics of this latest installment would be very useful for those weighing the pros and cons of updating their MVC 2 applications. In this post I will talk about what you might expect when moving to MVC 3. The short answer is things should be about the same.</p>
<p>Of course that short statement is not accurate because the only correct answer to such performance questions is: &ldquo;it depends&rdquo;. It depends on what your application does and which features it is using: database connections, business logic, output caching, html helpers, etc. I say this because in a moment I will present some numbers and they might not correspond to what you would see in your application. But they should provide you with a good starting point.</p>
<p>The more detailed answer is that some applications will perform better while others will perform worse. That is because as we added new features (dependency injection, improved filters, etc.) some components of MVC 3 got slower than in MVC 2 simply because they are now doing more work. At the same time we have introduced targeted performance optimizations which improved other components. The only definite way you can know the impact on your application is if you carefully measure performance yourself. At the end of this post I will provide a rough list of some of the things that have gotten faster or slower.</p>
<h1>The Setup</h1>
<p>The application I will use for the tests is the default &ldquo;Internet Application&rdquo; project template that ships with every installation of MVC. While quite small, it is still a pretty good choice because it uses a wide variety of MVC features. This means that the test exercises a large part of the framework without focusing on any individual features.</p>
<p>For my tests I have the following applications:</p>
<ol>
<li>MVC 2 Aspx Internet Application project running against MVC 2 runtime </li>
<li>MVC 2 Aspx Internet Application project running against MVC 3 runtime </li>
<li>MVC 3 Aspx Internet Application project running against MVC 3 runtime </li>
<li>MVC 3 Razor Internet Application project running against MVC 3 runtime </li>
</ol>
<p>I modified each of these applications in the following ways to ensure consistency and remove unnecessary noise from the results:</p>
<ul>
<li>Set debug=&rdquo;false&rdquo; in the root Web.config file. </li>
<li>Changed application to build in Release mode. </li>
<li>Changed the FormsAuthenticationService and MembershipService classes to return hardcoded values (I do not want to test database connection latency). </li>
</ul>
<p>For each of the applications I executed the following sequence of requests and recorded the throughput (number of requests per second). The sequence ran for about 1 hour in our performance testing lab (meaning that the results should be amortized with respect to any other OS tasks that might have occurred on the server).</p>
<ol>
<li>GET /Home/Index (arrive at site) </li>
<li>GET /Account/LogOn (click on &ldquo;log on&rdquo; link) </li>
<li>POST /Account/LogOn (attempt to log on with invalid credentials) </li>
<li>GET /Account/Register (click on &ldquo;register&rdquo; link) </li>
<li>POST /Account/Register (submit the registration form) </li>
</ol>
<h1>The Results</h1>
<table cellpadding="2" cellspacing="0" border="1" style="width: 526px;">
<thead>
<tr>
<th align="center" width="139" valign="top">Application</th><th align="center" width="160" valign="top">Requests/second (higher is better)</th><th align="center" width="225" valign="top">% change (wrt&nbsp;baseline)</th>
</tr>
</thead>
<tbody>
<tr>
<td align="center" width="140" valign="top">1. MVC 2 Aspx on v2</td>
<td align="center" width="161" valign="top">8135 (baseline)</td>
<td align="center" width="224" valign="top">n/a</td>
</tr>
<tr>
<td align="center" width="140" valign="top">2. MVC 2 Aspx on v3</td>
<td align="center" width="162" valign="top">7987</td>
<td align="center" width="223" valign="top">-1.82%</td>
</tr>
<tr>
<td align="center" width="140" valign="top">3. MVC 3 Aspx on v3</td>
<td align="center" width="163" valign="top">7457</td>
<td align="center" width="223" valign="top">-8.33%</td>
</tr>
<tr>
<td align="center" width="140" valign="top">4. MVC 3 Razor on v3</td>
<td align="center" width="164" valign="top">7136</td>
<td align="center" width="222" valign="top">-12.28%</td>
</tr>
</tbody>
</table>
<p>Note: The above results were captured on a 12-core server and should only be used for comparative purposes.&nbsp;Absolute RPS values on your own machine&nbsp;might&nbsp;de&nbsp;vastly different but their relative distribution should remain the same.&nbsp;</p>
<h3>Applications 1 vs. 2</h3>
<p>As you can see from comparing the results for Application 1 and Application 2 the difference is quite small. In fact &ndash;1.82% falls within the margin of error. Application 1 and Application 2 are the same identical application, except 1. references System.Web.Mvc.dll version 2.0 and 2. references System.Web.Mvc.dll version 3.0. <span style="text-decoration: underline;">These results are why we say that MVC 3 is on par with the performance characteristics of MVC 2</span>.</p>
<p>Of course followers of Scott Guthrie will point out that with the RC2 release he <a href="https://weblogs.asp.net/scottgu/archive/2010/12/10/announcing-asp-net-mvc-3-release-candidate-2.aspx">claimed that MVC 3 was faster than MVC 2</a>. While that was true at the time it is not correct any longer for RTM. We had to undo a pretty significant performance fix related to model metadata caching because it caused some <a href="https://weblogs.asp.net/scottgu/archive/2010/12/14/update-on-asp-net-mvc-3-rc2-and-a-workaround-for-a-bug-in-it.aspx">functional bugs</a> (after all it does not matter how fast your application is if it does not actually work correctly). However, we will have that improvement available as an add-on in MVC Futures and we will roll it into MVC 4.</p>
<h3>Applications 2 vs. 3</h3>
<p>Comparing Application 2 with Application 3 shows that 3. is &ndash;6.64% slower. However, in this case the runtimes are the same. The difference is in the project templates used. The project template that ships with MVC 3 has more functionality enabled by default. Most notably it has <a href="https://bradwilson.typepad.com/blog/2010/10/mvc3-unobtrusive-validation.html">unobtrusive client-side validation</a> enabled; MVC 2 project templates did not have client-side validation enabled. The extra time is taken up inspecting the model metadata and emitting additional markup and javascript code. Of course while page rendering will be slower, the overall result of enabling client-side validation should be reduced load on the server as the majority of invalid inputs will be caught on the client thus avoiding the need for unnecessary roundtrips.</p>
<h3>Applications 3 vs. 4</h3>
<p>The comparison of Application 3 and Application 4 will be of interest to those looking at adopting the new Razor view engine. Application 4 is &ndash;4.3% slower than Application 3. This shows that using Razor does have a performance cost. However, that difference is not that big and is outweighed by the elegance and increased readability of the new view engine. Razor is also a new technology and I am sure that as it matures we will be able to optimize it even further.</p>
<h1>The Changes</h1>
<p>At the beginning of this post I promised that I would list how the various features or components of MVC changed in their performance characteristics. This list is compiled from our internal performance tests as well as change logs. It is meant to be taken as informational only. Your results may vary and depends on how you actually use each feature and what else you have happening in your application</p>
<p>Things that got faster (in no particular order):</p>
<ul>
<li>Expression caching (internal subsystem that helps in the performance of methods that accept lambdas)</li>
<li>URL generation</li>
<li>Action lookup</li>
<li>Filter invocation</li>
<li>TagBuilder</li>
</ul>
<p>Things that got slower (also in no particular order):</p>
<ul>
<li>Things for which Dependency Injection entry points have been exposed</li>
<li>Auto-generated editor and display helpers</li>
<li>Model binding</li>
</ul>
<p>Of course I am not going to tell you by how much things have changed because it depends... you will have to measure yourself.</p>]]></content:encoded>
    </item>
    <item>
      <title>MVC 3 Project Upgrade Tool</title>
      <link>https://docs.microsoft.com/archive/blogs/marcinon/mvc-3-project-upgrade-tool</link>
      <pubDate>Thu, 13 Jan 2011 08:18:00 GMT</pubDate>
      <dc:creator><![CDATA[Marcin Doboz]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/marcinon/2011/01/13/mvc-3-project-upgrade-tool/</guid>
      <description><![CDATA[We have just released the final version of ASP.NET MVC 3. Read the official MVC 3&nbsp;release...]]></description>
      <content:encoded><![CDATA[<p>We have just released the final version of ASP.NET MVC 3. Read the <a href="https://www.asp.net/mvc/mvc3">official MVC 3&nbsp;release information</a> or <a href="https://www.microsoft.com/downloads/en/details.aspx?FamilyID=d2928bc1-f48c-4e95-a064-2a455a22c8f6&amp;displaylang=en">download MVC 3</a>.</p>
<p>To help you upgrade your MVC 2 projects to MVC 3 we have released an upgrade tool. You can download it here: <a href="https://aspnet.codeplex.com/releases/view/59008" title="https://aspnet.codeplex.com/releases/view/59008">https://aspnet.codeplex.com/releases/view/59008</a>. (This is an update of the tool that Eilon Lipton previously <a href="https://weblogs.asp.net/leftslipper/archive/2010/07/28/migrating-asp-net-mvc-2-applications-to-asp-net-mvc-3-preview-1.aspx">previewed on his blog</a> and now we are giving it a more permanent home on our CodePlex site).</p>
<p><strong>April 11 Update</strong>: We made a small update to the tool that allows you to skip the backup step. You might want to consider skipping the backup step if you use source control or if your solution is very big.</p>
<p><strong>January 14 Update</strong>: We have updated the file on codeplex to fix an issue with converting solutions that had Web Sites or other solution items. If you are having problems please make sure you download the tool again from the codeplex site.</p>
<p>The upgrade tool only supports Visual Studio 2010 projects targeting .NET 4. Upgrading both MVC 2 and MVC 3 Beta (or RC) projects is supported.</p>
<p>The tool does not support Visual Studio 2008 solutions, MVC 1 projects, or projects targeting .NET 3.5. Those projects will first have to be upgraded using Visual Studio 2010 and/or retargeted for .NET 4:</p>
<ul>
<li>If you have a Visual Studio 2008 solution you can simply open it with Visual Studio 2010 to initiate the solution upgrade process.</li>
<li>If your projects are targetting .NET 3.5 read <a href="https://msdn.microsoft.com/en-us/library/bb398202.aspx" title="Change Visual Studio project target framework">how to target .NET 4</a>.</li>
<li>If you have a MVC 1.0 project you can use <a href="https://weblogs.asp.net/leftslipper/archive/2010/03/10/migrating-asp-net-mvc-1-0-applications-to-asp-net-mvc-2-rtm.aspx" title="Old version of upgrade tool for MVC 2">the old version of this tool</a> to convert it to MVC 2.</li>
</ul>
<p><img height="500" width="634" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/95/24/metablogapi/1641.MvcConverterScreenshot_74A4FCE4.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-95-24-metablogapi/1641.MvcConverterScreenshot_5F00_74A4FCE4.png" alt="MVC upgrade tool screenshot" border="0" title="MVCConverterScreenshot" style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" /></p>
<p>The usage of the tool is quite simple:</p>
<ol>
<li>If you use a source control system make sure your files are checked out and writable</li>
<li>Run the executable </li>
<li>Select your Visual Studio 2010 solution file that contains your project </li>
<li>Review the changes for each item in the Item details pane </li>
<li>Click on the Convert button to initiate the conversion process </li>
<li>Review the results in the Conversion log pane </li>
</ol>
<p><br />During the conversion process the tool will:</p>
<ol>
<li>Create a backup of the entire solution. </li>
<li>Update all class library projects (including Test projects) that reference System.Web.Mvc.dll to reference version 3.0. </li>
<li>Update all Web Application projects that reference System.Web.Mvc to reference version 3.0 and add references to System.Web.Helpers.dll and System.Web.WebPages.dll.</li>
<li>Change all MVC 2&nbsp;Web Application projects to be MVC 3 projects (this affects&nbsp;which version of the 'Add View' dialog you get etc)&nbsp;</li>
<li>Update all MVC Web Application root Web.config files: <ol>
<li>Update references to System.Web.Mvc version 3.0. </li>
<li>Add an assembly binding redirect entry for System.Web.Mvc. </li>
<li>Add assembly and namespace references to System.Web.Helpers and System.Web.WebPages. </li>
<li>Add the &ldquo;ClientValidationEnabled&rdquo; and &ldquo;UnobtrusiveJavaScriptEnabled&rdquo; settings to the &lt;appSettings&gt; element with value &ldquo;false&rdquo; if they were not already present (these settings can be used to control the <a href="https://bradwilson.typepad.com/blog/2010/10/mvc3-unobtrusive-validation.html">unobtrusive client validation</a> and <a href="https://bradwilson.typepad.com/blog/2010/10/mvc3-unobtrusive-ajax.html">unobtrusive Ajax</a> features). </li>
</ol></li>
<li>Update all MVC Web Application views Web.config files (~\Views\Web.config as well as the views Web.config files for all Areas): <ol>
<li>Update references to System.Web.Mvc version 3.0 </li>
<li>Add a &lt;configSections&gt; entry required for Razor configuration in MVC </li>
<li>Add the &lt;system.web.webPages.razor&gt; entry required for Razor support in MVC </li>
<li>Add the &ldquo;webPages:enabled&rdquo; setting to the &lt;appSettings&gt; element with value &ldquo;false&rdquo; (required to prevent .cshtml or .vbhtml files in the Views folder from being directly accessible from a web browser) </li>
</ol></li>
<li>Add the following JavaScript libraries to the MVC Web Applications (only if they did not already exist): 
<ul>
<li>jQuery 1.4.4 (jquery-1.4.4.js, jquery-1.4.4-vsdoc.js, jquery-1.4.4.min.js) </li>
<li>jQuery UI 1.8.7 (jquery-ui.js, jquery-ui.min.js) </li>
<li>jQuery Validation 1.7 (jquery-validate.js, jquery-validate-vsdoc.js, jquery-validate.min.js) </li>
<li>Microsoft Ajax (MicrosoftAjax.js, Microsoft.Ajax.debug.js) </li>
</ul>
</li>
<li>Overwrite MVC-specific JavaScript files in MVC Web Applications: 
<ul>
<li>MicrosoftMvcAjax.js, MicrosoftMvcAjax.debug.js, MicrosoftMvcValidation.js, MicrosoftMvcValidation.debug.js, jquery.unobtrusive-ajax.js, jquery.unobtrusive-ajax.min.js, jquery.validate.unobtrusive.js, jquery.validate.unobtrusive.min.js</li>
</ul>
</li>
<li>Add jQuery UI theme files (stylesheet and images)</li>
</ol>
<p><br />This is an unsupported utility and there is a possibility that it might not work correctly for your solution. Specifically, the tool has the following limitations:</p>
<ul>
<li>Read-only project files are not supported (make sure you check out your solution if you use source control)</li>
<li>Very long file paths might cause problems</li>
<li>Solutions with project files outside of the solution folder might cause problems</li>
<li>The tool will not upgrade your application code to account for any potential runtime breaking changes</li>
<li>Non-standard project files (e.g. missing MVC project type GUID) will not be handled correctly</li>
<li>Once again, VS 2008 solutions, MVC 1 or .NET 3.5 projects are not supported</li>
<li>The tool will also not modify any Web Sites in your solution</li>
</ul>
<p><br />However, if you run into problems let me know and I will see if we can get them addressed.</p>]]></content:encoded>
    </item>
    <item>
      <title>Razor, Nested Layouts and Redefined Sections</title>
      <link>https://docs.microsoft.com/archive/blogs/marcinon/razor-nested-layouts-and-redefined-sections</link>
      <pubDate>Wed, 15 Dec 2010 00:10:00 GMT</pubDate>
      <dc:creator><![CDATA[Marcin Doboz]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/marcinon/2010/12/15/razor-nested-layouts-and-redefined-sections/</guid>
      <description><![CDATA[In a recent post I introduced a technique for dealing with optional Razor sections and default...]]></description>
      <content:encoded><![CDATA[<p>In a recent post I introduced a technique for <a href="https://blogs.msdn.com/b/marcinon/archive/2010/12/08/Optional-Razor-Sections-with-Default-Content.aspx" title="Optional Razor Sections with Default Content">dealing with optional Razor sections and default content</a>. In this post I will expand upon that technique and describe a way of working with sections across nested layout hierarchies. If you are not familiar with sections, layout pages, or my technique then go ahead and read that post to catch up.</p>
<p>One aspect of the relationship between layout pages and sections in Razor that a fair number of people might find surprising is that a section defined in a content page can only be used in its immediate layout. There is implicit scoping going on that prevents certain use cases. Take the following example:</p>
<pre title="~/Views/_MasterLayout.cshtml" class="brush: xml;">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;body&gt;
@RenderSection("SubSection")
@RenderBody()
&lt;/body&gt;
&lt;/html&gt;</pre>
<pre title="~/Views/_SubLayout.cshtml" class="brush: xml;">@{
    Layout = "~/Views/_MasterLayout.cshtml";
}
&lt;div&gt;
@section SubSection {
&lt;h1&gt;Title&lt;/h1&gt;
}
@RenderBody()
@RenderSection("ContentSection")
&lt;/div&gt;</pre>
<pre title="~/Views/Content.cshtml" class="brush: xml;">@{
    Layout = "~/Views/_SubLayout.cshtml";
}
&lt;div&gt;
&lt;p&gt;Main content&lt;/p&gt;
@section ContentSection {
&lt;div&gt;Footer&lt;/div&gt;
}
&lt;/div&gt;</pre>
<p>In the above example you can certainly call <code>RenderSection("SubSection")</code> in _MasterLayout.cshtml, as well as call <code>RenderSection("ContentSection")</code> in _SubLayout.cshtml. However, it is impossible to call <code>RenderSection("ContentSection")</code> from _MasterLayout.cshtml because the file rendering the section and the file defining the section are not directly related. Essentially sections are limited to the Content-Layout scope and are not accessible to other layout pages outside of that scope.</p>
<h1>Redefining sections</h1>
<p>You can work around this by essentially redefining the section in the intermediate layout.&nbsp; </p>
<pre class="brush: xml;">@{
    Layout = "~/Views/_MasterLayout.cshtml";
}
&lt;div&gt;
@section SubSection {
&lt;h1&gt;Title&lt;/h1&gt;
}
@RenderBody()
@section ContentSection {
  @RenderSection("ContentSection", required: false)
}
&lt;/div&gt;</pre>
<p>Now you are able to reference &ldquo;ContentSection&rdquo; from _MasterLayout.cshtml. However you should be aware that you are not overriding &ldquo;ContentSection" in the same sense as overriding methods in a child class. You are actually defining a new section named &ldquo;ContentSection&rdquo; in the SubLayout-MasterLayout scope that renders the section named &ldquo;ContentSection&rdquo; from the Content-SubLayout scope. The fact that the names match is incidental. The names certainly do not have to match.</p>
<p>Things get even more complicated when you want to use the <code><a href="https://blogs.msdn.com/b/marcinon/archive/2010/12/08/optional-razor-sections-with-default-content.aspx#RazorSectionDefaultContent_IsSectionDefined">IsSectionDefined</a></code> method to conditionally provide default content for optional sections. Because it&rsquo;s necessary to propagate &ldquo;ContentSection&rdquo; by redefining the section in _SubLayout.cshtml you can no longer depend on IsSectionDefined returning the expected result.</p>
<h1>Conditionally redefining sections via RedefineSection</h1>
<p>Fortunately not everything is lost. What you want to do is to conditionally redefine a section. Building on the <a href="https://blogs.msdn.com/b/marcinon/archive/2010/12/08/optional-razor-sections-with-default-content.aspx#RazorSectionDefaultContent_InlineTemplate">RenderSection helper method from my previous post</a> I created the <code>RedefineSection</code> more helper methods to aid in this scenario:</p>
<pre class="brush: csharp;">public static class SectionExtensions {
    private static readonly object _o = new object();
    public static HelperResult RenderSection(this WebPageBase page,
                            string sectionName,
                            Func&lt;object, HelperResult&gt; defaultContent) {
        if (page.IsSectionDefined(sectionName)) {
            return page.RenderSection(sectionName);
        }
        else {
            return defaultContent(_o);
        }
    }

    public static HelperResult RedefineSection(this WebPageBase page,
                            string sectionName) {
        return RedefineSection(page, sectionName, defaultContent: null);
    }

    public static HelperResult RedefineSection(this WebPageBase page,
                            string sectionName,
                            Func&lt;object, HelperResult&gt; defaultContent) {
        if (page.IsSectionDefined(sectionName)) {
            page.DefineSection(sectionName,
                               () =&gt; page.Write(page.RenderSection(sectionName)));
        }
        else if (defaultContent != null) {
            page.DefineSection(sectionName,
                               () =&gt; page.Write(defaultContent(_o)));
        }
        return new HelperResult(_ =&gt; { });
    }
}</pre>
<p>The RedefineSection method conditionally redefines a section (that is it redefines in only if a section was already defined in a content page). The second overload also allows you to provide a default content template that will be used if the content page did not define the section. Using this code you can write the following pages:</p>
<pre title="~/Views/_MasterLayout.cshtml" class="brush: xml;">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;body&gt;
@RenderSection("TitleSection", required: false)
@RenderBody()
&lt;/body&gt;
&lt;/html&gt;</pre>
<pre title="~/Views/_SubLayout.cshtml" class="brush: xml;">@{
    Layout = "~/Views/_MasterLayout.cshtml";
}
&lt;div&gt;
@this.RedefineSection("TitleSection",
                      @&lt;h1&gt;Default SubLayout title&lt;/h1&gt;)
@RenderBody()
&lt;/div&gt;</pre>
<pre title="~/Views/Content.cshtml" class="brush: xml;">@{
    Layout = "~/Views/_SubLayout.cshtml";
}
@section TitleContent {
&lt;h1&gt;Title&lt;/h1&gt;
}
&lt;p&gt;Main content&lt;/p&gt;</pre>
<p>In the above example Content.cshtml defines the &ldquo;TitleContent&rdquo; section. _SubLayout.cshtml redefines that section but also provides some default markup in case the content page does not have the &ldquo;TitleContent&rdquo; section defined. Finally, _MasterLayout.cshtml consumes the section indicating that it is optional &ndash; this means that the entire site will still work even if the content page does not define the section and the intermediate layout does not provide a default value.</p>
<p>Hope you find the above technique useful in your complex layout pages. Please let me know if you encounter any issues and whether these methods are valuable enough that they should be added to the framework for the next version.</p>]]></content:encoded>
    </item>
    <item>
      <title>Optional Razor Sections with Default Content</title>
      <link>https://docs.microsoft.com/archive/blogs/marcinon/optional-razor-sections-with-default-content</link>
      <pubDate>Wed, 08 Dec 2010 12:30:00 GMT</pubDate>
      <dc:creator><![CDATA[Marcin Doboz]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/marcinon/2010/12/08/optional-razor-sections-with-default-content/</guid>
      <description><![CDATA[Solution quick links:

IsSectionDefined method
Razor inline templates

RenderSection
The new...]]></description>
      <content:encoded><![CDATA[<p>Solution quick links:</p>
<ol>
<li><a href="#RazorSectionDefaultContent_IsSectionDefined" title="Solution 1: Use IsSectionDefined method">IsSectionDefined method</a></li>
<li><a href="#RazorSectionDefaultContent_InlineTemplate" title="Solution 1: Use Razor inline templates">Razor inline templates</a></li>
</ol>
<h1>RenderSection</h1>
<p>The new ASP.NET page framework built on Razor (which is available in MVC 3) provides a facility for content pages to contribute named fragments of markup to their layout pages which the layout page can then render in an arbitrary location using the <code>RenderSection</code> method.</p>
<p>For example, the following content page declares an "ExtraContent" section:</p>
<pre class="brush: xml;">@{
    Layout = "~/Views/Shared/_Layout.cshtml";
}

@section ExtraContent {
    &lt;div&gt;Some extra content&lt;/div&gt;
}

&lt;div&gt;The main content&lt;/div&gt;</pre>
<p>And the following layout page renders it:</p>
<pre class="brush: xml;">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;head&gt;&lt;/head&gt;
&lt;body&gt;
@RenderBody()

@RenderSection("ExtraContent")
@RenderSection("OptionalContent", required: false)
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>You can even declare that a section is not required like the &ldquo;OptionalContent&rdquo; section in the example above.</p>
<p>But what if you want to have some default content for your optional sections?</p>
<h1><a name="RazorSectionDefaultContent_IsSectionDefined"></a>Option 1: Use the IsSectionDefined method</h1>
<p>The <code>IsSectionDefined</code> method returns true if a child content page defined a section. You can use that to decide whether to render a section or some other content:</p>
<pre class="brush: xml;">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;body&gt;
@RenderBody()

@if (IsSectionDefined("OptionalContent")) { 
    @RenderSection("OptionalContent")
}
else { 
    &lt;div&gt;Default content&lt;/div&gt;
}
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>Just remember that you need to use the <code>@RenderSection()</code> syntax (you need the <em>@</em> character) so that the contents of the section is actually printed to the output. Without that character you will get an exception with the following message: </p>
<blockquote><i>The following sections have been defined but have not been rendered for the layout page "~/Views/Shared/_Layout.cshtml": "OptionalContent"</i> </blockquote>
<h1><a name="RazorSectionDefaultContent_InlineTemplate"></a>Option 2: Use Razor inline templates</h1>
<p>Razor provides a way to pass inline markup templates into function calls. This is a powerful mechanism that allows you to combine custom markup fragments with general purpose display logic. In order to make the following example work you will need to drop the following code into your project:</p>
<pre class="brush: csharp;">using System.Web.WebPages;
using System;

public static class SectionExtensions {
    private static readonly object _o = new object();
    public static HelperResult RenderSection(this WebPageBase page,
                        string sectionName,
                        Func&lt;object, HelperResult&gt; defaultContent) {
        if (page.IsSectionDefined(sectionName)) {
            return page.RenderSection(sectionName);
        }
        else {
            return defaultContent(_o);
        }
    }
}</pre>
<p>This code essentially wraps the previous example in a reusable extension method. All you need now is to provide the default content markup. With it you can write views like the following:</p>
<pre class="brush: csharp;">&lt;!DOCTYPE html&gt;
&lt;html&gt;
&lt;body&gt;
@RenderBody()

@this.RenderSection("OptionalContent",
                    @&lt;div&gt;Default content&lt;/div&gt;)
&lt;/body&gt;
&lt;/html&gt;</pre>
<p>For the second parameter you need to use the <em>@</em> character to trigger the Razor parser to go into markup mode. Once in markup mode you can do anything that you do in the main body of the page.</p>
<p>Just remember that since this is an extension method you need to call it off the <code>this</code> object. Otherwise the C# compiler will not be able to locate it and you will get a compilation error.</p>
<p>If you like this technique&nbsp;read the follow up: <a href="https://blogs.msdn.com/b/marcinon/archive/2010/12/15/Razor-Nested-Layouts-and-Redefined-Sections.aspx" title="Razor, Nested Layouts and Redefined Sections">Razor, Nested Layouts and Redefined Sections</a> </p>]]></content:encoded>
    </item>
    <item>
      <title>Fixing area view lookups when using multiple view engines</title>
      <link>https://docs.microsoft.com/archive/blogs/marcinon/fixing-area-view-lookups-when-using-multiple-view-engines</link>
      <pubDate>Sun, 14 Nov 2010 23:48:00 GMT</pubDate>
      <dc:creator><![CDATA[Marcin Doboz]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/marcinon/2010/11/14/fixing-area-view-lookups-when-using-multiple-view-engines/</guid>
      <description><![CDATA[11/17 Update: I've fixed a bug in the view engine registration code that prevented this method from...]]></description>
      <content:encoded><![CDATA[<p><b>11/17 Update:</b> I've fixed a bug in the view engine registration code that prevented this method from working. Please note the addition of the <code>dummyFormats</code> property in the solution below.</p>
<p>Oskar from the ASP.NET forums asked a question about the <a href="https://forums.asp.net/t/1623138.aspx">order of view lookups when using Areas in MVC 3</a>. The problem is that&nbsp;now that MVC ships with two view engines registered by default (<code>WebFormViewEngine</code> and <code>RazorViewEngine</code>), the order of lookups might not work as expected when you are using Areas in conjunction with a mixed environment of Aspx and Razor views.</p>
<p>Take the following application layout as an example. This application has an &ldquo;Admin&rdquo; area with a Home controller and a Home Index view written in Razor. There&rsquo;s also a default Home Index view written using the Aspx view engine.</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/95/24/metablogapi/7457.AreaLookup_2A3B5FF5.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-95-24-metablogapi/7457.AreaLookup_5F00_2A3B5FF5.png"><img height="548" width="324" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/95/24/metablogapi/3568.AreaLookup_thumb_70B84FFD.png" original-url="https://blogs.msdn.com/cfs-file.ashx/__key/CommunityServer-Blogs-Components-WeblogFiles/00-00-00-95-24-metablogapi/3568.AreaLookup_5F00_thumb_5F00_70B84FFD.png" alt="AreaLookup" border="0" title="AreaLookup" style="background-image: none; border-right-width: 0px; margin: ; padding-left: 0px; padding-right: 0px; display: inline; float: ; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" /></a></p>
<h1>The Problem</h1>
<p>When requesting the Index action of the Admin area&rsquo;s HomeController you would expect Index.cshtml to be served. However, in MVC 3 you will actually be served Index.aspx. This is because the process for looking up a View involves querying the collection of registered view engine until the first successful match. Once a successful match is found the remaining view engines are ignored. This gets a bit counter-intuitive when you mix Razor and Aspx views because this is the effective search order:</p>
<p>~/Areas/Admin/Views/Home/Index.aspx <br />~/Areas/Admin/Views/Home/Index.ascx <br />~/Areas/Admin/Views/Shared/Index.aspx <br />~/Areas/Admin/Views/Shared/Index.ascx <br /><span style="background-color: #ffff00;">~/Views/Home/Index.aspx <br /></span>~/Views/Home/Index.ascx <br />~/Views/Shared/Index.aspx <br />~/Views/Shared/Index.ascx <br /><span style="background-color: #ffff00;">~/Areas/Admin/Views/Home/Index.cshtml</span> <br />~/Areas/Admin/Views/Home/Index.vbhtml <br />~/Areas/Admin/Views/Shared/Index.cshtml <br />~/Areas/Admin/Views/Shared/Index.vbhtml <br />~/Views/Home/Index.cshtml <br />~/Views/Home/Index.vbhtml <br />~/Views/Shared/Index.cshtml <br />~/Views/Shared/Index.vbhtml</p>
<p>Notice that because the <code>WebFormsViewEngine</code> is registered first by default, the path Views/Home/Index.aspx file gets looked at before the Areas/Admin/Views/Home/Index.cshtml path. That&rsquo;s because the MVC Areas support is not hardcoded as a general pattern. Instead, it&rsquo;s the job of each view engine to implement the lookup ordering and fallback logic.</p>
<p>To make things work intuitively, you would need a multi-pass system that first scans all view engines for area-specific matches and then does another pass asking for general matches. But that is not how things are implemented in MVC (mainly because Areas did not exist in MVC 1 and it was not possible to change the existing view lookup contracts).</p>
<h1>The Solution</h1>
<p>However, it&rsquo;s actually quite easy to reconfigure MVC to emulate this multi-pass behavior. Just use multiple instances of view engines. In your <code>Global.asax.cs</code> file add the following code (don&rsquo;t forget to call this method from <code>Application_Start</code>):</p>
<pre class="brush: csharp; gutter: false; toolbar: false;">public static void SetUpViewEngines(ViewEngineCollection viewEngines) {
    viewEngines.Clear();

    string[] dummyFormats = new[] { "~/ThisFileShouldNotExist.aspx" };

    // area-specific pass
    viewEngines.Add(new WebFormViewEngine {
        ViewLocationFormats = dummyFormats,
        PartialViewLocationFormats = dummyFormats,
        MasterLocationFormats = dummyFormats
    });
    viewEngines.Add(new RazorViewEngine {
        ViewLocationFormats = dummyFormats,
        PartialViewLocationFormats = dummyFormats,
        MasterLocationFormats = dummyFormats
    });

    // general pass
    viewEngines.Add(new WebFormViewEngine {
        AreaViewLocationFormats = null,
        AreaPartialViewLocationFormats = null,
        AreaMasterLocationFormats = null
    });
    viewEngines.Add(new RazorViewEngine {
        AreaViewLocationFormats = null,
        AreaPartialViewLocationFormats = null,
        AreaMasterLocationFormats = null
    });
}</pre>
<p>This solution works by first registering a pair of WebForms and Razor view engines that have dummy general location formats pointing to a file that does not exist (meaning that they are effectively only aware of the area-specific locations formats) and then a pair that only knows about the general location formats. This way both Aspx and Razor views will be searched for in area locations and if neither succeed the general views will be searched.</p>
<p>This technique should be helpful for those who want to transition their application from Aspx to Razor (or maybe between some other pair of view engines). However, once you are done with the transition you should probably stick to just having one view engine registered to avoid unnecessary searches in the other view engines.</p>
<div></div>
<div></div>]]></content:encoded>
    </item>
    <item>
      <title>Granular Request Validation in ASP.NET MVC 3</title>
      <link>https://docs.microsoft.com/archive/blogs/marcinon/granular-request-validation-in-asp-net-mvc-3</link>
      <pubDate>Tue, 09 Nov 2010 11:46:00 GMT</pubDate>
      <dc:creator><![CDATA[Marcin Doboz]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/marcinon/2010/11/09/granular-request-validation-in-asp-net-mvc-3/</guid>
      <description><![CDATA[12/10 Update: In MVC 3 RC 2 SkipRequestValidationAttribute got renamed to AllowHtmlAttribute. I...]]></description>
      <content:encoded><![CDATA[<div class="note">
<p><strong>12/10 Update</strong>: In <a href="https://www.microsoft.com/downloads/en/details.aspx?FamilyID=955d593e-cbd1-4ed1-88eb-02ff79dd74d8">MVC 3 RC 2</a> <code>SkipRequestValidationAttribute</code> <a href="https://www.asp.net/learn/whitepapers/mvc3-release-notes#_Toc2_7">got renamed</a> to <code>AllowHtmlAttribute</code>. I have updated the examples below. </p>
</div>
<p>A little while ago I wrote a blog post describing <a href="https://blogs.msdn.com/b/marcinon/archive/2010/10/06/mvc3-granular-request-validation.aspx">granular request validation that shipped in MVC 3 Beta</a>. However, since then we have changed the API for this feature and that post is no longer valid. In this post I will present the new API which is usable in the recently-shipped <a href="https://go.microsoft.com/fwlink/?LinkID=191797">MVC 3 Release Candidate</a>.</p>
<p>But first: a quick refresh on request validation and why it&rsquo;s great to make it granular. Request validation is a feature of ASP.NET that analyzes the data that a browser sends to the server when a user interacts with your site (such as form or query string data) and rejects requests that contain suspicious input that looks like html code (basically anything with a &lsquo;&lt;&rsquo;). This protects you from HTML injection attacks such as <a href="https://en.wikipedia.org/wiki/Cross-site_scripting">cross-site scripting (XSS)</a>. It is enabled by default, however in previous versions it was an all-on-or-off feature, meaning that if you want to be able to accept HTML-formatted input from your users in just one field you had to completely turn this protection off. This in turn meant that you now had to validate every bit of data that came from the client.</p>
<h1>AllowHtmlAttribute <span style="text-decoration: line-through;">SkipRequestValidationAttribute</span></h1>
<p>In MVC 3 we are introducing a new attribute called <code>AllowHtmlAttribute</code>. You can use this attribute to annotate your model properties to indicate that values corresponding to them should not be validated. Let&rsquo;s take this User model and UserController as an example:</p>
<pre class="brush: csharp;">public class User {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    [AllowHtml]
    public string Description { get; set; }
    [AllowHtml]
    public string Bio { get; set; }
}

public class UserController {
    [HttpPost]
    public ActionResult Update(User user) {
        // update user database
    }
}</pre>
<p>I have annotated the Description and Bio properties to indicate they should not be request-validated. Now when the Update action method gets invoked these two properties on the User object will not be validated and any HTML they might contain will be passed straight through to the action method. However, everything else will still go through request validation and requests that contain suspicious content in the Name or Email fields will get rejected.</p>
<h1>ValidateInputAttribute</h1>
<p><code>AllowHtmlAttribute</code> can only be applied to properties of a model class. For other request validation scenarios the existing <a href="https://msdn.microsoft.com/en-us/library/system.web.mvc.validateinputattribute.aspx"><code>ValidateInputAttribute</code></a> is still helpful. For example, you can use it to disable request validation for action methods that bind to a loose collection of parameters:</p>
<pre class="brush: csharp;">[ValidateInput(false)]
public ActionResult Update(int userId, string description) {
}</pre>
<p>Now when the parameters of the Update method get bound request validation will not be performed. You can apply <code>ValidateInput</code> to action methods as shown above or to the entire controller to affect all of its action methods.</p>
<p><code>ValidateInput</code> is also more usable in MVC 3. In MVC 2 running on .NET 4 you had to set <code>requestValidationMode="2.0"</code> in order to turn request validation off. In MVC 3 this is no longer necessary.</p>]]></content:encoded>
    </item>
    <item>
      <title>Granular Request Validation in ASP.NET MVC 3 Beta</title>
      <link>https://docs.microsoft.com/archive/blogs/marcinon/granular-request-validation-in-asp-net-mvc-3-beta</link>
      <pubDate>Wed, 06 Oct 2010 12:15:00 GMT</pubDate>
      <dc:creator><![CDATA[Marcin Doboz]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/marcinon/2010/10/06/granular-request-validation-in-asp-net-mvc-3-beta/</guid>
      <description><![CDATA[11/9 Update: This article only applies to the MVC 3 Beta release. I have a new post about...]]></description>
      <content:encoded><![CDATA[<div class="note">
<p><b>11/9 Update:</b> This article only applies to the MVC 3 Beta release. I have a new <a href="https://blogs.msdn.com/b/marcinon/archive/2010/11/09/mvc3-granular-request-validation-update.aspx">post about AllowHtmlAttribute</a> that describes the new APIs and behaviors available in MVC 3 RC and later.</p>
</div>
<p>If you don&rsquo;t know already, we have just released the <a href="https://go.microsoft.com/fwlink/?LinkID=191795">ASP.NET MVC 3 Beta</a> and it brings a slew of new features. A small but useful feature is what we call granular request validation. It allows you to opt out of ASP.NET&rsquo;s request validation on a field-by-field basis, meaning that it will be a lot easier now to write forms that accept HTML user input (think smart text boxes like TinyMCE, etc.) for some of the fields while at the same time maintaining the built-in security for the rest.</p>
<p>Request Validation is a core ASP.NET feature that helps in preventing <a href="https://en.wikipedia.org/wiki/Cross-site_scripting">cross-site scripting (XSS)</a> and other flavors of HTML injection attacks. It works by examining incoming requests and blocking when any client-supplied data (such as through form fields or the query string) contains potentially dangerous input (for example, the less-than character &lsquo;&lt;&rsquo;). It is turned on by default and the you have to explicitly disable it if you want to accept HTML-formatted user input. However, until now this was an all-or-nothing setting and turning it off meant that you had to take extra steps to manually validate all of the inputs for malicious content.</p>
<p>In ASP.NET MVC you can control whether an action should have request validation performed using <a href="https://msdn.microsoft.com/en-us/library/system.web.mvc.validateinputattribute.aspx"><code>ValidateInputAttriubte</code></a>. For example the following usage will disable request validation:</p>
<pre class="brush: csharp;">[ValidateInput(false)]
public ActionResult MyAction() { ... }</pre>
<div class="note">
<p><strong>Note for ASP.NET 4:</strong> because of the <a href="https://www.asp.net/learn/whitepapers/aspnet4/breaking-changes#0.1__Toc256770147">hardening of request validation</a> in .NET 4 for the above usage to actually work in MVC 2 you had to revert to 2.0 behavior by changing a setting in web.config:</p>
<pre class="brush: xml;">&lt;httpRuntime requestValidationMode="2.0" /&gt;</pre>
</div>
<p>MVC 3 Beta introduces a new property on <code>ValidateInputAttribute</code> called <code>Exclude</code>. Using this property you can opt out of request validation for only <em>some</em> of your fields. For example, take the following User model:</p>
<pre class="brush: csharp;">public class User {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Email { get; set; }
    public string Description { get; set; }
    public string Bio { get; set; }
}</pre>
<p>If you want your users to be able to edit their Bio or Description and insert arbitrary markup into those two fields while at the same time ensuring no markup makes its way into the Name or Email fields you can annotate your action in the following manner:</p>
<pre class="brush: csharp;">[ValidateInput(true, Exclude="Bio, Description")]
public ActionResult Edit(User user) { ... }</pre>
<p>The <code>Exclude</code> property takes in a string with a comma-separated list of property/field names that should not be validated. All other fields in the incoming request will be validated and blocked if dangerous input is detected.</p>
<p>With this Beta release it is also no longer necessary to set your application to 2.0 request validation mode. You benefit from .NET 4&rsquo;s more secure behavior while at the same time being able to allow unvalidated HTML input only on the fields of your choosing.</p>]]></content:encoded>
    </item>
  </channel>
</rss>