June 2009 Blog Posts
When you visit Norway, it takes a week to recover. Ok, at least when I visit Norway, it takes a week. But that’s just a testament to the good time I had. As they say, what happens in Vegas stays in Vegas, but what happens in Oslo gets recorded as a .NET Rocks Live episode.
The week before last, I spent the week in Oslo, Norway attending and speaking at the Norwegian Developer’s Conference (NDC 09). This conference was not your typical Microsoft conference I usually attend but was a conference on .NET with a heavy Agile Software bent.
Just looking at the speaker line-up will tell you that. Scott Bellware tweeted a blurb recently that succinctly summarized my impression of the conference:
how to know you're at a good conference: the speakers are going to sessions (at least the ones who aren't working on their sessions)
That is definitely true. I didn’t attend as many talks as I would have liked, but I did manage to attend two by Mary Poppendieck which really sparked my imagination and got me excited about the concept of a problem solving organization and learning more about Lean. She had promised to put her slides on her site, but I can’t for the life of me find them! ;)
While there, I gave three talks, one of them being a joint talk with the Hanselnator (aka Mr. Hanselman).
Black Belt Ninja Tips ASP.NET MVC
This covered several tips on getting more out of ASP.NET MVC and included the first public demonstration of David Ebbo’s T4 template.
ASP.NET MVC + AJAX = meant for each other
This covered the Ajax helpers included with ASP.NET MVC and drilled into some of the lesser known client aspects of these helpers, such as showing the Sys.Mvc.AjaxContext object and how to leverage it. The talk then moved into a demonstration of the client templating feature of ASP.NET Ajax 4 Preview 4. I showed off some of the work Jonathan Carter and I (mostly Jonathan) did to make two-way data binding work with ASP.NET MVC. The audience really dug it.
The Haacked and Hanselman Show
So named because we didn’t have any agenda until about a week before the conference, this ended up being a web security talk where Scott would present a common “secure” implementation of a feature, I would then proceed to “Haack” the feature, and then Scott would fix the feature, all the while explaining what was going on. I think this was very big hit as we saw messages on Twitter like “I’m now too afraid to build a web application”. ;) Of course, I hope more attendees felt empowered rather than fearful. :P
The conference was held in an indoor soccer stadium since it was a venue large enough for all the attendees. They curtained off sections of the bleachers to create rooms for giving the talks. On the outside of the curtains was a large screen which allowed attendees to walk around from talk to talk with a headset on the conference floor if they didn’t feel like sitting in the bleachers.
Plenty of bean bags on the floor provided a comfortable place to relax and listen in. In fact, that’s where I would often find some of my new friends lounging around such as the crazy Irishman.
On the second night of the conference, we all rocked out at the big attendee party featuring the band, DataRock which played some rocking music with geek friendly lyrics like:
I ran into her on computer camp
(Was that in 84?)
Not sure
I had my commodore 64
Had to score
-- DataRock, Computer Camp Love
Many thanks to Kjetil Klaussen for posting those lyrics in his NDC 09 highlights post because I had forgotten pretty much every lyric. :) After DataRock, we all went upstairs for the after party to enjoy a more intimate setting with LoveShack, an 80s cover band.
One interesting highlight of the show was a live recording of .NET Rocks. The show was originally going to simply feature Scott Hanselman, but while hanging out in the speakers lounge Carl Franklin, one of the hosts of the show, suggested I join in the fun too.
While it was great fun, Scott is a big, no ginormous, personality and I rarely got a word in edgewise, except for the few times I swooped right in just in time to put my foot in my mouth to apparently great comedic effect. In any case, you can listen to the results yourself, though I hope they post the video soon to get the full effect of how much fun everyone was having. :) Be warned, there’s not a lot of real software development content in the show.
The conference ended on Friday leaving all of Saturday for me to relax and actually get out and see Oslo. On Saturday, I headed out to Vigeland Statue Park with an eclectic group of people, Ted Neward, Rocky Lhotka and his wife, Jeremy Miller, and Anna K{Something With Too Many Syllables in a Row}, a conference organizer herself.
The park was very beautiful and I took a ton of pictures, but unfortunately I lost my camera on the flight home from Norway. :( So instead, I’ll just include this Creative Commons licensed picture taken by Cebete from Flickr. The main difference was the sky was a deep blue when we visited.
That evening, Sondre Bjellås, an attendee, was kind enough to invite several of us over to his flat for a little gathering. I headed over with Bellware and Anna since everyone else was pretty much flattened by the previous weeks activities. It was great to meet non-techie Norwegians such as his wife and friends in order to get a different perspective on what it’s like to live in Norway. The answer: expensive!
In an odd coincidence, on my connecting flight in Philadelphia, I ran into my good friend Walter who happened to be flying home from Belgium. In fact, we were on the same flight in the same exit row with seats right next to each other. How’s that for a funny coincidence?
Show me the Code!
Rune, one of the organizers of the conference, assures me that the videos of the talks will be posted online soon, so you’ll get to see them if you’d like. I’ve also posted my powerpoint slides and code samples here.
Please note that my talks tend to be heavy in demos so the Powerpoint decks don’t have much content in them. Likewise, the code samples represent the “before” state of my talks, not the “after” state. I usually write up a checklist for each talk which I use a to remind myself where I am in those cases where I have a total brain fart and forget my own name under the pressure of presenting.
Other NDC 09 Posts
In my last post, I wrote about the hijacking of JSON arrays. Near the end of the post, I mentioned a comment whereby someone suggests that what really should happen is that browsers should be more strict about honoring content types and not execute code with the content type of application/json.
I totally agree! But then again, browsers haven’t had a good track record with being strict with such standards and it’s probably too much to expect browsers to suddenly start tightening ship, not to mention potentially breaking the web in the process.
Another potential solution that came to mind was this: Can we simply change JSON? Is it too late to do that or has that boat left the harbor?

Let me run an idea by you. What if everyone got together and decided to version the JSON standard and change it in such a way that when the entire JSON response is an array, the format is no longer executable script. Note that I’m not referring to an array which is a property of a JSON object. I’m referring to the case when the entire JSON response is an array.
One way to do this, and I’m just throwing this out there, is to make it such that the JSON package must always begin and end with a curly brace. JSON objects already fulfill this requirement, so their format would remain unchanged.
But when the response is a JSON array, we would go from here:
[{"Id":1,"Amt":3.14},{"Id":2,"Amt":2.72}]
to here:
{[{"Id":1,"Amt":3.14},{"Id":2,"Amt":2.72}]}
Client code would simply check to see if the JSON response starts with {[ to determine whether it’s an array, or an object. There many alternatives, such as simply wrapping ALL JSON responses in some new characters to keep it simple.
It’d be possible to do this without breaking every site out there by simply giving all the client libraries a head start. We would update the JavaScript libraries which parse JSON to recognize this new syntax, but still support the old syntax. That way, they’d work with servers which haven’t yet upgraded to the new syntax.
As far as I know, most sites that make use of JSON are using it for Ajax scenarios so the site developer is in control of the client and server anyways. For sites that provide JSON as a cross-site service, upgrading the server before the clients are ready could be problematic, but not the end of the world.
So what do you think? Is this worth pursuing? Not that I have any idea on how I would convince or even who I would need to convince. ;)
UPDATE: 6/26 10:39 AM
Scott Koon points out this idea is not new (I didn’t think it would be) and points to a great post that gives more detail on the specifics of executable JSON as it relates to the ECMAScript Specification.
A while back I wrote about a subtle JSON vulnerability which could result in the disclosure of sensitive information. That particular exploit involved overriding the JavaScript Array constructor to disclose the payload of a JSON array, something which most browsers do not support now.
However, there’s another related exploit that seems to affect many more browsers. It was brought to my attention recently by someone at Microsoft and Scott Hanselman and I demonstrated it at the Norwegian Developers Conference last week, though it has been demonstrated against Twitter in the past.

Before I go further, let me give you the punch line first in terms of what this vulnerability affects.
This vulnerability requires that you are exposing a JSON service which…
- …returns sensitive data.
- …returns a JSON array.
- …responds to GET requests.
- …the browser making the request has JavaScript enabled (very likely the case)
- …the browser making the request supports the
__defineSetter__ method.
Thus if you never send sensitive data in JSON format, or you only send JSON in response to a POST request, etc. then your site is probably not vulnerable to this particular vulnerability (though there could be others).
I’m terrible with Visio, but I thought I’d give it my best shot and try to diagram the attack the best I could. In this first screenshot, we see the unwitting victim logging into the vulnerable site, and the vulnerable site issues an authentication cookie, which the browser holds onto.
At some point, either in the past, or the near future, the bad guy spams the victim with an email promising a hilariously funny video of a hamster on a piano.

But the link actually points to the bad guy’s website. When the victim clicks on the link, the next two steps happen in quick succession. First, the victim’s browser makes a request for the bad guy’s website.
The website responds with some HTML containing some JavaScript along with a script tag. When the browser sees the script tag, it makes another GET request back to the vulnerable site to load the script, sending the auth cookie along.
The bad guy has tricked the victim’s browser to issue a request for the JSON containing sensitive information using the browser’s credentials (aka the auth cookie). This loads the JSON array as executable JavaScript and now the bad guy has access to this data.
To gain a deeper understanding, it may help to see actual code (which you can download and run) which demonstrates this attack.
Note that the following demonstration is not specific to ASP.NET or ASP.NET MVC in any way, I just happen to be using ASP.NET MVC to demonstrate it. Suppose the Vulnerable Website returns JSON with sensitive data via an action method like this.
[Authorize]
public JsonResult AdminBalances() {
var balances = new[] {
new {Id = 1, Balance=3.14},
new {Id = 2, Balance=2.72},
new {Id = 3, Balance=1.62}
};
return Json(balances);
}
Assuming this is a method of HomeController, you can access this action via a GET request for /Home/AdminBalances which returns the following JSON:
[{"Id":1,"Balance":3.14},{"Id":2,"Balance":2.72},{"Id":3,"Balance":1.62}]
Notice that I’m requiring authentication via the AuthorizeAttribute on this action method, so an anonymous GET request will not be able to view this sensitive data.
The fact that this is a JSON array is important. It turns out that a script that contains a JSON array is a valid JavaScript script and can thus be executed. A script that just contains a JSON object is not a valid JavaScript file. For example, if you had a JavaScript file that contained the following JSON:
{"Id":1, "Balance":3.14}
And you had a script tag that referenced that file:
<script src="http://example.com/SomeJson"></script>
You would get a JavaScript error in your HTML page. However, through an unfortunate coincidence, if you have a script tag that references a file only containing a JSON array, that would be considered valid JavaScript and the array gets executed.
Now let’s look at the HTML page that the bad guy hosts on his/her own server:
<html>
...
<body>
<script type="text/javascript">
Object.prototype.__defineSetter__('Id', function(obj){alert(obj);});
</script>
<script src="http://example.com/Home/AdminBalances"></script>
</body>
</html>
What’s happening here? Well the bad guy is changing the prototype for Object using the special __defineSetter__ method which allows overriding what happens when a property setter is being called.
In this case, any time a property named Id is being set on any object, an anonymous function is called which displays the value of the property using the alert function. Note that the script could just as easily post the data back to the bad guy, thus disclosing sensitive data.
As mentioned before, the bad guy needs to get you to visit his malicious page shortly after logging into the vulnerable site while your session on that site is still valid. Typically a phishing attack via email containing a link to the evil site does the trick.
If by blind bad luck you’re still logged into the original site when you click through to the link, the browser will send your authentication cookie to the website when it loads the script referenced in the script tag. As far as the original site is concerned, you’re making a valid authenticated request for the JSON data and it responds with the data, which now gets executed in your browser. This may sound familiar as it is really a variant of a Cross Site Request Forgery (CSRF) attack which I wrote about before.
If you want to see it for yourself, you can grab the CodeHaacks solution from GitHub and run the JsonHijackDemo project locally (right click on the project and select Set as StartUp Project. Just follow the instructions on the home page of the project to see the attack in action. It will tell you to visit http://demo.haacked.com/security/JsonAttack.html.
Note that this attack does not work on IE 8 which will tell you that __defineSetter__ is not a valid method. Last I checked, it does work on Chrome and Firefox.
The mitigation is simple. Either never send JSON arrays OR always require an HTTP POST to get that data (except in the case of non-sensitive data in which case you probably don’t care). For example, with ASP.NET MVC, you could use the AcceptVerbsAttribute to enforce this like so:
[Authorize]
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult AdminBalances() {
var balances = new[] {
new {Id = 1, Balance=3.14},
new {Id = 2, Balance=2.72},
new {Id = 3, Balance=1.62}
};
return Json(balances);
}
One issue with this approach is that many JavaScript libraries such as jQuery request JSON using a GET request by default, not POST. For example, $.getJSON issues a GET request by default. So when calling into this JSON service, you need to make sure you issue a POST request with your client library.
ASP.NET and WCF JSON service endpoints actually wrap their JSON in an object with the “d” property as I wrote about a while back. While it might seem odd to have to go through this property to get access to your data, this awkwardness is eased by the fact that the generated client proxies for these services strip the “d” property so the end-user doesn’t need to know it was ever there.
With ASP.NET MVC (and other similar frameworks), a significant number of developers are not using client generated proxies (we don’t have them) but instead using jQuery and other such libraries to call into these methods, making the “d” fix kind of awkward.
What About Checking The Header?
Some of you might be wondering, “why not have the JSON service check for a special header such as the X-Requested-With: XMLHttpRequest or Content-Type: application/json before serving it up in response to a GET request?” I too thought this might be a great mitigation because most client libraries send one or the other of these headers, but a browser’s GET request in response to a script tag would not.
The problem with this (as a couple of co-workers pointed out to me) is that at some point in the past, the user may have made a legitimate GET request for that JSON in which case it may well be cached in the user’s browser or in some proxy server in between the victim’s browser and the vulnerable website. In that case, when the browser makes the GET request for the script, the request might get fulfilled from the browser cache or proxy cache. You could try setting No-Cache headers, but at that point you’re trusting that the browser and all proxy servers correctly implement caching and that the user can’t override that accidentally.
Of course, this particular caching issue isn’t a problem if you’re serving up your JSON using SSL.
The real issue?
There’s a post at the Mozilla Developer Center which states that object and array initializers should not invoke setters when evaluated, which at this point, I tend to agree with, though a comment to that post argues that perhaps browsers really shouldn’t execute scripts regardless of their content type, which is also a valid complaint.
But at the end of the day, assigning blame doesn’t make your site more secure. These type of browser quirks will continue to crop up from time to time and we as web developers need to deal with them. Chrome 2.0.172.31 and Firefox 3.0.11 were both vulnerable to this. IE 8 was not because it doesn’t support this method. I didn’t try it in IE 7 or IE 6.
It seems to me that to be secure by default, the default behavior for accessing JSON should probably be POST and you should opt-in to GET, rather than the other way around as is done with the current client libraries. What do you think? And how do other platforms you’ve worked with handle this? I’d love to hear your thoughts.
In case you missed it, here are the repro steps again: grab the CodeHaacks solution from GitHub and run the JsonHijackDemo project locally (right click on the project and select Set as StartUp Project. Just follow the instructions on the home page of the project to see the attack in action. To see a successful attack, you’ll need to do this in a vulnerable browser such as Firefox 3.0.11.
I followed up this post with a proposal to fix JSON to prevent this particular issue.
Every now and then some email or website comes along promising to prove Fred Brooks wrong about this crazy idea he wrote in The Mythical Man Month (highly recommended reading!) that there is no silver bullet which by itself will provide a tenfold improvement in productivity, reliability, and simplicity within a decade.
This time around, the promise was much like others, but they felt the need to note that their revolutionary new application/framework/doohickey will allow business analysts to directly build applications 10 times as fast without the need for programmers!
Ah yeah! Get rid of those foul smelling pesky programmers! We don’t need em!
Now wait one dag-burn minute! Seriously?!
I’m going to try real hard for a moment to forget they said that and not indulge my natural knee jerk reaction which is to flip the bozo bit immediately. If I were a more reflective person, this would raised a disturbing question:
Why are these business types so eager to get rid of us programmers?
It’s easy to blame the suits for not understanding software development and forcing us into a Tom Smykowski moment having to defend what it is we do around here.
Well-well look. I already told you: I deal with the god damn customers so the engineers don't have to. I have people skills; I am good at dealing with people. Can't you understand that? What the hell is wrong with you people?
Maybe, as Steven “Doc” List quotes from Cool Hand Luke in his latest End Bracket article on effective communication for MSDN Magazine,
What we've got here is a failure to communicate.
Leon Bambrick (aka SecretGeek) recently wrote about this phenomena in his post entitled, The Better You Program, The Worse You Communicate, in which he outlines how techniques that make us effective software developers do not apply to communicating with other humans.
After all, we can sometimes be hard to work with. We’re often so focused on the technical aspects and limitations of a solution that we unknowingly confuse the stakeholders with jargon and annoy them by calling their requirements “ludicrous”. Sometimes, we fail to deeply understand their business and resort to making fun of our stakeholders rather than truly understanding their needs. No wonder they want to do the programming themselves!
Ok, ok. It’s not always like this. Not every programmer is like this and it isn’t fair to lay all the blame at our feet. I’m merely trying to empathize and understand the viewpoint that would lead to this idea that moving programmers out of the picture would be a good thing.
Some blame does deserve to lie squarely at the feet of these snake oil salespeople, because at the moment, they’re selling a lie. What they’d like customers to believe is your average business analyst simply describes the business in their own words to the software, and it spits out an application.
The other day, I started an internal email thread describing in hand-wavy terms some feature I thought might be interesting. A couple hours later, my co-worker had an implementation ready to show off.
Now that my friends, is the best type of declarative programming. I merely declared my intentions, waited a bit, and voila! Code! Perhaps that’s along the lines of what these types of applications hope to accomplish, but there’s one problem. In the scenario I described, it required feeding requirements to a human. If I had sent that email to some software, it would have no idea what to do with it.
At some point, something close to this might be possible, but only when software has reached the point where it can exhibit sophisticated artificial intelligence and really deal with fuzziness. In other words, when the software itself becomes the programmer, only then might you really get rid of the human programmer. But I’m sorry to say, you’re still working with a programmer, just one who doesn’t scoff at your requirements arrogantly (at least not in your face while it plots to take over the world, carrot-top).
Until that day, when a business analyst wires together an applications with Lego-like precision using such frameworks, that analyst has in essence become a programmer. That work requires many of the same skills that developers require. At this point, you really haven’t gotten rid of programmers, you’ve just converted a business type into a programmer, but one who happens to know the business very well.
In the end, no matter how “declarative” a system you build and how foolproof it is such that a non-programmer can build applications by dragging some doohickeys around a screen, there’s very little room for imprecision and fuzziness, something humans handle well, but computers do not, as Spock demonstrated so well in an episode of Star Trek.
“Computer, compute the last digit of PI” - Spock
Throw into the mix that the bulk of the real work of building an application is not the coding, but all the work surrounding that, as Udi Dahan points out in his post on The Fallacy of ReUse.
This is not to say that I don’t think we should continue to invest in building better and better tools. After all, the history of software development is about building better and better higher level tools to make developers more productive. I think the danger lies in trying to remove the discipline and traits that will always be required when using these tools to build applications.
Even when you can tell the computer what you want in human terms, and it figures it out, it’s important to still follow good software development principles, ensure quality checks, tests, etc…
The lesson for us programmers, I believe is two-fold. One, we have to educate our stakeholders about how software production really works. Even if they won’t listen, a little knowledge and understanding here goes a long way. Be patient, don’t be condescending, and hope for the best. Secondly, we have to educate ourselves about the business in a deep manner so that we are seen as valuable business partners who happen to write the code that matters.
A little while ago I announced our plans for ASP.NET MVC as it relates to Visual Studio 2010. ASP.NET MVC wasn’t included as part of Beta 1, which raised a few concerns by some (if not conspiracy theories!) ;). The reason for this was simple as I pointed out:
One thing you’ll notice is that ASP.NET MVC is not included in Beta 1. The reason for this is that Beta 1 started locking down before MVC 1.0 shipped. ASP.NET MVC will be included as part of the package in VS10 Beta 2.
…
We’re working hard to have an out-of-band installer which will install the project templates and tooling for ASP.NET MVC which works with VS2010 Beta 1 sometime in June on CodePlex. Sorry for the inconvenience. I’ll blog about it once it is ready.
Today I’m happy to announce that we’re done with the work I described and the installer is now available on CodePlex. Be sure to give it a try as many of the new VS10 features intended to support the TDD workflow fit very nicely with ASP.NET MVC, which ScottGu will describe in an upcoming blog post.
If you run into problems with the intaller, try out this troubleshooting guide by Jacques, the developer who did the installer work and do provide feedback.
You’ll notice that the installer says this is ASP.NET MVC 1.1, but as the readme notes point out, this is really ASP.NET MVC 1.0 retargeted for Visual Studio 2010. The 1.1 is just a placeholder version number. We bumped up the version number to avoid runtime conflicts with ASP.NET MVC 1.0. All of this and more is described in the Release Notes.
When VS10 Beta 2 comes out, you won’t need to download a separate standalone installer to get ASP.NET MVC (though a standalone installer will be made available for VS2008 users that will run on ASP.NET 3.5 SP1). A pre-release version of ASP.NET MVC 2 will be included as part of the Beta 2 installer as described in the …
Roadmap

I recently published the Roadmap for ASP.NET MVC 2 which gives a high level look at what features we plan to do for ASP.NET MVC 2. The features are noticeably lacking in details as we’re deep in the planning phase trying to gather pain points.
Right now, we’re avoiding focusing the implementation details as much as possible. When designing software, it’s very easy to have preconceived notions about what the solution should be, even when we really don’t have a full grasp of the problem that needs to be solved.
Rather than guiding people towards what we think the solution is, I hope to focus on making sure we understand the problem domain and what people want to accomplish with the framework. That leaves us free to try out alternative approaches that we might not have considered before such as alternatives to expression based URL helpers. Maybe the alternative will work out, maybe not. Ideally, I’d like to have several design alternatives to choose from for each feature.
As we get further along the process, I’ll be sure to flesh out more and more details in the Roadmap and share them with you.
Snippets
One cool new feature of VS10 is that snippets now work in the HTML editor. Jeff King from the Visual Web Developer team sent me the snippets we plan to include in the next version. They are also downloadable from the CodePlex release page. Installation is very simple:
Installation Steps:
1) Unzip "ASP.NET MVC Snippets.zip" into "C:\Users\<username>\Documents\Visual Studio 10\Code Snippets\Visual Web Developer\My HTML Snippets", where "C:\" is your OS drive.
2) Visual Studio will automatically detect these new files.
Try them out and let us know if you have ideas for snippets that will help you be more productive.
Important Links:
One of the features contained in the MVC Futures project is the ability to generate action links in a strongly typed fashion using expressions. For example:
<%= Html.ActionLink<HomeController>(c => c.Index()) %>
Will generate a link to to the Index action of the HomeController.
It’s a pretty slick approach, but it is not without its drawbacks. First, the syntax is not one you’d want to take as your prom date. I guess you can get used to it, but a lot of people who see it for the first time kind of recoil at it.
The other problem with this approach is performance as seen in this slide deck I learned about from Brad Wilson. One of the pain points the authors of the deck found was that the compilation of the expressions was very slow.
I had thought that we might be able to mitigate these performance issues via some sort of caching of the compiled expressions, but that might not work very well. Consider the following case:
<% for(int i = 0; i < 20; i++) { %>
<%= Html.ActionLink<HomeController>(c => c.Foo(i)) %>
<% } %>
Each time through that loop, the expression is the same: c => c.Foo(i)
But the value of the captured “i” is different each time. If we try to cache the compiled expression, what happens?
So I started thinking about an alternative approach using code generation against the controllers and circulated an email internally. One approach was to code gen action specific action link methods. Thus the about link for the home controller (assuming we add an id parameter for demonstration purposes) would be:
<%= HomeAboutLink(123) %>
Brad had mentioned many times that while he likes expressions, he’s no fan of using them for links and he tends to write specific action link methods just like the above. So what if we could generate them for you so you didn’t have to write them by hand?
A couple hours after starting the email thread, David Ebbo had an implementation of this ready to show off. He probably had it done earlier for all I know, I was stuck in meetings. Talk about the best kind of declarative programming. I declared what I wanted roughly with hand waving, and a little while later, the code just appears! ;)
David’s approach uses a BuildProvider to reflect over the Controllers and Actions in the solution and generate custom action link methods for each one. There’s plenty of room for improvement, such as ensuring that it honors the ActionNameAttribute and generating overloads, but it’s a neat proof of concept.
One disadvantage of this approach compared to the expression based helpers is that there’s no refactoring support. However, if you rename an action method, you will get a compilation error rather than a runtime error, which is better than what you get without either. One advantage of this approach is that it performs fast and doesn’t rely on the funky expression syntax.
These are some interesting tradeoffs we’ll be looking closely at for the next version of ASP.NET MVC.