Sep 22

The MVC platform – ViewPage and ViewUserControl classes

Posted in Uncategorized      Comments Off on The MVC platform – ViewPage and ViewUserControl classes

Today we’ll concentrate on the final process related with the view generation. As we’ve seen in the last post, the WebFormView is responsible for instanting the page (or user control) required for rendering the HTML sent back to the client. Lets start with the ViewPage class…It extends the traditional ASP.NET Page class and it will also implement the IViewDataContainter interface. The IViewDataContainer is really simple and it’s only there for letting the View receive the ViewDataDictionary that contains data passed from the Controller:

public interface IViewDataContainer {
   ViewDataDictionary ViewData { get; set; }

Besides this property, you’ll notice that the ViewPage introduces several other interesting properties:

  • Ajax: property of type AjaxHelper. You can use this property for adding AJAX to your pages (we’ll see how in a future post);
  • Html: property of type HtmlHelper which gives you access to several utility methods that will help you generate controls on your pages (between other things). More about this on a future post;
  • MasterLocation: property used for putting the location of the master page;
  • Url: property of type UrlHelper. You’ll use this property for getting the correct urls for a specific route;
  • ViewContext: context associated with the current request;
  • Writer: read only property which you can use to get acccess to the HtmlTextWriter that is going to be used for writting the response to the client;
  • TempData: shorcut for the ViewContext.TempData property.

When you’re building views, you’ll end up creating new pages that inherit from this class. Do notice that all your pages must end up inheriting from this class. If you don’t do that, you’ll end up getting an exception because the WebFormView class will always try to cast your pages/user controls to ViewPage or ViewUserControl.

The ViewUserControl is similar to the ViewPage class. It doesn’t have a MasterLocation property because you only apply master pages to pages and not to user controls. However, it has other interesting properties. For instance, the class exposes a ViewPage property. It will try to cast the Page property (that you normally find on the UserControl class) into a ViewPage instance. If it works, then you’ll be able to access (for instance) the Url and Ajax properties from your control. If you don’t have a “valid” page, then you won’t be able to access any of those goodies.

If you look at the internals of the ViewUserControl class, you’ll find out that the ViewData property getter is interesting. You have two options here: you can pass the ViewDataDictionary or you can end up reusing the ViewDataDictionary of its parent. Another interesting thing: you can use a different view engine for rendering partial views!

By now we’ve got an idea of what is available on the views and partial views. Before going on, I’d like to make something clear. Until now, I’ve been saying that a view is an ASPX page and that a partial view is a user control. This is what will happen most of the time (you can probably say that it’s the most natural mapping when you think about ASP.NET and MVC). However,you should also keep in mind that nothing prevents you from “promoting” an ascx into a view. In other words,even though most of the time you’ll end up using the model I’ve been refering to  (ie, pages are mapped into ViewPages and user controls into user ViewUserControl), nothing requires you to do that. A view can be a user control or a page (and the same thing can be said about partial views).

As we’ve seen, you’ll end up influecing the view that is called by returning an ActionResult from your controller method. But what about rendering partial views? A valid scenario for partial views is dividing your pages into smaller components (user controls) and then placing them on your pages. You can do that in several ways. You can use the traditional ASP.NET approach, where you add a register directive to the page or you can use the HtmlHelper and call its RenderPartial method. Do notice that this last option will let you specify the ViewDataDictionary (or even the view engine) while in the first option you’ll end up using the default ASP.NET engine.

It’s interesting to notice that the RenderPartial methods are implemented as extension methods (as are several of the HtmlHelper public methods). We’ll return to them in a future post.

Before ending, there’s time to speak about two other classes. If you want to get a typed view page or view user control, you should use the ViewPage<T> and ViewUserControl<T> classes. These classes expand the previous classes and “transform” the ViewData property into a strongly type property of type ViewDataDictionary<T>. This means that if you’re passing a strongly typed object to your view, you’ll be able to access that object in your view (or partial view) through the ViewData property and access its properties directly.

On the next post, we’ll start looking at the helper classes. Keep tuned!