Maarten Balliauw {blog}

ASP.NET, ASP.NET MVC, Windows Azure, PHP, ...

NAVIGATION - SEARCH

Book review: Learning Ext JS

learning-ext-js For a project at one of our customers, we’re building a rich web application using the Coolite web controls in ASP.NET MVC. Coolite is a great product, wrapping all Ext JS widgets in an ASP.NET control. Upon ordering a license for both, we received two free copies of Packt’s “Learning Ext JS”, providing better insight in what’s going on behind the curtains of Coolite.

I only spent one evening reading this book and must admit: it’s really great at getting you started quickly with Ext JS. You’re working with grids, windows and your own grid column renderers, creating a nice looking application which enables you to  manage your DVD collection. As a plus, almost every example features a character or quote from the best movie ever (as an ICT-er): Office Space. This makes it a nice read (at least for me).

The people at Coolite actually did a great job providing this book with their license, as you get a better view of what they do when wrapping Ext JS widgets. If you’re not buying Coolite or a commercial Ext JS license, there’s always Packt’s website offering this book for purchase, too. Nice read!

PHPPowerPoint 0.1.0 (CTP1) released!

PHPPowerPoint logo People following me on Twitter could have already guessed, but here’s something I probably should not have done for my agenda: next to the well known PHPExcel class library, I’ve now also started something similar for PowerPoint: PHPPowerPoint.

Just like with PHPExcel, PHPPowerPoint can be used to generate PPTX files from a PHP application. This can be done by creating an in-memory presentation that consists of slides and different shapes, which can then be written to disk using a writer (of which there’s currently only one for PowerPoint 2007).

Simple PHPPowerPoint demo Here’s some sample code:

[code:c#]

/* Create new PHPPowerPoint object */
$objPHPPowerPoint = new PHPPowerPoint();

/* Create slide */
$currentSlide = $objPHPPowerPoint->getActiveSlide();

/* Create a shape (drawing) */
$shape = $currentSlide->createDrawingShape();
$shape->setName('PHPPowerPoint logo');
$shape->setDescription('PHPPowerPoint logo');
$shape->setPath('./images/phppowerpoint_logo.gif');
$shape->setHeight(36);
$shape->setOffsetX(10);
$shape->setOffsetY(10);
$shape->getShadow()->setVisible(true);
$shape->getShadow()->setDirection(45);
$shape->getShadow()->setDistance(10);

/* Create a shape (text) */
$shape = $currentSlide->createRichTextShape();
$shape->setHeight(300);
$shape->setWidth(600);
$shape->setOffsetX(170);
$shape->setOffsetY(180);
$shape->getAlignment()->setHorizontal( PHPPowerPoint_Style_Alignment::HORIZONTAL_CENTER );
$textRun = $shape->createTextRun('Thank you for using PHPPowerPoint!');
$textRun->getFont()->setBold(true);
$textRun->getFont()->setSize(60);
$textRun->getFont()->setColor( new PHPPowerPoint_Style_Color( 'FFC00000' ) );

/* Save PowerPoint 2007 file */
$objWriter = PHPPowerPoint_IOFactory::createWriter($objPHPPowerPoint, 'PowerPoint2007');
$objWriter->save(str_replace('.php', '.pptx', __FILE__));

[/code]

Advanced sample A more advanced sample is also included in the download, where a complete presentation is rendered using PHPPowerPoint.

Now go grab the fresh sample on CodePlex and be the very first person downloading and experimenting with it. Feel free to post some feature requests or general remarks on CodePlex too.

I want to thank my employer, RealDolmen, for letting me work on this during regular office hours and also the people at DynamicLogic who convinced me to start this new project.

MSDN session on ASP.NET MVC

As promised to all people attending my online session on ASP.NET MVC this afternoon, here is the slide deck I’ve used.

I must say, doing a presentation using Live Meeting and a Microsoft Roundtable device seemed a bit strange at first. However, the setup that is used to do this kind of sessions is really cool to work with! Make sure to check Katrien’s blog for all other Live Meeting MSDN sessions that are planned.

kick it on DotNetKicks.com

ASP.NET MVC and the Managed Extensibility Framework (MEF)

Microsoft’s Managed Extensibility Framework (MEF) is a .NET library (released on CodePlex) that enables greater re-use of application components. You can do this by dynamically composing your application based on a set of classes and methods that can be combined at runtime. Think of it like building an appliation that can host plugins, which in turn can also be composed of different plugins. Since examples say a thousand times more than text, let’s go ahead with a sample leveraging MEF in an ASP.NET MVC web application.

kick it on DotNetKicks.com

Getting started…

The Managed Extensibility Framework can be downloaded from the CodePlex website. In the download, you’ll find the full source code, binaries and some examples demonstrating different use cases for MEF.

Now here’s what we are going to build: an ASP.NET MVC application consisting of typical components (model, view, controller), containing a folder “Plugins” in which you can dynamically add more models, views and controllers using MEF. Schematically:

Sample Application Architecture

Creating a first plugin

Before we build our host application, let’s first create a plugin. Create a new class library in Visual Studio, add a reference to the MEF assembly (System.ComponentModel.Composition.dll) and to System.Web.Mvc and System.Web.Abstractions. Next, create the following project structure:

Sample Plugin Project

That is right: a DemoController and a Views folder containing a Demo folder containing Index.aspx view. Looks a bit like a regular ASP.NET MVC application, no? Anyway, the DemoController class looks like this:

[code:c#]

[Export(typeof(IController))]
[ExportMetadata("controllerName", "Demo")]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class DemoController : Controller
{
    public ActionResult Index()
    {
        return View("~/Plugins/Views/Demo/Index.aspx");
    }
}

[/code]

Nothing special, except… what are those three attributes doing there, Export and PartCreationPolicy? In short:

  • Export tells the MEF framework that our DemoController class implements the IController contract and can be used when the host application is requesting an IController implementation.
  • ExportMetaData provides some metadata to the MEF, which can be used to query plugins afterwards.
  • PartCreationPolicy tells the MEF framework that it should always create a new instance of DemoController whenever we require this type of controller. By defaukt, a single instance would be shared across the application which is not what we want here. CreationPolicy.NonShared tells MEF to create a new instance every time.

Now we are ready to go to our host application, in which this plugin will be hosted.

Creating our host application

The ASP.NET MVC application hosting these plugin controllers is a regular ASP.NET MVC application, in which we’ll add a reference to the MEF assembly (System.ComponentModel.Composition.dll). Next, edit the Global.asax.cs file and add the following code in Application_Start:

[code:c#]

ControllerBuilder.Current.SetControllerFactory(
    new MefControllerFactory(
        Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Plugins")));

[/code]

What we are doing here is telling the ASP.NET MVC framework to create controller instances by using the MefControllerFactory instead of ASP.NET MVC’s default DefaultControllerFactory. Remember that everyone’s always telling ASP.NET MVC is very extensible, and it is: we are now changing a core component of ASP.NET MVC to use our custom MefControllerFactory class. We’re also telling our own MefControllerFactory class to check the “Plugins” folder in our web application for new plugins. By the way, here’s the code for the MefControllerFactory:

[code:c#]

public class MefControllerFactory : IControllerFactory
{
    private string pluginPath;
    private DirectoryCatalog catalog;
    private CompositionContainer container;

    private DefaultControllerFactory defaultControllerFactory;

    public MefControllerFactory(string pluginPath)
    {
        this.pluginPath = pluginPath;
        this.catalog = new DirectoryCatalog(pluginPath);
        this.container = new CompositionContainer(catalog);

        this.defaultControllerFactory = new DefaultControllerFactory();
    }

    #region IControllerFactory Members

    public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
    {
        IController controller = null;

        if (controllerName != null)
        {
            string controllerClassName = controllerName + "Controller";
            Export<IController> export = this.container.GetExports<IController>()
                                             .Where(c => c.Metadata.ContainsKey("controllerName")
                                                 && c.Metadata["controllerName"].ToString() == controllerName)
                                             .FirstOrDefault();
            if (export != null) {
                controller = export.GetExportedObject();
            }
        }

        if (controller == null)
        {
            return this.defaultControllerFactory.CreateController(requestContext, controllerName);
        }

        return controller;
    }

    public void ReleaseController(IController controller)
    {
        IDisposable disposable = controller as IDisposable;
        if (disposable != null)
        {
            disposable.Dispose();
        }
    }

    #endregion
}

[/code]

Too much? Time for a breakdown. Let’s start with the constructor:

[code:c#]

public MefControllerFactory(string pluginPath)
{
    this.pluginPath = pluginPath;
    this.catalog = new DirectoryCatalog(pluginPath);
    this.container = new CompositionContainer(catalog);

    this.defaultControllerFactory = new DefaultControllerFactory();
}

[/code]

In the constructor, we are storing the path where plugins can be found (the “Plugins” folder in our web application). Next, we are telling MEF to create a catalog of plugins based on what it can find in that folder using the DirectoryCatalog class. Afterwards, a CompositionContainer is created which will be responsible for matching plugins in our application.

Next, the CreateController method we need to implement for IControllerFactory:

[code:c#]

public IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName)
{
    IController controller = null;

    if (controllerName != null)
    {
        string controllerClassName = controllerName + "Controller"; 
        Export<IController> export = this.container.GetExports<IController>()
                                         .Where(c => c.Metadata.ContainsKey("controllerName") 
                                             && c.Metadata["controllerName"].ToString() == controllerName)
                                         .FirstOrDefault();
        if (export != null) {
            controller = export.GetExportedObject();
        }
    }

    if (controller == null)
    {
        return this.defaultControllerFactory.CreateController(requestContext, controllerName);
    }

    return controller;
}

[/code]

This method handles the creation of a controller, based on the current request context and the controller name that is required. What we are doing here is checking MEF’s container for all “Exports” (plugins as you wish) that match the controller name. If one is found, we return that one. If not, we’re falling back to ASP.NET MVC’s DefaultControllerBuilder.

The ReleaseController method is not really exciting: it's used by ASP.NET MVC to correctly dispose a controller after use.

Running the sample

First of all, the sample code can be downloaded here: MvcMefDemo.zip (270.82 kb)

When launching the application, you’ll notice nothing funny. That is, untill you want to navigate to the http://localhost:xxxx/Demo URL: there is no DemoController to handle that request! Now compile the plugin we’ve just created (in the MvcMefDemo.Plugins.Sample project) and copy the contents from the \bin\Debug folder to the \Plugins folder of our host application. Now, when the application restarts (for example by modifying web.config), the plugin will be picked up and the http://localhost:xxxx/Demo URL will render the contents from our DemoController plugin:

Sample run MEF ASP.NET MVC

Conclusion

The MEF (Managed Extensibility Framework) offers a rich manner to dynamically composing applications. Not only does it allow you to create a plugin based on a class, it also allows exporting methods and even properties as a plugin (see the samples in the CodePlex download).

By the way, sample code can be downloaded here: MvcMefDemo.zip (270.82 kb)

kick it on DotNetKicks.com

Using the ASP.NET MVC Futures AsyncController

Last week, I blogged about all stuff that is included in the ASP.NET MVC Futures assembly, which is an assembly available on CodePlex and contains possible future features (tonguetwister!) for the ASP.NET MVC framework. One of the comments asked for more information on the AsyncController that is introduced in the MVC Futures. So here goes!

kick it on DotNetKicks.com

Asynchronous pages

The AsyncController is an experimental class to allow developers to write asynchronous action methods. But… why? And… what? I feel a little confusion there. Let’s first start with something completely different: how does ASP.NET handle requests? ASP.NET has 25 threads(*) by default to service all the incoming requests that it receives from IIS. This means that, if you have a page that requires to work 1 minute before returning a response, only 25 simultaneous users can access your web site. In most situations, this occupied thread will just be waiting on other resources such as databases or webservice, meaning it is actualy waiting without any use while it should be picking up new incoming requests.

(* actually depending on number of CPU’s and some more stuff, but this is just to state an example…)

In ASP.NET Webforms, the above limitation can be worked around by using the little-known feature of “asynchronous pages”. That <%@ Page Async="true" ... %> directive you can set in your page is not something that had to do with AJAX: it enables the asynchronous page processing feature of ASP.NET Webforms. More on how to use this in this article from MSDN magazine. Anyway, what basically happens when working with async pages, is that the ASP.NET worker thread fires up a new thread, assigns it the job to handle the long-running page stuff and tells it to yell when it’s done so that the worker thread can return a response to the user. Let me rephrase that in an image:

Asynchronous page flow 

I hope you see that this pattern really enables your web server to handle more requests simultaneously without having to tweak standard ASP.NET settings (which may be another performance tuning thing, but we will not be doing that in this post).

AsyncController

The ASP.NET MVC Futures assembly contains an AsyncController class, which actually mimics the pattern described above. It’s still experimental and subject to change (or to disappearing), but at the moment you can use it in your application. In general, the web server schedules a worker thread to handle an incoming request. This worker thread will start a new thread and call the action method on there. The worker thread is now immediately available to handle a new incoming request. Sound a bit the same as above, no? Here’s an image of the AsyncController flow:

AsyncController thread flow

Now you know the theory, let’s have a look at how to implement the AsyncController pattern…

Preparing your project…

Before you can use the AsyncController, some changes to the standard “File > New > MVC Web Application” are required. Since everything I’m talking about is in the MVC Futures assembly, first grab the Microsoft.Web.Mvc.dll at CodePlex. Next, edit Global.asax.cs and change the calls to MapRoute into MapAsyncRoute, like this:

[code:c#]

routes.MapAsyncRoute(
    "Default",
    "{controller}/{action}/{id}",
    new { controller = "Home", action = "Index", id = "" }
);

[/code]

No need to worry: all existing synchronous controllers in your project will keep on working. The MapAsyncRoute automatically falls back to MapRoute when needed.

Next, fire up a search-and-replace on your Web.config file, replacing

[code:c#]

<add verb="*" path="*.mvc" validate="false" type="System.Web.Mvc.MvcHttpHandler, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

<add name="MvcHttpHandler" preCondition="integratedMode" verb="*" path="*.mvc" type="System.Web.Mvc.MvcHttpHandler, System.Web.Mvc, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>

[/code]

with:

[code:c#]

<add verb="*" path="*.mvc" validate="false" type="Microsoft.Web.Mvc.MvcHttpAsyncHandler, Microsoft.Web.Mvc"/>

<add name="MvcHttpHandler" preCondition="integratedMode" verb="*" path="*.mvc" type="Microsoft.Web.Mvc.MvcHttpAsyncHandler, Microsoft.Web.Mvc"/>

[/code]

If you now inherit all your controllers from AsyncController instead of Controller, you are officially ready to begin some asynchronous ASP.NET MVC development.

Asynchronous patterns

Ok, that was a lie. We are not ready yet to start asynchronous ASP.NET MVC development. There’s a choice to make: which asynchronous pattern are we going to implement?

The AsyncController offers 3 distinct patterns to implement asynchronous action methods.. These patterns can be mixed within a single AsyncController, so you actually pick the one that is appropriate for your situation. I’m going trough all patterns in this blog post, starting with…

The IAsyncResult pattern

The IAsyncResult pattern is a well-known pattern in the .NET Framework and is well documened on MSDN. To implement this pattern, you should create two methods in your controller:

[code:c#]

public IAsyncResult BeginIndexIAsync(AsyncCallback callback, object state) { }
public ActionResult EndIndexIAsync(IAsyncResult asyncResult) { }

[/code]

Let’s implement these methods. In the BeginIndexIAsync method, we start reading a file on a separate thread:

[code:c#]

public IAsyncResult BeginIndexIAsync(AsyncCallback callback, object state) {
    // Do some lengthy I/O processing... Can be a DB call, file I/O, custom, ...
    FileStream fs = new FileStream(@"C:\Windows\Installing.bmp",
        FileMode.Open, FileAccess.Read, FileShare.None, 1, true);
    byte[] data = new byte[1024]; // buffer

    return fs.BeginRead(data, 0, data.Length, callback, fs);
}

[/code]

Now, in the EndIndexIAsync action method, we can fetch the results of that operation and return a view based on that:

[code:c#]

public ActionResult EndIndexIAsync(IAsyncResult asyncResult)
{
    // Fetch the result of the lengthy operation
    FileStream fs = asyncResult.AsyncState as FileStream;
    int bytesRead = fs.EndRead(asyncResult);
    fs.Close();

    // ... do something with the file contents ...

    // Return the view
    ViewData["Message"] = "Welcome to ASP.NET MVC!";
    ViewData["MethodDescription"] = "This page has been rendered using an asynchronous action method (IAsyncResult pattern).";
    return View("Index");
}

[/code]

Note that standard model binding takes place for the normal parameters of the BeginIndexIAsync method. Only filter attributes placed on the BeginIndexIAsync method are honored: placing these on the EndIndexIAsync method is of no use.

The event pattern

The event pattern is a different beast. It also consists of two methods that should be added to your controller:

[code:c#]

public void IndexEvent() { }
public ActionResult IndexEventCompleted() { }

[/code]

Let’s implement these and have a look at the details. Here’s the IndexEvent method:

[code:c#]

public void IndexEvent() {
    // Eventually pass parameters to the IndexEventCompleted action method
    // ... AsyncManager.Parameters["contact"] = new Contact();

    // Add an asynchronous operation
    AsyncManager.OutstandingOperations.Increment();
    ThreadPool.QueueUserWorkItem(o =>
    {
        Thread.Sleep(2000);
        AsyncManager.OutstandingOperations.Decrement();
    }, null);
}

[/code]

We’ve just seen how you can pass a parameter to the IndexEventCompleted action method. The next thing to do is tell the AsyncManager how many outstanding operations there are. If this count becomes zero, the IndexEventCompleted  action method is called.

Next, we can consume the results just like we could do in a regular, synchronous controller:

[code:c#]

public ActionResult IndexEventCompleted() {
    // Return the view
    ViewData["Message"] = "Welcome to ASP.NET MVC!";
    ViewData["MethodDescription"] = "This page has been rendered using an asynchronous action method (Event pattern).";
    return View("Index");
}

[/code]

I really think this is the easiest-to-implement asynchronous pattern available in the AsyncController.

The delegate pattern

The delegate pattern is the only pattern that requires only one method in the controller. It basically is a simplified version of the IAsyncResult pattern. Here’s a sample action method, no further comments:

[code:c#]

public ActionResult IndexDelegate()
{
    // Perform asynchronous stuff
    AsyncManager.RegisterTask(
        callback => ...,
        asyncResult =>
        {
            ...
        });

    // Return the view
    ViewData["Message"] = "Welcome to ASP.NET MVC!";
    ViewData["MethodDescription"] = "This page has been rendered using an asynchronous action method (Delegate pattern).";
    return View("Index");
}

[/code]

Conclusion

First of all, you can download the sample code I have used here: MvcAsyncControllersExample.zip (64.24 kb)

Next, I think this is really a feature that should be included in the next ASP.NET MVC release. It can really increase the number of simultaneous requests that can be processed by your web application if it requires some longer running I/O code that otherwise would block the ASP.NET worker thread. Development is a little bit more complex due to the nature of multithreading: you’ll have to do locking where needed, work with IAsyncResult or delegates, …

In my opinion, the “event pattern” is the way to go for the ASP.NET MVC team, because it is the most readable. Also, there’s no need to implement IAsyncResult classes for your own long-running methods.

Hope this clarified AsyncControllers a bit. Till next time!

kick it on DotNetKicks.com

Speaking at DevDays 2009, The Hague (and more)

DevDays09, The NetherlandsSome Great news (at least: I think this is great :-)): Kevin Dockx and I will be giving a session on PHP and Silverlight at the Netherlands DevDays09. This event, aimed totally at developers, will take place on May 28 and 29th in The Hague (Den Haag). It’s the first time the DevDays are hosting sessions related to PHP, and it’s also the first time I’ll be speaking at an event of this size.

Our session will cover the basics of Silverlight and show you how you can create rich web applications using the best of 2 worlds: Silverlight and PHP.

dpc09_speakerNext to this event, we’ll be doing this very same session at the Dutch PHP Conference in Amsterdam, which will take place June 11 – June 13th. Yes, we are evil, doing a presentation on Microsoft technologies at a PHP event.

And now that I’m announcing upcoming sessions anyway… I’ll be doing a session on mocking at VISUG (Visual Studio User Group Belgium). Come visit us at May 7th! This session will show you the basics of unit testing without having to rely on external dependencies like databases, WCF services, ... and will show you how you can reproduce behaviour in a unit test that might be otherwide difficult to test.

Oh, and another one: MSDN Belgium is hosting some virtual events. I’ll be doing a session on the ASP.NET MVC framework (in Dutch) on April 23 at 14:00. Check the MSDN pages for more info (yet to come). Here’s the abstract of that session:

"Join us for this 90 min session and get a developer-focused overview on ASP.NET MVC (Model-View-Controller), a new approach in building ASP.NET applications. Learn how the new ASP.NET MVC framework differs and can be an alternative to the current ASP.NET Web Forms framework. This session will help you to learn how to take advantage of ASP.NET MVC to build loosely coupled, highly testable, agile applications. You will see how ASP.NET MVC provides you with fine-grained control over both HTML and JavaScript."

Back to the future! Exploring ASP.NET MVC Futures

Back to the future!For those of you who did not know yet: next to the ASP.NET MVC 1.0 version and its source code, there’s also an interesting assembly available if you can not wait for next versions of the ASP.NET MVC framework: the MVC Futures assembly. In this blog post, I’ll provide you with a quick overview of what is available in this assembly and how you can already benefit from… “the future”.

kick it on DotNetKicks.com 

First things first: where to get this thing? You can download the assembly from the CodePlex releases page. Afterwards, reference this assembly in your ASP.NET MVC web application. Also add some things to the Web.config file of your application:

[code:c#]

<?xml version="1.0"?>
<configuration>
    <!-- ... -->
    <system.web>
        <!-- ... -->

        <pages>
            <controls>
                <!-- ... -->
                <add tagPrefix="mvc" namespace="Microsoft.Web.Mvc.Controls" assembly="Microsoft.Web.Mvc"/>
            </controls>
            <namespaces>
                <!-- ... -->
                <add namespace="Microsoft.Web.Mvc"/>
                <add namespace="Microsoft.Web.Mvc.Controls"/>
            </namespaces>
        </pages>

        <!-- ... -->
    </system.web>
    <!-- ... -->
</configuration>

[/code]

You are now ready to go! Buckle up and start your De Lorean DMC-12…

Donut caching (a.k.a. substitution)

If you have never heard of the term “donut caching” or “substitution”, now is a good time to read a previous blog post of mine. Afterwards, return here. If you don’t want to click that link: fine! Here’s in short: “With donut caching, most of the page is cached, except for some regions which are able to be substituted with other content.”

You’ll be needing an OutputCache-enabled action method in a controller:

[code:c#]

[OutputCache(Duration = 10, VaryByParam = "*")]
public ActionResult DonutCaching()
{
    ViewData["lastCached"] = DateTime.Now.ToString();

    return View();
}

[/code]

Next: a view. Add the following lines of code to a view:

[code:c#]

<p>
    This page was last cached on: <%=Html.Encode(ViewData["lastCached"])%><br />
    Here's some "donut content" that is uncached: <%=Html.Substitute( c => DateTime.Now.ToString() )%>
</p>

[/code]

There you go: when running this application, you will see one DateTime printed in a cached way (refreshed once a minute), and one DateTime printed on every page load thanks to the substitution HtmlHelper extension. This extension method accepts a HttpContext instance which you can also use to enhance the output.

Now before you run away and use his in your projects: PLEASE, do not do write lots of code in your View. Instead, put the real code somewhere else so your view does not get cluttered and your code is re-usable. In an ideal world, this donut caching would go hand in hand with our next topic…

Render action methods inside a view

You heard me! We will be rendering an action method in a view. Yes, that breaks the model-view-controller design pattern a bit, but it gives you a lot of added value while developing applications! Look at this like “partial controllers”, where you only had partial views in the past. If you have been following all ASP.NET MVC previews before, this feature already existed once but has been moved to the futures assembly.

Add some action methods to a Controller:

[code:c#]

public ActionResult SomeAction()
{
    return View();
}

public ActionResult CurrentTime()
{
    ViewData["currentTime"] = DateTime.Now.ToString();

    return View();
}

[/code]

This indeed is not much logic, but here’s the point: the SomeAction action method will render a view. That view will then render the CurrentTime action method, which will also render a (partial) view. Both views are combined and voila: a HTTP response which was generated by 2 action methods that were combined.

Here’s how you can render an action method from within a view:

[code:c#]

<% Html.RenderAction("CurrentTime"); %>

[/code]

There’s also lambdas to perform more complex actions!

[code:c#]

<% Html.RenderAction<HomeController>(c => c.CurrentTime()); %>

[/code]

What most people miss: controls

Lots of people are missing something when first working with the ASP.NET MVC framework: “Where are all the controls? Why don’t all ASP.NET Webforms controls work?” My answer would normally be: “You don’t need them.”, but I now also have an alternative: “Use the futures assembly!”

Here’s a sample controller action method:

[code:c#]

public ActionResult Controls()
{
    ViewData["someData"] = new[] {
        new {
            Id = 1,
            Name = "Maarten"
        },
        new {
            Id = 2,
            Name = "Bill"
        }
    };

    return View();
}

[/code]

The view:

[code:c#]

<p>
    TextBox: <mvc:TextBox Name="someTextBox" runat="server" /><br />
    Password: <mvc:Password Name="somePassword" runat="server" />
</p>
<p>
    Repeater:
    <ul>
    <mvc:Repeater Name="someData" runat="server">
        <EmptyDataTemplate>
            <li>No data is available.</li>
        </EmptyDataTemplate>
        <ItemTemplate>
            <li><%# Eval("Name") %></li>
        </ItemTemplate>
    </mvc:Repeater>
    </ul>
</p>

[/code]

As you can see: these controls all work quite easy. The "Name property accepts the key in the ViewData dictionary and will render the value from there. In the repeater control, you can even work with “good old” Eval: <%# Eval("Name") %>.

Extra HtmlHelper extension methods

Not going in too much detail here: there are lots of new HtmlHelper extension methods. The ones I especially like are those that allow you to create a hyperlink to an action method using lambdas:

[code:c#]

<%=Html.ActionLink<HomeController>(c => c.ShowProducts("Books"), "Show books")%>

[/code]

Here’s a list of new HtmlHelper extension methods:

  • ActionLink – with lambdas
  • RouteLink – with lambdas
  • Substitute (see earlier in this post)
  • JavaScriptStringEncode
  • HiddenFor, TextFor, DropDownListFor, … – like Hidden, Text, … but with lambdas
  • Button
  • SubmitButton
  • Image
  • Mailto
  • RadioButtonList

More model binders

Another thing I will only cover briefly: there are lots of new ModelBinders included! Model binders actually allow you to easily map input from a HTML form to parameters in an action method. That being said, here are the new kids on the block:

  • FileCollectionModelBinder – useful for HTTP posts that contain uploaded files
  • LinqBinaryModelBinder
  • ByteArrayModelBinder

When you want to use these, do not forget to register them with ModelBinders.Binders in your Global.asax.

More ActionFilters and ResultFilters

Action filters and result filters are used to intercept calls to an action method or view rendering, providing a hook right before and after that occurs. This way, you can still modify some variables in the request or response prior to, for example, executing an action method. Here’s what is new:

  • AcceptAjaxAttribute – The action method is only valid for AJAX requests. It allows you to have different action methods for regular requests and AJAX requests.
  • ContentTypeAttribute – Sets the content type of the HTTP response
  • RequireSslAttribute – Requires SSL for the action method to execute. Allows you to have a different action method for non-SSL and SSL requests.
  • SkipBindingAttribute – Skips executing model binders for an action method.

Asynchronous controllers

This is a big one, but it is described perfectly in a Word document that can be found on the MVC Futures assembly release page. In short:

The AsyncController is an experimental class to allow developers to write asynchronous action methods. The usage scenario for this is for action methods that have to make long-running requests, such as going out over the network or to a database, and don’t want to block the web server from performing useful work while the request is ongoing.

In general, the pattern is that the web server schedules Thread A to handle some incoming request, and Thread A is responsible for everything up to launching the action method, then Thread A goes back to the available pool to service another request. When the asynchronous operation has completed, the web server retrieves a Thread B (which might be the same as Thread A) from the thread pool to process the remainder of the request, including rendering the response. The diagram below illustrates this point.

Asynchronous controllers

Sweet! Should speed up your ASP.NET MVC web application when it has to handle much requests.

Conclusion

I hope you now know what the future for ASP.NET MVC holds. It’s not sure all of this will ever make it into a release, but you are able to use all this stuff from the futures assembly. If you are too tired to scroll to the top of this post after reading it, here’s the link to the futures assembly again: MVC Futures assembly

kick it on DotNetKicks.com