Headspring has developed and donated Portable Areas to the MvcContrib project. It currently resides in the MVC2 branch on the MvcContrib GitHub source control site. Eric Hexter has written a multi-piece tutorial on how to create and publish a Portable Area assembly.
Download code here.
A Portable Area builds on the concept of an ASP.NET control, and it takes it a step further. Whereas a control can encapsulate a certain part of the page to deliver rich functionality, a Portable Area can encapsulate an unlimited number of pages in a single assembly. The Portable Area in itself is an ASP.NET MVC 2 area that is packaged in a certain way into a single .Net assembly.
Component vendors have offerings of rich functionality packaged up into web controls. Now with MvcContrib layered on top of ASP.NET MVC 2, component vendors as well as you and I can package and distribute entire sections of functionality in a single binary. Think of comprehensive user administration and diagnostics. Think of executive dashboards and content management. All this rich front-end functionality can be packaged and distributed while at the same time allowing for the application to examine and process messages being sent from the Portable Area.
For example, a dashboard portable area might need 5 key metrics based on the type of dashboard used. It sends a QueryMessage to the application (via the Portable Areas bus) requesting these metrics. A query message handler that the application defines accepts the query message and provides the metrics for the portable area to consume and publish on the rich dashboard.
In this application, I want to demonstrate how Portable Areas, while being based on ASP.NET MVC 2, are a generic ASP.NET component model. This example, available via the MvcContrib CodePlex page, is a standard Web Forms application with the LoginPortableArea configured. This is just the first sample portable area that is included in MvcContrib’s MVC2 branch.
Enabling MVC routes and views in a Web Forms app.
In you web.config, you will need to add the following section in your <pages/> element:
Also, you need to add the UrlRoutingModule to the <httpModules/> element:
You will also need a Site.Master page in the page where the Portable Area expects it. This may be a future enhancement, but it must implement content placeholders for TitleContent and MainContent. Use it to adapt the sections of your existing master page so that views delivered by the portable area fit nicely within your own master page. Also notice the web.config file that must be in the Views folder (just copy it from an empty ASP.NET MVC project):
Registering the LoginPortableArea and handling messages sent by it:
In your Global.asax file, there are a few lines of code to register the portable area:
Notice that you are registering two classes of your own:
We will explore LoginHandler, but download the code if you care to see the ForgotPasswordHandler. We register handlers with the bus so that we have classes that can be created and passed the messages. Here is what LoginHandler looks like:
Derive from MessageHandler<TMessage> or implement IMessageHandler fully. Putting the type of the message in the declaration will tell the bus that this handler knows how to handle that message type. It is possible to create a handler that can inspect ALL message types by implementing IMessageHandler fully.
There are three types of messages that a Portable Area might send:
- IEventMessage : informational purposes
- IQueryMessage : requesting some information
- ICommandMessage : requestion the app to perform some action
All the message types are IEventMessage(s), and they all flow down the same bus. There is a handler factory abstraction you can set so that you are in control of the construction of event handler classes. The default that is built in is Activator.CreateInstance() – requires a no-arg constructor.
Once this is wired up, we can run our app and see the only page present, Default.aspx
This is our only Web Form in the application. It uses some built-in login controls to show who is logged in as well as links to login and log out. I have configured forms authentication in the web.config file. We will run the browser and step through the sequence of screens:
We see that we are not logged in. Let’s click the “Login” link . . .
Now we are in the Portable Area. This page is not defined in our app at all. Let’s type in a user name and password and click Submit. . .
Now it knows that I am logged in, and regular Web Forms gives me a handy “Logout” link.
This post has given us an example of how to consume an MvcContrib Portable Area from within a regular Web Forms app. Furthermore, it demonstrates how to run ASP.NET MVC pages right alongside Web Forms pages.
Call to action for component vendors
Please flood the marketplace with richer components that span multiple pages. The controls are nice and very useful, but there is lots of general functionality that can be bought instead of built by every development team. Portable Areas work in ASP.NET MVC as well as Web Forms, so while the development model is MVC, the consumption and customer market is the full breadth of ASP.NET developers.