Be aware that this is not going to be a classic how-to article that delves more or less deeply into some technical issue or feature. It is, instead, an article that aims at providing an overview of the options you have at present for architecting Web solutions.
Web solutions? Why not simply Web sites?
Gone are the days when a team could solve a business problem by simply building a set of interrelated Web pages. Most of the time, you don't build plain Web sites anymore; you build articulated solutions that result from the combination of various artifacts, including a classic Web site full of HTML pages, a mobile front end for navigation over devices, maybe a push-notification endpoint for mobile apps that relates to the solution, and a distinct network for static content.
Each piece of the solution requires its own framework when not on its own platform. This causes a proliferation of frameworks and codenames that are confusing to everybody except a (very) small group of geeks.
In addition, sites like GitHub make it easy for everybody to contribute his own work to the community. Far from being a problem, it encourages everybody to write his own framework for doing the same things as others but in a slightly different way that the author and a few followers reckoned was better.
Now, if your work is on the cutting edge, and you are lucky enough to only work on brand-new projects from day one, and your buyers are open to any sort of technology or framework regardless of support (and lack thereof), availability of (and lack thereof) service-level agreements, open-source statements and similar, then you live in a perfect world. But otherwise, you may just happen to live in the neighborhood of hell and want to move elsewhere.
This article, like a real-estate leaflet, lists properties on sale without exaggerating value, benefits, and quality!
Web Problem Solving as of the 2010s
Today, if you have a specific, well-identified problem. you open up Google or Bing and just type some words that describe the problem. More often than not, you write a simple question. Try typing something like “how to authenticate users…” in Google. You'll get more precise suggestions as you type and in the end you obtain a long list of links. More importantly, the list has a high likelihood to include just one suggestion that will really help solve the problem or, at least, provide key hints on further steps. Figure 1 doesn't lie.
Because questions are often direct and straightforward, the answers you may find-mostly through StackOverflow-are likewise specific and direct. Often, with a couple of clicks, you close the ticket and move to the next.
Now try typing another kind of question, for example "Web Forms vs ...". (See Figure 2.)
Not surprisingly, Google helps out providing by search options and subsequently related links. The key difference, though, is in the “vs” string.
It indicates that you are not looking for a direct answer on how to code a given feature. Therefore, there's no guarantee that the list of links contains just one that explains exactly what you need to learn. If you use “vs” in the question, you're likely looking to learn rather than just be informed on how to do something. It's a “doing” versus an “understanding” issue.
When it comes to contrasting and comparing frameworks for building Web solutions (or other types of solutions), it all depends on the material that has been published to the Internet and indexed by the search engine. Answers need to be extensive, go deep into the subject, and they take time to write and read. Often, answers cut long stories short and often they skip or skim over the aspect that's most interesting for you.
It's not easy to get (and explain) the big picture of Web frameworks today. Especially, if you spent past years in the cave of a long-term ASP.NET Web Forms project that now needs be refreshed. You look around and see so many new frameworks and wonder which one is the best for another long-term project.
Well, the first point you're missing is that you may not need to determine which framework is ideal for you. It's more likely to be a combination of frameworks.
Web Solutions Today
When it comes to planning Web solutions using the Microsoft stack, you have the following options available: ASP.NET Web Forms, ASP.NET MVC, or Single-Page Application (SPA).
These three options refer to the skeleton of the solution; in other words, how you make entry points available to the users and encourage the users to interact with the application.
If you choose Web Forms, you populate the Web server with ASPX pages and force users to request them and navigate through them. Internally, ASPX pages can offer any level of support for Ajax features to minimize page refresh rates. The more Ajax features you add, the more you shift the app towards a (hybrid) SPA model.
If you choose ASP.NET MVC, you populate the Web server with controller classes and Razor views. You force users to follow more descriptive URLs that refer to actions instead of pages. It's not a significant difference for the end user, but it's quite a bit of difference (in good but also in bad) for some developers. Similarly, the more Ajax features you add, the more you shift the ASP.NET MVC app towards a (hybrid) SPA model.
Finally, you can envision your Web solution as an entirely client-side application. This means that on the Web server, you only have a few HTML pages and a lot of JavaScript files. In addition, you reference lots of resources from external (or proprietary) content delivery networks (CDN) to take advantage of caching shared resources and split the workload between the server that serves pages and data and the server that only serves static resources; such as CSS, images, and scripts. For a classic Web developer, the SPA option is a complete shift of paradigm. For the end user equipped with an up-to-date Web browser, a well-done SPA solution is paradise. Even an older Web browser can see a bit of a difference.
For developers, a SPA solution is challenging but requires use (and knowledge) of ad hoc JavaScript frameworks, such as AngularJS or perhaps EmberJS. These frameworks smooth handling of typical HTTP issues (routing, session, history) that are managed by the Web server otherwise or just don't exist because of the server-centric architecture.
Finally, whatever archetypal solution you opt for, you then have the problem of defining the SDK of your application as a set of publicly callable HTTP endpoints. This is where Web API and possibly Katana fit in. Let's step into each option and examine the state of the art.
ASP.NET Web Forms Today
It is estimated that the popularity of ASP.NET is only second to PHP in the space of Web solutions, but it is light years away from reaching out the same PHP penetration. Still, most of the ASP.NET Web applications today are based on the ASP.NET Web Forms framework. A common user story sounds like this:
We have a Web application that is a few years old. It works well, and we've fine-tuned its performance and it scales as appropriate. We know how to maintain and evolve it. However, we're facing new business challenges and we're considering a serious remake. What should we do? We understand that Microsoft itself seems to push ASP.NET MVC. We've also found a Microsoft reference that claims Web API as the future. Are we wrong if we stick to Web Forms?
In the Microsoft Web stack, ASP.NET Web Forms is by far the most known and used framework. Except from brand new projects, the lion's share of remakes for existing sites starts from a large ASP.NET codebase. Quite paradoxically, architects surface after years of hard work on a single system and get a clear message that ASP.NET Web Forms is a thing of the past-perhaps even a dead thing.
They diligently look around for alternatives and find nothing that is clearly better than ASP.NET Web Forms. More precisely, they hardly find a strong business reason for choosing ASP.NET MVC over Web Forms. And for the most part, they're right.
Who's wrong then?
Let's pinpoint the pros and cons of ASP.NET Web Forms.
ASP.NET Web Forms was devised in the late 1990s in the thick of the browsers war. At that time, any approach that could minimize the impact on browsers was warmly welcomed. ASP.NET Web Forms introduced server controls to produce user interface without developers having to learn HTML. Server controls, at the same time, enabled Visual Studio to do some good WYSIWYG prototyping of pages. All aspects and properties of server controls could be configured programmatically using C# or Visual Basic with nearly no exposure to HTML and JavaScript. Once configured, server controls generated HTML and JavaScript for the browser. Server controls were, in other words, factories of HTML that acted on the server side.
At the same time, other aspects of Web programming, such as session state, authentication, and statefulness, were handled by the ad hoc infrastructure offered by ASP.NET and IIS. In particular, the post-back model was the junction point between Web and desktop programming.
The postback model enabled a programming model similar to what developers did for years: paint the user interface, wait for the user to interact, react to the user's action in the system, and repaint the user interface. In the Web space, this inherently stateful model could be implemented over a stateless protocol like HTTP, thanks to the machinery of ASP.NET.
A fundamental gear of this machinery is the notorious viewstate
.
ASP.NET Web Forms was the right framework at the right time and reached its climax with version 2.0 back in 2005. No significant changes were required by the platform after that to improve the set of functionalities. More importantly, ASP.NET Web Forms was designed to serve at a time in which abstraction over HTML and JavaScript was perceived as an excellent plus.
ASP.NET Web Forms was devised in an age when direct exposure to HTML and JavaScript was dangerous for the health of developers and applications. ASP.NET Web Forms guaranteed results while keeping developers at a safe distance from HTML.
Remember the popular cartoon representing human evolution? I mean the one where you see evolution from various types of hominid unable to stand right to outstanding human being and then down with the back to a human being sitting to a computer desk? The payoff says “something somewhere went terribly wrong”. But what went terribly wrong at some point to mark ASP.NET Web Forms as obsolete and no longer keen technology?
From my standpoint, the poisoned arrow which shot ASP.NET Web Forms in the heel-like Achilles-has the name of Ajax. Ajax represented a complete paradigm shift. It gave spark to a process that progressively shifted focus from the server to the client, taking the value of server assets down every day. The same framework that worked great and brilliantly served business needs for years became pure junk to get rid of to the eyes of Ajax advocates.
The advent of Ajax and the subsequent change of perspective are real. Is it also real that Web Forms is now pure junk? For sure, the design principles of ASP.NET Web Forms are outdated from the point of view of Ajax. Can we say the same for ASP.NET Web Forms applications?
You can still build Web applications using ASP.NET Web Forms. You still have plenty of commercial extensions and libraries. You still have a mature and reliable platform being maintained for a few more years and supported for the foreseeable future. If it works for you, then it just works. Period.
Another way to look at it is this: Web Forms worked well for you in the past decade, and the whole team knows the platform very well. Now, you're about to embark on a significant remake. Is Web Forms up to the task you want it to? If your purpose is building a highly responsible SPA or, more simply, a JavaScript intensive application, you may be facing a hard time. If you need to ensure full accessibility to any page of the site, then you may be facing a hard time. If it's critical to have SEO-friendly URLs, then with Web Forms you may be facing a hard time.
Facing a hard time doesn't mean not being able to do things. Following up version 2.0 of ASP.NET Web Forms, Microsoft improved some aspects of Web Forms to minimize the aforementioned aspects. So there's no compelling business reason to leave ASP.NET Web Forms to embrace other Web frameworks.
So does this mean that advocates of ASP.NET MVC or SPA are dead wrong?
I'm a big fan of ASP.NET MVC and I switched to it for all projects that I have control on. But honestly, I'm unable to provide many compelling business reasons that make it highly beneficial to switch to MVC. I stop at “control over HTML,” which ultimately means more power for handling accessibility.
Most points that MVC advocates make against ASP.NET Web Forms are absolutely true and fair. Except that-in my humble opinion-they don't make a difference business-wise.
Table 1 is a synopsis of reasons commonly put forward to abandon Web Forms for ASP.NET MVC and countermeasures that you can take to improve your Web Forms code.
A lot of developers hate viewstate and tend to see it as the root of all evil. Like it or not, viewstate is tightly bound to the postback model. If you think that the postback model is great for you, then viewstate is part of it. It tends to make pages bigger, but the size can be controlled. By the same token, if page size is an issue and you track it back to viewstate, then changing the programming model-and making the switch to, say, ASP.NET MVC-is probably the only viable option. But whether viewstate is good or bad shouldn't be an absolute statement.
Let's look at unit testing. The HTTP context exposed in Web Forms is not mockable and this cuts your testing power short. If you opt for ASP.NET MVC instead, you have a richer infrastructure designed for testability from the ground up.
That's far from the idea of neglecting unit testing in general, but I'm not sure the mocking the HTTP context is the most important aspect of testing the code of Web applications. By taking code out of the code-behind classes and moving it to user-defined service classes-designed for testability-you reduce the responsibility of code-behind classes and decouple HTTP context from application and business logic. If the service class that manages a postback event needs data from the Cache
or Session
state, you ensure that it is passed in a proper data transfer object. The code snippet below shows the point. Suppose this comes from default.aspx.cs.
private void Button1_Click(Object sender, EventArgs e){
var dataFromSession = Session["DataToBeProcessed"];
var service = new DefaultAspxService(dataFromSession);
service.ProcessButton1Click();}
You don't need to mock up Session; you can just keep your code-behind class as thin as possible. The service class is fully testable. I agree that this is not the same as having an environment designed for testability; but plain good refactoring of the code magically improves the testability of Web Forms code.
Unit testing is a development feature; not a business feature. I'm not sure you can easily sell a site upgrade to ASP.NET MVC because in that way, it'll be easier for you to test the code.
What's the bottom line with Web Forms? If you don't have a special reason to seriously complain about it, and if you see a significant effort or cost for your team in acquiring new MVC skills, then you can keep up with Web Forms. Regardless of what you may hear, the majority of production sites based on ASP.NET use ASP.NET Web Forms. You won't be alone out there.
ASP.NET MVC Today
Between me and ASP.NET MVC, it wasn't love at first sight. But like it happens in the real world, a relationship that builds up day after day may result in full love and has the potential to last forever. ASP.NET MVC and I are now happy together. On my end, I feel I can say that my love for ASP.NET MVC is justified because it captured my heart with features that I contrasted to Web Forms for several months. There's nothing like religion, and nothing insane at all, in my passion for ASP.NET MVC. As I like to say, instead, it's a sane passion.
Now why on earth did Microsoft, at some point in the fall of 2007, decide they had to give to happy and stabilized ASP.NET developers a second option to build Web sites? Did someone at Microsoft know about the Dead Poets Society movie (check it out at http://en.wikipedia.org/wiki/Dead_Poets_Society)?
The movie tells the story of an English teacher, played by Robin Williams, who astonishes and conquers students with his unorthodox way of explaining poetry. A popular quote from the movie is “I stand upon my desk to remind myself that we must constantly look at things in a different way.”
Was ASP.NET MVC designed so that the team could look at Web development from a different perspective?
A different perspective of known subjects, I'm sure you agree, is more valuable when you're in the process of learning; not necessarily when you're just trying to solve concrete problems. Still, a new perspective may help in the long run to solve problems in a more efficient way.
I like to think that ASP.NET MVC was offered to the masses as a different perspective of Web development, highly inspired by a long list of open-source MVC-based frameworks available. As usual, when a new perspective is offered, some people get it right away, either because they could capture the essence of change sooner than others or because they feel cool at grabbing anything new ahead of time and religiously stick to it.
Some people, instead, take to it slowly and some refuse to take to it at all. Each party tends to criticize opponents, hardly getting to the point of understanding the pros and cons of the subject in an unbiased way.
Personally, I formed the idea that initially Microsoft pushed out MVC for merely commercial purposes-corralling more developers to the ASP.NET platform and offering the same perspective and experience for Web development as frameworks like MonoRail. ASP.NET MVC, though, was not bad at all and ended up providing a powerful framework for the Web of the 2010s.
ASP.NET Web Forms was inspired by the vision of the Web of the late 2000s. ASP.NET MVC just offers a more up-to-date view of the Web at a time in which the expected responsiveness of pages grew to a level hard to achieve on top of Web Forms pillars. Web Forms owed its success to the thick abstraction layer it built over a Web core infrastructure.
Conversely, ASP.NET MVC is most appreciated for making the same abstraction layer as thin as possible. Web Forms makes a point of shielding developers from HTML, CSS, and JavaScript. ASP.NET MVC makes the opposite point-giving you total control over markup, including HTML, CSS, and JavaScript. In a way, they are at the opposite extremes of the solution range. Both can do the job; but it depends on circumstances and preferences which one (if any) is ideal for you.
The Web today seems to be oriented towards intensive use of JavaScript to empower and render pages and CSS to style pages. These goals are much easier to achieve if you use ASP.NET MVC to host the application.
Awareness of this point leads some people to praise ASP.NET MVC as the only way to go and neglects Web Forms as an obsolete and badly arranged technology. But that's way too simplistic a view.
Technically speaking, I'd summarize the difference between ASP.NET Web Forms and ASP.NET MVC by saying that ASP.NET MVC neatly separates the processing phase from the rendering phase. In doing so, it breaks up the postback model, and pushes a programming model that is both stateless and much closer to the true underpinnings of the Web. The postback model was an abstraction provided to assimilate Web development to stateful desktop development. This abstraction is deliberately broken - by design - in MVC.
In ASP.NET MVC, a request is mapped to a method on a controller class; the URL indicates the controller class. In ASP.NET Web Forms, a request is mapped to a method in the code-behind class of the ASPX page that is referenced from the URL. In Web Forms, though, a number of steps are performed before the request is actually processed. In particular, the last-known-good-state of the page is restored, reading back from the viewstate and copying viewstate content onto properties of freshly instantiated page server controls. In ASP.NET MVC, instead, once the action method is known, it can be run and it has access to the HTTP context. Next, once the processing phase has ended, any generated results are passed to a distinct subsystem - the rendering engine - for producing markup, JSON, or whatever else the method is expected to return. In Web Forms, generated values must be bound to server controls in order to produce updated markup.
In ASP.NET MVC, you finally have separation of concerns between rendering and processing -which makes it inherently easier to write testable code.
What's the bottom line with ASP.NET MVC? It's a framework for building Web applications the way Web applications are commonly built these days. It's easier to use, according to newer standards, but it doesn't mean that's the only way to go.
I've seen the dichotomy of ASP.NET Web Forms versus ASP.NET MVC put down in terms of car versus motorcycle. I think there's a much better analogy: automatic transmission versus manual transmission for cars. Both do the job, but automatic is easier and more modern, although in some countries it costs you extra. Manual is harder to manage, but it may be cheaper and doesn't really represent a problem if you know how to handle it.
I suggest you find a way to learn and use ASP.NET MVC anyway; for example, in toy or pilot projects to start with. At the same time, you shouldn't be worried about choosing ASP.NET Web Forms if that gives you a sense of stability and confidence. Just make sure that you pick up the latest version of ASP.NET Web Forms and extensively use improvements over viewstate and control management that were introduced with ASP.NET 4.0.
Web API Today
The increasing responsiveness of pages is a must for every Web developer today. More responsive pages can hardly be achieved without a set of remote HTTP-reachable endpoints to invoke through JavaScript functions. The key is that these endpoints should return raw data (e.g., JSON, XML, plain text) to be rendered into a nice-looking format within the browser. What's the ideal way to set up such a Web service front end?
Over the years, various frameworks have been regularly presented as the definitive solution to the issue. So you may remember that, at some point, WCF was nominated as the ideal technology to build a service layer for whatever kind of client, including TCP and HTTP clients. WCF has never been focused to HTTP, however.
Next, WCF went through a number of extensions aimed at simplifying HTTP programming; examples are Web HTTP binding and REST starter kit. In the end, it was never a way to directly enable HTTP-based servers, but it was always WCF over HTTP. Developers accepted it, but never loved it.
In this regard, Web API is the latest, and hopefully definitive, attempt to provide an ideal framework for Web services over HTTP. Although sometimes perceived as an ASP.NET MVC-related thing, Web API is a general framework that's not limited to use in web scenarios.
Web API is an engine that receives and handles HTTP calls. Its overall architecture mimics ASP.NET MVC (i.e., controllers, actions, routing, model binding, and extensibility), with some important differences. In particular, the runtime of Web API is completely separated from ASP.NET MVC. You meet classes with similar names and behavior, but namespaces are different and assemblies are different. This is the factor that enables also Web Forms applications to use Web API, giving developers two benefits: stop using WCF and its over-configured and auto-generated proxies, and learn a much simpler model to grab data from remote data sources.
The differences between ASP.NET MVC and Web API are summarized by the following three points:
- Decoupling processing code from serialization of results.
- Content negotiation.
- Hosting outside of IIS.
A Web API layer is made up of a collection of controller classes, but derived from a different base class - ApiController. HTTP GET action methods defined on a controller can return raw data without explicitly passing from an ActionResult container, as in ASP.NET MVC.
public IList<News> GetAll(int count=20)
{ // This is processing code for the request
var url = ...;
var client = new WebClient();
var rss = client.DownloadString(url);
var news = ParseRssInternal(rss, count);
// Returning raw data; no HTTP packaging/formatting
return news;
}
Any data returned from a Web API action method passes through a formatting layer - content negotiation - that ultimately determines the stream to be served back to the caller. Content negotiation, for the most part, is invisible to the developer. Standard conventions return any data to JSON by default; however, extensibility points exist to replace the JSON formatter, or serialize to a general-purpose or type-specific custom XML formatter. You register your own formatters at the startup of the application as part of the configuration effort.
Finally, ASP.NET MVC is - by design - a Web application and requires a Web server. IIS is the natural choice to host ASP.NET MVC applications. Supported by this fact, designers have tightly bound some aspects of ASP.NET MVC to IIS.
Web API abstracts the hosting environment so that it fits well in IIS but also works well with custom host applications. In the end, a Web API layer - much like a WCF service - can be hosted in any application (console, Windows service, WPF) that exposes the right interfaces.
The bottom line with Web API is that it aims at being a key constituent part of a Web solution; but it still needs an HTML rendering engine. Such a rendering engine can be server-side and take the form of an ASP.NET Web Forms or MVC application. Or it can be on the client side and take the form of a SPA.
Web API aims at being a key constituent part of any Web solution for its ability to provide a HTTP-reachable backend, but the solution still needs an HTML-rendering engine.
SPA Today
The current evolution of the Internet leads to a scenario in which more and more work is done on the client and the server is often used as a mere manager of data and workflows. At the end of this path, we find the SPA model.
I discovered SPA at the same time as I discovered Ajax, about a decade ago. Back then, I dismissed SPA because of the issues with Web client programming that today frameworks like Bootstrap and AngularJS seem to be able to solve. The main benefit I see with a SPA model is not in having a more responsive application. There are many ways to get that without shifting to a radically different paradigm like SPA.
The main benefit of SPA is that most rendering work (e.g., HTML building) is done on the client. But this benefit is mostly evident for large applications. Think of Gmail, for example, and its gazillion users. Moving HTML rendering to the connected browser saves a humongous amount of logic on the server. This is doubly beneficial in both cost savings and responsiveness. The cost is learning a new paradigm and, for Google and Twitter, building new (large and complex) frameworks.
How costly is it to learn AngularJS (or other frameworks)? Do you trust your learning skills? SPA can be good for everyone; but it is crucial only for a few companies. SPA can be painful for everyone, if tackled the wrong way or through inappropriate tools.
At the Very End of the Day
Figure 3 summarizes how popular Web frameworks in the Microsoft stack fit together.
For any Web solution, you need an HTML-rendering engine responsible for returning HTML markup for a specified URL. In a SPA scenario, the rendering engine might consist of a single URL (single page) or just a few pages-one for the use-case or main logical area.
In a Web Forms scenario, the rendering engine is a set of ASPX pages; in ASP.NET MVC it's a set of controllers and Razor views. Your solutions should be as responsive as possible. Responsiveness can be achieved in part through CSS tricks and effects but for the most part, it depends on data downloaded and/or cached, and on dynamic DOM updates. Downloads require a HTTP front end. You can build such a front end using WCF services (now a superseded approach), an ASP.NET MVC application, or a Web API layer hosted in IIS. A Web API layer may not be necessary if you're already using ASP.NET MVC as the HTML rendering engine. A Web API layer is the simplest and most beneficial way to add responsiveness via Ajax to Web Forms solutions.
Summary
You can build Web solutions in many equally effective ways. At present, I don't see one approach above the others from any angle. A purely technical perspective recommends newer frameworks; a more business-oriented view may choose more mature, stable and better-known frameworks. As usual, it depends on your perspective of coding and projects. This said, though, Web API looks like the next big area of focus for developers who are really looking for new perspectives in Web development. But an old and classic perspective, such as ASP.NET Web Forms or ASP.NET MVC, still works with no significant limitations.
Reason | Countermeasure |
---|---|
Viewstate | The viewstate API has been significantly improved in ASP.NET 4 and later. You now have a lot more control over the amount of viewstate emitted on a per-control basis. |
Hard to unit-test | The ASP.NET Web Forms runtime is not designed for testability; but you can write your code to be testable. Using the Model-View-Presenter pattern and proper Separation-of-Concerns lets you shield your code from the HTTP runtime. There's no real need to mock-up the HTTP context to cover relevant parts of your code. |
No control over markup of server controls | This aspect of the API has also been improved starting with ASP.NET 4. Although a server control is conceived to be a sort of black-box acting as an HTML factory, you have more power on it and can always override controls, fix the rendering engine, and use commercial products. |
Limited SEO | This aspect has been improved starting with ASP.NET 4 with the introduction of URL mapping and routing. |
Limited support for dynamic DOM updates | Starting with ASP.NET 4, it's much easier to assign a unique ID to nearly any element generated within a Web Forms control template. |