Extending the Controller
A key change is that RSVPController inherits from the Controller base class. The base class performs the
Execute() method and wires up actions. Using the
ControllerActionAttribute declares that the
Index() method should be exposed as an action (
Index() is the default action).
--/Controllers/RsvpController.cs File
public class RsvpController : Controller
{
[ControllerAction]
public void Index()
{
RenderView("RsvpList");
}
}
For example's sake, I'll change the URL to be
http://www.partywithpalermo.com/rsvp/list where
list will be the action.
--/Controllers/RsvpController.cs File
public class RsvpController : Controller
{
private IAttendeesRepository repository
= new AttendeeRepository();
[ControllerAction]
public void List()
{
IEnumerable<Attendee> attendees =
repository.GetAttendees();
RenderView("RsvpList", attendees);
}
}
Note the
RenderView() method in the preceding code. The
RsvpList string argument denotes the name of a view in the
/Views folder in the web application. It will look for the file
/Views/RsvpList.aspx, load it, and render it. To retrieve the Attendees the code uses an IAttendeesRepository. The page code sets a property bag called
ViewData with the objects that need to go to the view. In this case there's a single object but you can set several because
ViewData is an IDictionary unless overridden.
--/Views/RsvpList.aspx File
<%@ Page Language="C#"
AutoEventWireup="true"
CodeBehind="RsvpList.aspx.cs"
Inherits="PartyWithPalermo.Website.Views.
RsvpHome" %>
<%@ Import namespace="PartyWithPalermo.
Domain.Model"%>
<%@ Import namespace="PartyWithPalermo.
Website.Controllers"%>
<!DOCTYPE html PUBLIC
"-//W3C//DTD XHTML 1.0
Transitional//EN"
"http://www.w3.org/TR/
xhtml1/DTD/xhtml1-
transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
<title>Party with Palermo</title>
</head>
<body>
<table border="1">
<tr>
<td>Name</td>
<td>Website</td>
<td>Comment</td>
</tr>
<% foreach (Attendee attendee in
ViewData) { %>
<tr>
<td><%=attendee.Name %></td>
<td><%=attendee.Website %></td>
<td><%=attendee.Comment %></td>
</tr>
<% } %>
</table>
</body>
</html>
--/Views/RsvpList.aspx.cs File
public partial class RsvpHome :
ViewPage<IEnumerable<Attendee>>
{
protected void Page_Load(object sender,
EventArgs e)
{
}
}
The only difference from the code-behind is that it inherits from ViewPage instead of merely Page. By declaring the generic form of ViewPage you have strongly-typed
ViewData, and you can create a presentation DTO to hold any information that needs to be passed to the view. You'll get IntelliSense when binding objects to the view. Table 1 shows the view rendered to the browser.
Name |
Web site |
Comment |
Jeffrey Palermo | http://www.jeffreypalermo.com | Please RSVP, and you'll be added to this list! |
Homer Simpson | http://www.simpsons.com | Doh! |
Bart Simpson | http://www.simpsons.com | Don't have a cow. |
Table 1: View rendered to the browser.
Note how simplified this view is. This technique allows you to leverage the raw power of HTML (and still use server controls) without ViewState, Postbacks, or a server-side form wrapping the entire page.
Conclusion
This brief overview of Microsoft's new ASP.NET MVC framework barely scratches the surface of its capabilities. I did not cover mapping query string or form variables into controller actions, output caching, etc., but the framework has all these covered. The ASP.NET MVC framework also supports advanced scenarios, including Inversion of Control (IoC) container creation of controllers, and loading UserControls as a partial view. The framework is still in the prototype stage, but when it hits CTP status in a month or so, check out
my blog for more information.